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 <>
This commit is contained in:
Michal Kucharczyk
2023-05-25 23:49:25 +02:00
committed by GitHub
parent 2aa863f667
commit e31a214a85
12 changed files with 20 additions and 158 deletions
+1
View File
@@ -2784,6 +2784,7 @@ dependencies = [
"frame-system",
"parity-scale-codec",
"scale-info",
"serde",
]
[[package]]
@@ -743,7 +743,10 @@ pub mod pallet {
Members::<T>::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,
@@ -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 =>
+2 -4
View File
@@ -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,
+2 -4
View File
@@ -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;
+2 -1
View File
@@ -361,13 +361,13 @@ pub trait Hooks<BlockNumber> {
/// 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<T, I = ()>: 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<sp_runtime::Storage, String> {
let mut storage = Default::default();
self.assimilate_storage(&mut storage)?;
@@ -375,6 +375,7 @@ pub trait GenesisBuild<T, I = ()>: 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();
+6 -5
View File
@@ -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",
@@ -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",
]
@@ -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<Runtime, ()>` 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<Runtime, ()>` is not implemented for `frame_support_test_pallet::GenesisConfig`
|
= help: the trait `BuildModuleGenesisStorage<T, ()>` 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)
-1
View File
@@ -707,7 +707,6 @@ pub struct EventRecord<E: Parameter + Member, T> {
// Create a Hash with 69 for each byte,
// only used to build genesis config.
#[cfg(feature = "std")]
fn hash69<T: AsMut<[u8]> + Default>() -> T {
let mut h = T::default();
h.as_mut().iter_mut().for_each(|byte| *byte = 69);
@@ -55,7 +55,7 @@ pub mod pallet {
pub type Authorities<T> = StorageValue<_, Vec<Public>, ValueQuery>;
#[pallet::genesis_config]
#[cfg_attr(feature = "std", derive(Default))]
#[derive(Default)]
pub struct GenesisConfig {
pub authorities: Vec<Public>,
}