From 316bced604d3d94696126416df6ee9156375eaf5 Mon Sep 17 00:00:00 2001 From: Qinxuan Chen Date: Tue, 25 Apr 2023 19:58:21 +0800 Subject: [PATCH] frame-support: migrate some tests from `decl_*` macros to the new `pallet` macros (#12401) * frame-support: migrate some tests from decl macros to new pallet attribute macros * Remove useless type alias * Remove useless type alias * Work around for rust issue 52234 Signed-off-by: Oliver Tale-Yazdi * Fix tests Signed-off-by: Oliver Tale-Yazdi * Use polkadot-compatible paste version Signed-off-by: Oliver Tale-Yazdi * Fix crate access and add tests Signed-off-by: Oliver Tale-Yazdi * Typo Signed-off-by: Oliver Tale-Yazdi --------- Signed-off-by: Oliver Tale-Yazdi Co-authored-by: Oliver Tale-Yazdi Co-authored-by: parity-processbot <> --- Cargo.lock | 5 +- frame/support/src/dispatch.rs | 183 +++++++++----- frame/support/src/lib.rs | 237 ++++++++++++------ .../src/storage/generator/double_map.rs | 43 +--- frame/support/src/storage/generator/map.rs | 43 +--- frame/support/src/storage/generator/mod.rs | 128 ++++++++-- frame/support/src/storage/generator/nmap.rs | 61 ++--- primitives/core/Cargo.toml | 1 + primitives/core/src/lib.rs | 85 ++++--- primitives/runtime/src/lib.rs | 20 ++ 10 files changed, 490 insertions(+), 316 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79b79e2b2ef45..8d8d2d59a3c88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7239,9 +7239,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.11" +version = "1.0.12" source = "registry+/~https://github.com/rust-lang/crates.io-index" -checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pbkdf2" @@ -10503,6 +10503,7 @@ dependencies = [ "merlin", "parity-scale-codec", "parking_lot 0.12.1", + "paste", "primitive-types", "rand 0.8.5", "regex", diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index 9e949ef6d4a21..c75d75b41a292 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -3532,112 +3532,177 @@ mod tests { #[allow(dead_code)] mod weight_tests { use super::{tests::*, *}; - use sp_core::{parameter_types, Get}; + use sp_core::parameter_types; + use sp_runtime::{generic, traits::BlakeTwo256}; use sp_weights::RuntimeDbWeight; - pub trait Config: 'static { - type RuntimeOrigin; - type Balance; - type BlockNumber; - type DbWeight: Get; - type PalletInfo: crate::traits::PalletInfo; - } + pub use self::frame_system::{Call, Config, Pallet}; - pub struct TraitImpl {} + #[crate::pallet(dev_mode)] + pub mod frame_system { + use super::{frame_system, frame_system::pallet_prelude::*}; + pub use crate::dispatch::RawOrigin; + use crate::pallet_prelude::*; - parameter_types! { - pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { - read: 100, - write: 1000, - }; - } + #[pallet::pallet] + pub struct Pallet(PhantomData); - impl Config for TraitImpl { - type RuntimeOrigin = u32; - type BlockNumber = u32; - type Balance = u32; - type DbWeight = DbWeight; - type PalletInfo = crate::tests::PanicPalletInfo; - } + #[pallet::config] + #[pallet::disable_frame_system_supertrait_check] + pub trait Config: 'static { + type BlockNumber: Parameter + Default + MaxEncodedLen; + type AccountId; + type Balance; + type BaseCallFilter: crate::traits::Contains; + type RuntimeOrigin; + type RuntimeCall; + type PalletInfo: crate::traits::PalletInfo; + type DbWeight: Get; + } - decl_module! { - pub struct Module for enum Call where origin: T::RuntimeOrigin, system=self { + #[pallet::error] + pub enum Error { + /// Required by construct_runtime + CallFiltered, + } + + #[pallet::origin] + pub type Origin = RawOrigin<::AccountId>; + + #[pallet::call] + impl Pallet { // no arguments, fixed weight - #[weight = 1000] - fn f00(_origin) { unimplemented!(); } + #[pallet::weight(1000)] + pub fn f00(_origin: OriginFor) -> DispatchResult { + unimplemented!(); + } - #[weight = (1000, DispatchClass::Mandatory)] - fn f01(_origin) { unimplemented!(); } + #[pallet::weight((1000, DispatchClass::Mandatory))] + pub fn f01(_origin: OriginFor) -> DispatchResult { + unimplemented!(); + } - #[weight = (1000, Pays::No)] - fn f02(_origin) { unimplemented!(); } + #[pallet::weight((1000, Pays::No))] + pub fn f02(_origin: OriginFor) -> DispatchResult { + unimplemented!(); + } - #[weight = (1000, DispatchClass::Operational, Pays::No)] - fn f03(_origin) { unimplemented!(); } + #[pallet::weight((1000, DispatchClass::Operational, Pays::No))] + pub fn f03(_origin: OriginFor) -> DispatchResult { + unimplemented!(); + } // weight = a x 10 + b - #[weight = ((_a * 10 + _eb * 1) as u64, DispatchClass::Normal, Pays::Yes)] - fn f11(_origin, _a: u32, _eb: u32) { unimplemented!(); } + #[pallet::weight(((_a * 10 + _eb * 1) as u64, DispatchClass::Normal, Pays::Yes))] + pub fn f11(_origin: OriginFor, _a: u32, _eb: u32) -> DispatchResult { + unimplemented!(); + } - #[weight = (0, DispatchClass::Operational, Pays::Yes)] - fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); } + #[pallet::weight((0, DispatchClass::Operational, Pays::Yes))] + pub fn f12(_origin: OriginFor, _a: u32, _eb: u32) -> DispatchResult { + unimplemented!(); + } - #[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + Weight::from_parts(10_000, 0)] - fn f20(_origin) { unimplemented!(); } + #[pallet::weight(T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + Weight::from_all(10_000))] + pub fn f20(_origin: OriginFor) -> DispatchResult { + unimplemented!(); + } + + #[pallet::weight(T::DbWeight::get().reads_writes(6, 5) + Weight::from_all(40_000))] + pub fn f21(_origin: OriginFor) -> DispatchResult { + unimplemented!(); + } + } + + pub mod pallet_prelude { + pub type OriginFor = ::RuntimeOrigin; + } + } - #[weight = T::DbWeight::get().reads_writes(6, 5) + Weight::from_parts(40_000, 0)] - fn f21(_origin) { unimplemented!(); } + type BlockNumber = u32; + type AccountId = u32; + type Balance = u32; + type Header = generic::Header; + type UncheckedExtrinsic = generic::UncheckedExtrinsic; + type Block = generic::Block; + crate::construct_runtime!( + pub enum Runtime + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: self::frame_system, } + ); + + parameter_types! { + pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 100, + write: 1000, + }; + } + + impl Config for Runtime { + type BlockNumber = BlockNumber; + type AccountId = AccountId; + type Balance = Balance; + type BaseCallFilter = crate::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type DbWeight = DbWeight; + type PalletInfo = PalletInfo; } #[test] fn weights_are_correct() { - // #[weight = 1000] - let info = Call::::f00 {}.get_dispatch_info(); + // #[pallet::weight(1000)] + let info = Call::::f00 {}.get_dispatch_info(); assert_eq!(info.weight, Weight::from_parts(1000, 0)); assert_eq!(info.class, DispatchClass::Normal); assert_eq!(info.pays_fee, Pays::Yes); - // #[weight = (1000, DispatchClass::Mandatory)] - let info = Call::::f01 {}.get_dispatch_info(); + // #[pallet::weight((1000, DispatchClass::Mandatory))] + let info = Call::::f01 {}.get_dispatch_info(); assert_eq!(info.weight, Weight::from_parts(1000, 0)); assert_eq!(info.class, DispatchClass::Mandatory); assert_eq!(info.pays_fee, Pays::Yes); - // #[weight = (1000, Pays::No)] - let info = Call::::f02 {}.get_dispatch_info(); + // #[pallet::weight((1000, Pays::No))] + let info = Call::::f02 {}.get_dispatch_info(); assert_eq!(info.weight, Weight::from_parts(1000, 0)); assert_eq!(info.class, DispatchClass::Normal); assert_eq!(info.pays_fee, Pays::No); - // #[weight = (1000, DispatchClass::Operational, Pays::No)] - let info = Call::::f03 {}.get_dispatch_info(); + // #[pallet::weight((1000, DispatchClass::Operational, Pays::No))] + let info = Call::::f03 {}.get_dispatch_info(); assert_eq!(info.weight, Weight::from_parts(1000, 0)); assert_eq!(info.class, DispatchClass::Operational); assert_eq!(info.pays_fee, Pays::No); - // #[weight = ((_a * 10 + _eb * 1) as Weight, DispatchClass::Normal, Pays::Yes)] - let info = Call::::f11 { _a: 13, _eb: 20 }.get_dispatch_info(); + // #[pallet::weight(((_a * 10 + _eb * 1) as u64, DispatchClass::Normal, Pays::Yes))] + let info = Call::::f11 { a: 13, eb: 20 }.get_dispatch_info(); assert_eq!(info.weight, Weight::from_parts(150, 0)); // 13*10 + 20 assert_eq!(info.class, DispatchClass::Normal); assert_eq!(info.pays_fee, Pays::Yes); - // #[weight = (0, DispatchClass::Operational, Pays::Yes)] - let info = Call::::f12 { _a: 10, _eb: 20 }.get_dispatch_info(); - assert_eq!(info.weight, Weight::from_parts(0, 0)); + // #[pallet::weight((0, DispatchClass::Operational, Pays::Yes))] + let info = Call::::f12 { a: 10, eb: 20 }.get_dispatch_info(); + assert_eq!(info.weight, Weight::zero()); assert_eq!(info.class, DispatchClass::Operational); assert_eq!(info.pays_fee, Pays::Yes); - // #[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + 10_000] - let info = Call::::f20 {}.get_dispatch_info(); - assert_eq!(info.weight, Weight::from_parts(12300, 0)); // 100*3 + 1000*2 + 10_1000 + // #[pallet::weight(T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + + // Weight::from_all(10_000))] + let info = Call::::f20 {}.get_dispatch_info(); + assert_eq!(info.weight, Weight::from_parts(12300, 10000)); // 100*3 + 1000*2 + 10_1000 assert_eq!(info.class, DispatchClass::Normal); assert_eq!(info.pays_fee, Pays::Yes); - // #[weight = T::DbWeight::get().reads_writes(6, 5) + 40_000] - let info = Call::::f21 {}.get_dispatch_info(); - assert_eq!(info.weight, Weight::from_parts(45600, 0)); // 100*6 + 1000*5 + 40_1000 + // #[pallet::weight(T::DbWeight::get().reads_writes(6, 5) + Weight::from_all(40_000))] + let info = Call::::f21 {}.get_dispatch_info(); + assert_eq!(info.weight, Weight::from_parts(45600, 40000)); // 100*6 + 1000*5 + 40_1000 assert_eq!(info.class, DispatchClass::Normal); assert_eq!(info.pays_fee, Pays::Yes); } diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 036bd93464b9f..0ee82b9f16a8f 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -829,77 +829,153 @@ pub mod tests { PalletStorageMetadataIR, StorageEntryMetadataIR, StorageEntryModifierIR, StorageEntryTypeIR, StorageHasherIR, }; - use codec::{Codec, EncodeLike}; - use frame_support::traits::CrateVersion; use sp_io::{MultiRemovalResults, TestExternalities}; + use sp_runtime::{generic, traits::BlakeTwo256, BuildStorage}; use sp_std::result; - /// A PalletInfo implementation which just panics. - pub struct PanicPalletInfo; + pub use self::frame_system::{Config, Pallet}; - impl crate::traits::PalletInfo for PanicPalletInfo { - fn index() -> Option { - unimplemented!("PanicPalletInfo mustn't be triggered by tests"); - } - fn name() -> Option<&'static str> { - unimplemented!("PanicPalletInfo mustn't be triggered by tests"); - } - fn module_name() -> Option<&'static str> { - unimplemented!("PanicPalletInfo mustn't be triggered by tests"); - } - fn crate_version() -> Option { - unimplemented!("PanicPalletInfo mustn't be triggered by tests"); + #[pallet] + pub mod frame_system { + #[allow(unused)] + use super::{frame_system, frame_system::pallet_prelude::*}; + pub use crate::dispatch::RawOrigin; + use crate::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::config] + #[pallet::disable_frame_system_supertrait_check] + pub trait Config: 'static { + type BlockNumber: Parameter + Default + MaxEncodedLen; + type AccountId; + type BaseCallFilter: crate::traits::Contains; + type RuntimeOrigin; + type RuntimeCall; + type PalletInfo: crate::traits::PalletInfo; + type DbWeight: Get; } - } - pub trait Config: 'static { - type BlockNumber: Codec + EncodeLike + Default + TypeInfo; - type RuntimeOrigin; - type PalletInfo: crate::traits::PalletInfo; - type DbWeight: crate::traits::Get; - } + #[pallet::error] + pub enum Error { + /// Required by construct_runtime + CallFiltered, + } - mod module { - #![allow(dead_code)] + #[pallet::origin] + pub type Origin = RawOrigin<::AccountId>; + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + pub type Data = StorageMap<_, Twox64Concat, u32, u64, ValueQuery>; + + #[pallet::storage] + pub type OptionLinkedMap = StorageMap<_, Blake2_128Concat, u32, u32, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn generic_data)] + pub type GenericData = + StorageMap<_, Identity, T::BlockNumber, T::BlockNumber, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn generic_data2)] + pub type GenericData2 = + StorageMap<_, Blake2_128Concat, T::BlockNumber, T::BlockNumber, OptionQuery>; + + #[pallet::storage] + pub type DataDM = + StorageDoubleMap<_, Twox64Concat, u32, Blake2_128Concat, u32, u64, ValueQuery>; + + #[pallet::storage] + pub type GenericDataDM = StorageDoubleMap< + _, + Blake2_128Concat, + T::BlockNumber, + Identity, + T::BlockNumber, + T::BlockNumber, + ValueQuery, + >; + + #[pallet::storage] + pub type GenericData2DM = StorageDoubleMap< + _, + Blake2_128Concat, + T::BlockNumber, + Twox64Concat, + T::BlockNumber, + T::BlockNumber, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::unbounded] + pub type AppendableDM = StorageDoubleMap< + _, + Blake2_128Concat, + u32, + Blake2_128Concat, + T::BlockNumber, + Vec, + ValueQuery, + >; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub data: Vec<(u32, u64)>, + pub test_config: Vec<(u32, u32, u64)>, + } - use super::Config; + impl Default for GenesisConfig { + fn default() -> Self { + Self { data: vec![(15u32, 42u64)], test_config: vec![(15u32, 16u32, 42u64)] } + } + } - decl_module! { - pub struct Module for enum Call where origin: T::RuntimeOrigin, system=self {} + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + for (k, v) in &self.data { + >::insert(k, v); + } + for (k1, k2, v) in &self.test_config { + >::insert(k1, k2, v); + } + } } - } - use self::module::Module; - - decl_storage! { - trait Store for Module as Test { - pub Value get(fn value): u64; - pub Data get(fn data) build(|_| vec![(15u32, 42u64)]): - map hasher(twox_64_concat) u32 => u64; - pub OptionLinkedMap: map hasher(blake2_128_concat) u32 => Option; - pub GenericData get(fn generic_data): - map hasher(identity) T::BlockNumber => T::BlockNumber; - pub GenericData2 get(fn generic_data2): - map hasher(blake2_128_concat) T::BlockNumber => Option; - pub DataDM config(test_config) build(|_| vec![(15u32, 16u32, 42u64)]): - double_map hasher(twox_64_concat) u32, hasher(blake2_128_concat) u32 => u64; - pub GenericDataDM: - double_map hasher(blake2_128_concat) T::BlockNumber, hasher(identity) T::BlockNumber - => T::BlockNumber; - pub GenericData2DM: - double_map hasher(blake2_128_concat) T::BlockNumber, hasher(twox_64_concat) T::BlockNumber - => Option; - pub AppendableDM: - double_map hasher(blake2_128_concat) u32, hasher(blake2_128_concat) T::BlockNumber => Vec; + pub mod pallet_prelude { + pub type OriginFor = ::RuntimeOrigin; } } - struct Test; + type BlockNumber = u32; + type AccountId = u32; + type Header = generic::Header; + type UncheckedExtrinsic = generic::UncheckedExtrinsic; + type Block = generic::Block; + + crate::construct_runtime!( + pub enum Runtime + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: self::frame_system, + } + ); - impl Config for Test { - type BlockNumber = u32; - type RuntimeOrigin = u32; - type PalletInfo = PanicPalletInfo; + impl Config for Runtime { + type BlockNumber = BlockNumber; + type AccountId = AccountId; + type BaseCallFilter = crate::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type PalletInfo = PalletInfo; type DbWeight = (); } @@ -907,8 +983,6 @@ pub mod tests { GenesisConfig::default().build_storage().unwrap().into() } - type Map = Data; - trait Sorted { fn sorted(self) -> Self; } @@ -925,15 +999,15 @@ pub mod tests { new_test_ext().execute_with(|| { #[crate::storage_alias] type GenericData2 = StorageMap< - Test, + System, Blake2_128Concat, ::BlockNumber, ::BlockNumber, >; - assert_eq!(Module::::generic_data2(5), None); - GenericData2::::insert(5, 5); - assert_eq!(Module::::generic_data2(5), Some(5)); + assert_eq!(Pallet::::generic_data2(5), None); + GenericData2::::insert(5, 5); + assert_eq!(Pallet::::generic_data2(5), Some(5)); /// Some random docs that ensure that docs are accepted #[crate::storage_alias] @@ -1004,6 +1078,8 @@ pub mod tests { #[test] fn map_issue_3318() { new_test_ext().execute_with(|| { + type OptionLinkedMap = self::frame_system::OptionLinkedMap; + OptionLinkedMap::insert(1, 1); assert_eq!(OptionLinkedMap::get(1), Some(1)); OptionLinkedMap::insert(1, 2); @@ -1014,6 +1090,8 @@ pub mod tests { #[test] fn map_swap_works() { new_test_ext().execute_with(|| { + type OptionLinkedMap = self::frame_system::OptionLinkedMap; + OptionLinkedMap::insert(0, 0); OptionLinkedMap::insert(1, 1); OptionLinkedMap::insert(2, 2); @@ -1043,6 +1121,8 @@ pub mod tests { #[test] fn double_map_swap_works() { new_test_ext().execute_with(|| { + type DataDM = self::frame_system::DataDM; + DataDM::insert(0, 1, 1); DataDM::insert(1, 0, 2); DataDM::insert(1, 1, 3); @@ -1075,6 +1155,8 @@ pub mod tests { #[test] fn map_basic_insert_remove_should_work() { new_test_ext().execute_with(|| { + type Map = self::frame_system::Data; + // initialized during genesis assert_eq!(Map::get(&15u32), 42u64); @@ -1101,6 +1183,8 @@ pub mod tests { #[test] fn map_iteration_should_work() { new_test_ext().execute_with(|| { + type Map = self::frame_system::Data; + assert_eq!(Map::iter().collect::>().sorted(), vec![(15, 42)]); // insert / remove let key = 17u32; @@ -1154,7 +1238,7 @@ pub mod tests { fn double_map_basic_insert_remove_remove_prefix_with_commit_should_work() { let key1 = 17u32; let key2 = 18u32; - type DoubleMap = DataDM; + type DoubleMap = self::frame_system::DataDM; let mut e = new_test_ext(); e.execute_with(|| { // initialized during genesis @@ -1199,7 +1283,7 @@ pub mod tests { new_test_ext().execute_with(|| { let key1 = 17u32; let key2 = 18u32; - type DoubleMap = DataDM; + type DoubleMap = self::frame_system::DataDM; // initialized during genesis assert_eq!(DoubleMap::get(&15u32, &16u32), 42u64); @@ -1247,7 +1331,7 @@ pub mod tests { #[test] fn double_map_append_should_work() { new_test_ext().execute_with(|| { - type DoubleMap = AppendableDM; + type DoubleMap = self::frame_system::AppendableDM; let key1 = 17u32; let key2 = 18u32; @@ -1261,7 +1345,7 @@ pub mod tests { #[test] fn double_map_mutate_exists_should_work() { new_test_ext().execute_with(|| { - type DoubleMap = DataDM; + type DoubleMap = self::frame_system::DataDM; let (key1, key2) = (11, 13); @@ -1278,8 +1362,8 @@ pub mod tests { #[test] fn double_map_try_mutate_exists_should_work() { new_test_ext().execute_with(|| { - type DoubleMap = DataDM; - type TestResult = result::Result<(), &'static str>; + type DoubleMap = self::frame_system::DataDM; + type TestResult = Result<(), &'static str>; let (key1, key2) = (11, 13); @@ -1310,15 +1394,8 @@ pub mod tests { fn expected_metadata() -> PalletStorageMetadataIR { PalletStorageMetadataIR { - prefix: "Test", + prefix: "System", entries: vec![ - StorageEntryMetadataIR { - name: "Value", - modifier: StorageEntryModifierIR::Default, - ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), - default: vec![0, 0, 0, 0, 0, 0, 0, 0], - docs: vec![], - }, StorageEntryMetadataIR { name: "Data", modifier: StorageEntryModifierIR::Default, @@ -1422,7 +1499,7 @@ pub mod tests { #[test] fn store_metadata() { - let metadata = Module::::storage_metadata(); + let metadata = Pallet::::storage_metadata(); pretty_assertions::assert_eq!(expected_metadata(), metadata); } @@ -1441,12 +1518,6 @@ pub mod tests { assert_eq!(300, StorageParameter::get()); }) } - - parameter_types! { - pub const BlockHashCount: u64 = 250; - pub static Members: Vec = vec![]; - pub const Foo: Option = None; - } } /// Prelude to be used alongside pallet macro, for ease of use. diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 5763a472cd570..5da68873b10e6 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -514,43 +514,12 @@ where mod test_iterators { use crate::{ hash::StorageHasher, - storage::{generator::StorageDoubleMap, unhashed, IterableStorageDoubleMap}, + storage::{ + generator::{tests::*, StorageDoubleMap}, + unhashed, + }, }; - use codec::{Decode, Encode}; - - pub trait Config: 'static { - type RuntimeOrigin; - type BlockNumber; - type PalletInfo: crate::traits::PalletInfo; - type DbWeight: crate::traits::Get; - } - - crate::decl_module! { - pub struct Module for enum Call where origin: T::RuntimeOrigin, system=self {} - } - - #[derive(PartialEq, Eq, Clone, Encode, Decode)] - struct NoDef(u32); - - crate::decl_storage! { - trait Store for Module as Test { - DoubleMap: double_map hasher(blake2_128_concat) u16, hasher(twox_64_concat) u32 => u64; - } - } - - fn key_before_prefix(mut prefix: Vec) -> Vec { - let last = prefix.iter_mut().last().unwrap(); - assert!(*last != 0, "mock function not implemented for this prefix"); - *last -= 1; - prefix - } - - fn key_after_prefix(mut prefix: Vec) -> Vec { - let last = prefix.iter_mut().last().unwrap(); - assert!(*last != 255, "mock function not implemented for this prefix"); - *last += 1; - prefix - } + use codec::Encode; #[test] fn double_map_iter_from() { @@ -589,6 +558,8 @@ mod test_iterators { #[test] fn double_map_reversible_reversible_iteration() { sp_io::TestExternalities::default().execute_with(|| { + type DoubleMap = self::frame_system::DoubleMap; + // All map iterator let prefix = DoubleMap::prefix_hash(); diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index fb499384f1506..3b36b9bddb704 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -349,43 +349,12 @@ impl> storage::StorageMap mod test_iterators { use crate::{ hash::StorageHasher, - storage::{generator::StorageMap, unhashed, IterableStorageMap}, + storage::{ + generator::{tests::*, StorageMap}, + unhashed, + }, }; - use codec::{Decode, Encode}; - - pub trait Config: 'static { - type RuntimeOrigin; - type BlockNumber; - type PalletInfo: crate::traits::PalletInfo; - type DbWeight: crate::traits::Get; - } - - crate::decl_module! { - pub struct Module for enum Call where origin: T::RuntimeOrigin, system=self {} - } - - #[derive(PartialEq, Eq, Clone, Encode, Decode)] - struct NoDef(u32); - - crate::decl_storage! { - trait Store for Module as Test { - Map: map hasher(blake2_128_concat) u16 => u64; - } - } - - fn key_before_prefix(mut prefix: Vec) -> Vec { - let last = prefix.iter_mut().last().unwrap(); - assert!(*last != 0, "mock function not implemented for this prefix"); - *last -= 1; - prefix - } - - fn key_after_prefix(mut prefix: Vec) -> Vec { - let last = prefix.iter_mut().last().unwrap(); - assert!(*last != 255, "mock function not implemented for this prefix"); - *last += 1; - prefix - } + use codec::Encode; #[test] fn map_iter_from() { @@ -413,6 +382,8 @@ mod test_iterators { #[test] fn map_reversible_reversible_iteration() { sp_io::TestExternalities::default().execute_with(|| { + type Map = self::frame_system::Map; + // All map iterator let prefix = Map::prefix_hash(); diff --git a/frame/support/src/storage/generator/mod.rs b/frame/support/src/storage/generator/mod.rs index 2da612b24de8f..568d400129689 100644 --- a/frame/support/src/storage/generator/mod.rs +++ b/frame/support/src/storage/generator/mod.rs @@ -35,47 +35,123 @@ pub use nmap::StorageNMap; pub use value::StorageValue; #[cfg(test)] -#[allow(dead_code)] mod tests { + use codec::Encode; + use sp_io::TestExternalities; + use sp_runtime::{generic, traits::BlakeTwo256, BuildStorage}; + use crate::{ assert_noop, assert_ok, - storage::{generator::StorageValue, unhashed, IterableStorageMap}, + storage::{generator::StorageValue, unhashed}, }; - use codec::Encode; - use sp_io::TestExternalities; - struct Runtime; + #[crate::pallet] + pub mod frame_system { + #[allow(unused)] + use super::{frame_system, frame_system::pallet_prelude::*}; + pub use crate::dispatch::RawOrigin; + use crate::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::config] + #[pallet::disable_frame_system_supertrait_check] + pub trait Config: 'static { + type BlockNumber; + type AccountId; + type BaseCallFilter: crate::traits::Contains; + type RuntimeOrigin; + type RuntimeCall; + type PalletInfo: crate::traits::PalletInfo; + type DbWeight: Get; + } + + #[pallet::origin] + pub type Origin = RawOrigin<::AccountId>; + + #[pallet::error] + pub enum Error { + /// Required by construct_runtime + CallFiltered, + } + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + pub type Value = StorageValue<_, (u64, u64), ValueQuery>; - pub trait Config: 'static { - type RuntimeOrigin; - type BlockNumber; - type PalletInfo: crate::traits::PalletInfo; - type DbWeight: crate::traits::Get; + #[pallet::storage] + pub type Map = StorageMap<_, Blake2_128Concat, u16, u64, ValueQuery>; + + #[pallet::storage] + pub type NumberMap = StorageMap<_, Identity, u32, u64, ValueQuery>; + + #[pallet::storage] + pub type DoubleMap = + StorageDoubleMap<_, Blake2_128Concat, u16, Twox64Concat, u32, u64, ValueQuery>; + + #[pallet::storage] + pub type NMap = StorageNMap< + _, + (storage::Key, storage::Key), + u64, + ValueQuery, + >; + + pub mod pallet_prelude { + pub type OriginFor = ::RuntimeOrigin; + } } - impl Config for Runtime { - type RuntimeOrigin = u32; - type BlockNumber = u32; - type PalletInfo = crate::tests::PanicPalletInfo; + type BlockNumber = u32; + type AccountId = u32; + type Header = generic::Header; + type UncheckedExtrinsic = generic::UncheckedExtrinsic; + type Block = generic::Block; + + crate::construct_runtime!( + pub enum Runtime + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: self::frame_system, + } + ); + + impl self::frame_system::Config for Runtime { + type BlockNumber = BlockNumber; + type AccountId = AccountId; + type BaseCallFilter = crate::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type PalletInfo = PalletInfo; type DbWeight = (); } - decl_module! { - pub struct Module for enum Call where origin: T::RuntimeOrigin, system=self {} + pub fn key_before_prefix(mut prefix: Vec) -> Vec { + let last = prefix.iter_mut().last().unwrap(); + assert_ne!(*last, 0, "mock function not implemented for this prefix"); + *last -= 1; + prefix } - crate::decl_storage! { - trait Store for Module as Runtime { - Value get(fn value) config(): (u64, u64); - NumberMap: map hasher(identity) u32 => u64; - DoubleMap: double_map hasher(identity) u32, hasher(identity) u32 => u64; - } + pub fn key_after_prefix(mut prefix: Vec) -> Vec { + let last = prefix.iter_mut().last().unwrap(); + assert_ne!(*last, 255, "mock function not implemented for this prefix"); + *last += 1; + prefix } #[test] fn value_translate_works() { let t = GenesisConfig::default().build_storage().unwrap(); TestExternalities::new(t).execute_with(|| { + type Value = self::frame_system::Value; + // put the old value `1111u32` in the storage. let key = Value::storage_value_final_key(); unhashed::put_raw(&key, &1111u32.encode()); @@ -96,7 +172,9 @@ mod tests { fn map_translate_works() { let t = GenesisConfig::default().build_storage().unwrap(); TestExternalities::new(t).execute_with(|| { - // start with a map of u32 -> u32. + type NumberMap = self::frame_system::NumberMap; + + // start with a map of u32 -> u64. for i in 0u32..100u32 { unhashed::put(&NumberMap::hashed_key_for(&i), &(i as u64)); } @@ -125,6 +203,10 @@ mod tests { fn try_mutate_works() { let t = GenesisConfig::default().build_storage().unwrap(); TestExternalities::new(t).execute_with(|| { + type Value = self::frame_system::Value; + type NumberMap = self::frame_system::NumberMap; + type DoubleMap = self::frame_system::DoubleMap; + assert_eq!(Value::get(), (0, 0)); assert_eq!(NumberMap::get(0), 0); assert_eq!(DoubleMap::get(0, 0), 0); diff --git a/frame/support/src/storage/generator/nmap.rs b/frame/support/src/storage/generator/nmap.rs index 21fe7b41eda99..5d3d689aa98a6 100755 --- a/frame/support/src/storage/generator/nmap.rs +++ b/frame/support/src/storage/generator/nmap.rs @@ -462,43 +462,12 @@ impl> mod test_iterators { use crate::{ hash::StorageHasher, - storage::{generator::StorageNMap, unhashed, IterableStorageNMap}, + storage::{ + generator::{tests::*, StorageNMap}, + unhashed, + }, }; - use codec::{Decode, Encode}; - - pub trait Config: 'static { - type RuntimeOrigin; - type BlockNumber; - type PalletInfo: crate::traits::PalletInfo; - type DbWeight: crate::traits::Get; - } - - crate::decl_module! { - pub struct Module for enum Call where origin: T::RuntimeOrigin, system=self {} - } - - #[derive(PartialEq, Eq, Clone, Encode, Decode)] - struct NoDef(u32); - - crate::decl_storage! { - trait Store for Module as Test { - NMap: nmap hasher(blake2_128_concat) u16, hasher(twox_64_concat) u32 => u64; - } - } - - fn key_before_prefix(mut prefix: Vec) -> Vec { - let last = prefix.iter_mut().last().unwrap(); - assert!(*last != 0, "mock function not implemented for this prefix"); - *last -= 1; - prefix - } - - fn key_after_prefix(mut prefix: Vec) -> Vec { - let last = prefix.iter_mut().last().unwrap(); - assert!(*last != 255, "mock function not implemented for this prefix"); - *last += 1; - prefix - } + use codec::Encode; #[test] fn n_map_iter_from() { @@ -545,22 +514,18 @@ mod test_iterators { #[test] fn n_map_double_map_identical_key() { sp_io::TestExternalities::default().execute_with(|| { + use crate::hash::{Blake2_128Concat, Twox64Concat}; + + type NMap = self::frame_system::NMap; + NMap::insert((1, 2), 50); let key_hash = NMap::hashed_key_for((1, 2)); { #[crate::storage_alias] - type NMap = StorageDoubleMap< - Test, - crate::Blake2_128Concat, - u16, - crate::Twox64Concat, - u32, - u64, - >; - - let value = NMap::get(1, 2).unwrap(); - assert_eq!(value, 50); + type NMap = StorageDoubleMap; + + assert_eq!(NMap::get(1, 2), Some(50)); assert_eq!(NMap::hashed_key_for(1, 2), key_hash); } }); @@ -569,6 +534,8 @@ mod test_iterators { #[test] fn n_map_reversible_reversible_iteration() { sp_io::TestExternalities::default().execute_with(|| { + type NMap = self::frame_system::NMap; + // All map iterator let prefix = NMap::prefix_hash(); diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 302d52f2f862b..8eac0996760e3 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -39,6 +39,7 @@ futures = { version = "0.3.21", optional = true } dyn-clonable = { version = "0.9.0", optional = true } thiserror = { version = "1.0.30", optional = true } bitflags = "1.3" +paste = "1.0.7" # full crypto array-bytes = { version = "4.1", optional = true } diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index efccd0378e95a..04f44631cb21c 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -53,6 +53,7 @@ pub mod hashing; pub use hashing::{blake2_128, blake2_256, keccak_256, twox_128, twox_256, twox_64}; pub mod crypto; pub mod hexdisplay; +pub use paste; pub mod defer; pub mod ecdsa; @@ -403,38 +404,62 @@ pub const MAX_POSSIBLE_ALLOCATION: u32 = 33554432; // 2^25 bytes, 32 MiB #[rustfmt::skip] macro_rules! generate_feature_enabled_macro { ( $macro_name:ident, $feature_name:meta, $d:tt ) => { - /// Enable/disable the given code depending on - #[doc = concat!("`", stringify!($feature_name), "`")] - /// being enabled for the crate or not. - /// - /// # Example - /// - /// ```nocompile - /// // Will add the code depending on the feature being enabled or not. - #[doc = concat!(stringify!($macro_name), "!( println!(\"Hello\") )")] - /// ``` - #[cfg($feature_name)] - #[macro_export] - macro_rules! $macro_name { - ( $d ( $d input:tt )* ) => { - $d ( $d input )* + $crate::paste::paste!{ + /// Enable/disable the given code depending on + #[doc = concat!("`", stringify!($feature_name), "`")] + /// being enabled for the crate or not. + /// + /// # Example + /// + /// ```nocompile + /// // Will add the code depending on the feature being enabled or not. + #[doc = concat!(stringify!($macro_name), "!( println!(\"Hello\") )")] + /// ``` + #[cfg($feature_name)] + #[macro_export] + macro_rules! [<_ $macro_name>] { + ( $d ( $d input:tt )* ) => { + $d ( $d input )* + } + } + + /// Enable/disable the given code depending on + #[doc = concat!("`", stringify!($feature_name), "`")] + /// being enabled for the crate or not. + /// + /// # Example + /// + /// ```nocompile + /// // Will add the code depending on the feature being enabled or not. + #[doc = concat!(stringify!($macro_name), "!( println!(\"Hello\") )")] + /// ``` + #[cfg(not($feature_name))] + #[macro_export] + macro_rules! [<_ $macro_name>] { + ( $d ( $d input:tt )* ) => {}; } - } - /// Enable/disable the given code depending on - #[doc = concat!("`", stringify!($feature_name), "`")] - /// being enabled for the crate or not. - /// - /// # Example - /// - /// ```nocompile - /// // Will add the code depending on the feature being enabled or not. - #[doc = concat!(stringify!($macro_name), "!( println!(\"Hello\") )")] - /// ``` - #[cfg(not($feature_name))] - #[macro_export] - macro_rules! $macro_name { - ( $d ( $d input:tt )* ) => {}; + // Work around for: + #[doc(hidden)] + pub use [<_ $macro_name>] as $macro_name; } }; } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic] + fn generate_feature_enabled_macro_panics() { + generate_feature_enabled_macro!(if_test, test, $); + if_test!(panic!("This should panic")); + } + + #[test] + fn generate_feature_enabled_macro_works() { + generate_feature_enabled_macro!(if_not_test, not(test), $); + if_not_test!(panic!("This should not panic")); + } +} diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 2d959425e0f8e..0994dc21b31dd 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -1054,3 +1054,23 @@ mod tests { }); } } + +// NOTE: we have to test the sp_core stuff also from a different crate to check that the macro +// can access the sp_core crate. +#[cfg(test)] +mod sp_core_tests { + use super::*; + + #[test] + #[should_panic] + fn generate_feature_enabled_macro_panics() { + sp_core::generate_feature_enabled_macro!(if_test, test, $); + if_test!(panic!("This should panic")); + } + + #[test] + fn generate_feature_enabled_macro_works() { + sp_core::generate_feature_enabled_macro!(if_not_test, not(test), $); + if_not_test!(panic!("This should not panic")); + } +}