From f4cb21c876d4ce19eb9ef09c39bebf83ba01d16d Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Thu, 25 May 2023 23:49:25 +0200 Subject: [PATCH] frame: GenesisBuild::build allowed in no_std (#14107) * frame: GenesisBuild::build allowed in no_std i`GenesisBuild::build` function will be required for no_std in no native runtime world. `GenesisBuild::build` macro generated function allows to build the runtime GenesisConfig assembled from all pallets' GenesisConfigs. * fixes * GenesisBuild::build avaiable in no-std - #[cfg(feature = "std")] is not longer added to GenesisBuild implementation. * system: hash69 available for no-std * elections-phragmen: panic message fixed for no_std * frame::suport: doc updated * test-runtime: default for GenesisConfig * frame::test-pallet: serde/std added to std feature deps * Cargo.toml: deps sorted * Cargo.lock update cargo update -p frame-support-test-pallet -p frame-support-test * frame ui tests: cleanup --------- Co-authored-by: parity-processbot <> --- Cargo.lock | 1 + frame/elections-phragmen/src/lib.rs | 5 +- .../src/pallet/expand/genesis_build.rs | 11 -- frame/support/src/lib.rs | 6 +- frame/support/src/traits.rs | 6 +- frame/support/src/traits/hooks.rs | 3 +- frame/support/test/Cargo.toml | 11 +- frame/support/test/pallet/Cargo.toml | 2 + .../no_std_genesis_config.stderr | 130 ------------------ .../pass}/no_std_genesis_config.rs | 0 frame/system/src/lib.rs | 1 - .../runtime/src/substrate_test_pallet.rs | 2 +- 12 files changed, 20 insertions(+), 158 deletions(-) delete mode 100644 frame/support/test/tests/construct_runtime_ui/no_std_genesis_config.stderr rename frame/support/test/tests/{construct_runtime_ui => pallet_ui/pass}/no_std_genesis_config.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 0ac95cdb80e38..f371baebd6f6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2784,6 +2784,7 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", + "serde", ] [[package]] diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 08ef4e8db9a03..9757ddd67afe8 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -743,7 +743,10 @@ pub mod pallet { Members::::mutate(|members| { match members.binary_search_by(|m| m.who.cmp(member)) { Ok(_) => { - panic!("Duplicate member in elections-phragmen genesis: {}", member) + panic!( + "Duplicate member in elections-phragmen genesis: {:?}", + member + ) }, Err(pos) => members.insert( pos, diff --git a/frame/support/procedural/src/pallet/expand/genesis_build.rs b/frame/support/procedural/src/pallet/expand/genesis_build.rs index 9447154f386dd..1c8fb40f1f96e 100644 --- a/frame/support/procedural/src/pallet/expand/genesis_build.rs +++ b/frame/support/procedural/src/pallet/expand/genesis_build.rs @@ -19,7 +19,6 @@ use crate::pallet::Def; /// /// * implement the trait `sp_runtime::BuildModuleGenesisStorage` -/// * add #[cfg(feature = "std")] to GenesisBuild implementation. pub fn expand_genesis_build(def: &mut Def) -> proc_macro2::TokenStream { let genesis_config = if let Some(genesis_config) = &def.genesis_config { genesis_config @@ -41,16 +40,6 @@ pub fn expand_genesis_build(def: &mut Def) -> proc_macro2::TokenStream { let gen_cfg_use_gen = genesis_config.gen_kind.type_use_gen(genesis_build.attr_span); - let genesis_build_item = - &mut def.item.content.as_mut().expect("Checked by def parser").1[genesis_build.index]; - - let genesis_build_item_impl = if let syn::Item::Impl(impl_) = genesis_build_item { - impl_ - } else { - unreachable!("Checked by genesis_build parser") - }; - - genesis_build_item_impl.attrs.push(syn::parse_quote!( #[cfg(feature = "std")] )); let where_clause = &genesis_build.where_clause; quote::quote_spanned!(genesis_build.attr_span => diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 3cd8378be45d1..43ed9764f7d66 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1522,8 +1522,6 @@ pub mod tests { /// Prelude to be used alongside pallet macro, for ease of use. pub mod pallet_prelude { - #[cfg(feature = "std")] - pub use crate::traits::GenesisBuild; pub use crate::{ dispatch::{ DispatchClass, DispatchError, DispatchResult, DispatchResultWithPostInfo, Parameter, @@ -1540,8 +1538,8 @@ pub mod pallet_prelude { }, }, traits::{ - ConstU32, EnsureOrigin, Get, GetDefault, GetStorageVersion, Hooks, IsType, - PalletInfoAccess, StorageInfoTrait, StorageVersion, TypedGet, + ConstU32, EnsureOrigin, GenesisBuild, Get, GetDefault, GetStorageVersion, Hooks, + IsType, PalletInfoAccess, StorageInfoTrait, StorageVersion, TypedGet, }, Blake2_128, Blake2_128Concat, Blake2_256, CloneNoBound, DebugNoBound, EqNoBound, Identity, PartialEqNoBound, RuntimeDebug, RuntimeDebugNoBound, Twox128, Twox256, Twox64Concat, diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index ebcf328d71474..3db274c1720c6 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -80,11 +80,9 @@ pub use metadata::{ }; mod hooks; -#[cfg(feature = "std")] -pub use hooks::GenesisBuild; pub use hooks::{ - Hooks, IntegrityTest, OnFinalize, OnGenesis, OnIdle, OnInitialize, OnRuntimeUpgrade, - OnTimestampSet, + GenesisBuild, Hooks, IntegrityTest, OnFinalize, OnGenesis, OnIdle, OnInitialize, + OnRuntimeUpgrade, OnTimestampSet, }; pub mod schedule; diff --git a/frame/support/src/traits/hooks.rs b/frame/support/src/traits/hooks.rs index 12dcd6af0f791..7dda6624ffe65 100644 --- a/frame/support/src/traits/hooks.rs +++ b/frame/support/src/traits/hooks.rs @@ -361,13 +361,13 @@ pub trait Hooks { /// A trait to define the build function of a genesis config, T and I are placeholder for pallet /// trait and pallet instance. -#[cfg(feature = "std")] pub trait GenesisBuild: Default + sp_runtime::traits::MaybeSerializeDeserialize { /// The build function is called within an externalities allowing storage APIs. /// Thus one can write to storage using regular pallet storages. fn build(&self); /// Build the storage using `build` inside default storage. + #[cfg(feature = "std")] fn build_storage(&self) -> Result { let mut storage = Default::default(); self.assimilate_storage(&mut storage)?; @@ -375,6 +375,7 @@ pub trait GenesisBuild: Default + sp_runtime::traits::MaybeSerializeD } /// Assimilate the storage for this module into pre-existing overlays. + #[cfg(feature = "std")] fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { sp_state_machine::BasicExternalities::execute_with_storage(storage, || { self.build(); diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index 68411210f9b5c..7fc3d1b92f9c1 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -36,21 +36,22 @@ test-pallet = { package = "frame-support-test-pallet", default-features = false, [features] default = ["std"] std = [ - "serde/std", "codec/std", - "scale-info/std", "frame-benchmarking/std", "frame-executive/std", "frame-support/std", "frame-system/std", + "scale-info/std", + "serde/std", + "sp-api/std", + "sp-arithmetic/std", "sp-core/std", - "sp-std/std", "sp-io/std", "sp-runtime/std", "sp-state-machine", - "sp-arithmetic/std", + "sp-std/std", "sp-version/std", - "sp-api/std", + "test-pallet/std", ] try-runtime = [ "frame-support/try-runtime", diff --git a/frame/support/test/pallet/Cargo.toml b/frame/support/test/pallet/Cargo.toml index 135d0e64b8ff4..c08fba324eef6 100644 --- a/frame/support/test/pallet/Cargo.toml +++ b/frame/support/test/pallet/Cargo.toml @@ -14,6 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive"] } scale-info = { version = "2.0.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.136", default-features = false, features = ["derive"] } frame-support = { version = "4.0.0-dev", default-features = false, path = "../../" } frame-system = { version = "4.0.0-dev", default-features = false, path = "../../../system" } @@ -24,4 +25,5 @@ std = [ "frame-support/std", "frame-system/std", "scale-info/std", + "serde/std", ] diff --git a/frame/support/test/tests/construct_runtime_ui/no_std_genesis_config.stderr b/frame/support/test/tests/construct_runtime_ui/no_std_genesis_config.stderr deleted file mode 100644 index afa210c1ae59d..0000000000000 --- a/frame/support/test/tests/construct_runtime_ui/no_std_genesis_config.stderr +++ /dev/null @@ -1,130 +0,0 @@ -error: `Pallet` does not have the std feature enabled, this will cause the `test_pallet::GenesisConfig` type to not implement serde traits. - --> tests/construct_runtime_ui/no_std_genesis_config.rs:40:1 - | -40 | / construct_runtime! { -41 | | pub struct Runtime where -42 | | Block = Block, -43 | | NodeBlock = Block, -... | -48 | | } -49 | | } - | |_^ - | - = note: this error originates in the macro `test_pallet::__substrate_genesis_config_check::is_std_enabled_for_genesis` which comes from the expansion of the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: the trait bound `frame_support_test_pallet::GenesisConfig: Serialize` is not satisfied - --> tests/construct_runtime_ui/no_std_genesis_config.rs:40:1 - | -40 | / construct_runtime! { -41 | | pub struct Runtime where -42 | | Block = Block, -43 | | NodeBlock = Block, -... | -48 | | } -49 | | } - | |_^ the trait `Serialize` is not implemented for `frame_support_test_pallet::GenesisConfig` - | - = help: the following other types implement trait `Serialize`: - &'a T - &'a mut T - () - (T0, T1) - (T0, T1, T2) - (T0, T1, T2, T3) - (T0, T1, T2, T3, T4) - (T0, T1, T2, T3, T4, T5) - and $N others -note: required by a bound in `hidden_include::serde::ser::SerializeStruct::serialize_field` - --> $CARGO/serde-1.0.162/src/ser/mod.rs - | - | T: Serialize; - | ^^^^^^^^^ required by this bound in `SerializeStruct::serialize_field` - = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: the trait bound `frame_support_test_pallet::GenesisConfig: Deserialize<'_>` is not satisfied - --> tests/construct_runtime_ui/no_std_genesis_config.rs:47:3 - | -47 | Pallet: test_pallet::{Pallet, Config}, - | ^^^^^^ the trait `Deserialize<'_>` is not implemented for `frame_support_test_pallet::GenesisConfig` - | - = help: the following other types implement trait `Deserialize<'de>`: - <&'a [u8] as Deserialize<'de>> - <&'a std::path::Path as Deserialize<'de>> - <&'a str as Deserialize<'de>> - <() as Deserialize<'de>> - <(T0, T1) as Deserialize<'de>> - <(T0, T1, T2) as Deserialize<'de>> - <(T0, T1, T2, T3) as Deserialize<'de>> - <(T0, T1, T2, T3, T4) as Deserialize<'de>> - and $N others -note: required by a bound in `next_element` - --> $CARGO/serde-1.0.162/src/de/mod.rs - | - | T: Deserialize<'de>, - | ^^^^^^^^^^^^^^^^ required by this bound in `SeqAccess::next_element` - -error[E0277]: the trait bound `frame_support_test_pallet::GenesisConfig: Deserialize<'_>` is not satisfied - --> tests/construct_runtime_ui/no_std_genesis_config.rs:47:3 - | -47 | Pallet: test_pallet::{Pallet, Config}, - | ^^^^^^ the trait `Deserialize<'_>` is not implemented for `frame_support_test_pallet::GenesisConfig` - | - = help: the following other types implement trait `Deserialize<'de>`: - <&'a [u8] as Deserialize<'de>> - <&'a std::path::Path as Deserialize<'de>> - <&'a str as Deserialize<'de>> - <() as Deserialize<'de>> - <(T0, T1) as Deserialize<'de>> - <(T0, T1, T2) as Deserialize<'de>> - <(T0, T1, T2, T3) as Deserialize<'de>> - <(T0, T1, T2, T3, T4) as Deserialize<'de>> - and $N others -note: required by a bound in `next_value` - --> $CARGO/serde-1.0.162/src/de/mod.rs - | - | V: Deserialize<'de>, - | ^^^^^^^^^^^^^^^^ required by this bound in `MapAccess::next_value` - -error[E0277]: the trait bound `frame_support_test_pallet::GenesisConfig: Deserialize<'_>` is not satisfied - --> tests/construct_runtime_ui/no_std_genesis_config.rs:40:1 - | -40 | / construct_runtime! { -41 | | pub struct Runtime where -42 | | Block = Block, -43 | | NodeBlock = Block, -... | -48 | | } -49 | | } - | |_^ the trait `Deserialize<'_>` is not implemented for `frame_support_test_pallet::GenesisConfig` - | - = help: the following other types implement trait `Deserialize<'de>`: - <&'a [u8] as Deserialize<'de>> - <&'a std::path::Path as Deserialize<'de>> - <&'a str as Deserialize<'de>> - <() as Deserialize<'de>> - <(T0, T1) as Deserialize<'de>> - <(T0, T1, T2) as Deserialize<'de>> - <(T0, T1, T2, T3) as Deserialize<'de>> - <(T0, T1, T2, T3, T4) as Deserialize<'de>> - and $N others -note: required by a bound in `hidden_include::serde::__private::de::missing_field` - --> $CARGO/serde-1.0.162/src/private/de.rs - | - | V: Deserialize<'de>, - | ^^^^^^^^^^^^^^^^ required by this bound in `missing_field` - = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: the trait bound `frame_support_test_pallet::GenesisConfig: BuildModuleGenesisStorage` is not satisfied - --> tests/construct_runtime_ui/no_std_genesis_config.rs:40:1 - | -40 | / construct_runtime! { -41 | | pub struct Runtime where -42 | | Block = Block, -43 | | NodeBlock = Block, -... | -48 | | } -49 | | } - | |_^ the trait `BuildModuleGenesisStorage` is not implemented for `frame_support_test_pallet::GenesisConfig` - | - = help: the trait `BuildModuleGenesisStorage` is implemented for `frame_system::GenesisConfig` - = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/frame/support/test/tests/construct_runtime_ui/no_std_genesis_config.rs b/frame/support/test/tests/pallet_ui/pass/no_std_genesis_config.rs similarity index 100% rename from frame/support/test/tests/construct_runtime_ui/no_std_genesis_config.rs rename to frame/support/test/tests/pallet_ui/pass/no_std_genesis_config.rs diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index f3d75f719d54c..64db2f46fd4eb 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -707,7 +707,6 @@ pub struct EventRecord { // Create a Hash with 69 for each byte, // only used to build genesis config. -#[cfg(feature = "std")] fn hash69 + Default>() -> T { let mut h = T::default(); h.as_mut().iter_mut().for_each(|byte| *byte = 69); diff --git a/test-utils/runtime/src/substrate_test_pallet.rs b/test-utils/runtime/src/substrate_test_pallet.rs index 93a1a5efceeb9..20467523f7375 100644 --- a/test-utils/runtime/src/substrate_test_pallet.rs +++ b/test-utils/runtime/src/substrate_test_pallet.rs @@ -55,7 +55,7 @@ pub mod pallet { pub type Authorities = StorageValue<_, Vec, ValueQuery>; #[pallet::genesis_config] - #[cfg_attr(feature = "std", derive(Default))] + #[derive(Default)] pub struct GenesisConfig { pub authorities: Vec, }