Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update genesis_config related docs and tests and error messages #1642

Merged
merged 6 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 0 additions & 46 deletions substrate/frame/support/procedural/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1417,57 +1417,11 @@ pub fn type_value(_: TokenStream, _: TokenStream) -> TokenStream {
pallet_macro_stub()
}

/// The `#[pallet::genesis_config]` attribute allows you to define the genesis configuration
/// for the pallet.
///
/// Item is defined as either an enum or a struct. It needs to be public and implement the
/// trait `GenesisBuild` with [`#[pallet::genesis_build]`](`macro@genesis_build`). The type
/// generics are constrained to be either none, or `T` or `T: Config`.
///
/// E.g:
///
/// ```ignore
/// #[pallet::genesis_config]
/// pub struct GenesisConfig<T: Config> {
/// _myfield: BalanceOf<T>,
/// }
/// ```
#[proc_macro_attribute]
pub fn genesis_config(_: TokenStream, _: TokenStream) -> TokenStream {
pallet_macro_stub()
}

/// The `#[pallet::genesis_build]` attribute allows you to define how `genesis_configuration`
/// is built. This takes as input the `GenesisConfig` type (as `self`) and constructs the pallet's
/// initial state.
///
/// The impl must be defined as:
///
/// ```ignore
/// #[pallet::genesis_build]
/// impl<T: Config> GenesisBuild<T> for GenesisConfig<$maybe_generics> {
/// fn build(&self) { $expr }
/// }
/// ```
///
/// I.e. a trait implementation with generic `T: Config`, of trait `GenesisBuild<T>` on
/// type `GenesisConfig` with generics none or `T`.
///
/// E.g.:
///
/// ```ignore
/// #[pallet::genesis_build]
/// impl<T: Config> GenesisBuild<T> for GenesisConfig {
/// fn build(&self) {}
/// }
/// ```
///
/// ## Macro expansion
///
/// The macro will add the following attribute:
/// * `#[cfg(feature = "std")]`
///
/// The macro will implement `sp_runtime::BuildStorage`.
#[proc_macro_attribute]
pub fn genesis_build(_: TokenStream, _: TokenStream) -> TokenStream {
pallet_macro_stub()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub fn expand_genesis_build(def: &mut Def) -> proc_macro2::TokenStream {
#[cfg(feature = "std")]
impl<#type_impl_gen> #frame_support::sp_runtime::BuildStorage for #gen_cfg_ident<#gen_cfg_use_gen> #where_clause
{
fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> std::result::Result<(), std::string::String> {
fn assimilate_storage(&self, storage: &mut #frame_support::sp_runtime::Storage) -> std::result::Result<(), std::string::String> {
#frame_support::__private::BasicExternalities::execute_with_storage(storage, || {
self.build();
Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ pub fn check_type_def_gen(
/// return the instance if found for `GenesisBuild`
/// return None for BuildGenesisConfig
pub fn check_genesis_builder_usage(type_: &syn::Path) -> syn::Result<Option<InstanceUsage>> {
let expected = "expected `GenesisBuild<T>` or `GenesisBuild<T, I>`";
let expected = "expected `BuildGenesisConfig` (or the deprecated `GenesisBuild<T>` or `GenesisBuild<T, I>`)";
pub struct Checker(Option<InstanceUsage>);
impl syn::parse::Parse for Checker {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
Expand Down
76 changes: 73 additions & 3 deletions substrate/frame/support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2188,10 +2188,80 @@ pub mod pallet_macros {
pub use frame_support_procedural::{
call_index, compact, composite_enum, config, constant,
disable_frame_system_supertrait_check, error, event, extra_constants, generate_deposit,
generate_store, genesis_build, genesis_config, getter, hooks, import_section, inherent,
no_default, no_default_bounds, origin, pallet_section, storage, storage_prefix,
storage_version, type_value, unbounded, validate_unsigned, weight, whitelist_storage,
generate_store, getter, hooks, import_section, inherent, no_default, no_default_bounds,
origin, pallet_section, storage, storage_prefix, storage_version, type_value, unbounded,
validate_unsigned, weight, whitelist_storage,
};

/// Allows you to define the genesis configuration for the pallet.
///
/// Item is defined as either an enum or a struct. It needs to be public and implement the
/// trait [`frame_support::traits::BuildGenesisConfig`].
///
/// See [`genesis_build`] for an example.
pub use frame_support_procedural::genesis_config;

/// Allows you to define how the state of your pallet at genesis is build is built. This
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
/// takes as input the `GenesisConfig` type (as `self`) and constructs the pallet's initial
/// state.
///
/// The fields of the `GenesisConfig` can in turn be populated by the chain-spec.
///
/// ## Example:
///
/// ```
/// #[frame_support::pallet]
/// pub mod pallet {
/// # #[pallet::config]
/// # pub trait Config: frame_system::Config {}
/// # #[pallet::pallet]
/// # pub struct Pallet<T>(_);
/// # use frame_support::traits::BuildGenesisConfig;
/// #[pallet::genesis_config]
/// #[derive(frame_support::DefaultNoBound)]
/// pub struct GenesisConfig<T: Config> {
/// foo: Vec<T::AccountId>
/// }
///
/// #[pallet::genesis_build]
/// impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
/// fn build(&self) {
/// // use &self to access fields.
/// let foo = &self.foo;
/// todo!()
/// }
/// }
/// }
/// ```
///
/// ## Former Usage
///
/// Priori to <https://github.com/paritytech/substrate/pull/14306>, the following syntax was used.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
/// This is deprecated and will soon be removed.
///
/// ```
/// #[frame_support::pallet]
/// pub mod pallet {
/// # #[pallet::config]
/// # pub trait Config: frame_system::Config {}
/// # #[pallet::pallet]
/// # pub struct Pallet<T>(_);
/// # use frame_support::traits::GenesisBuild;
/// #[pallet::genesis_config]
/// #[derive(frame_support::DefaultNoBound)]
/// pub struct GenesisConfig<T: Config> {
/// foo: Vec<T::AccountId>
/// }
///
/// #[pallet::genesis_build]
/// impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
/// fn build(&self) {
/// todo!()
/// }
/// }
/// }
/// ```
pub use frame_support_procedural::genesis_build;
}

#[deprecated(note = "Will be removed after July 2023; Use `sp_runtime::traits` directly instead.")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ error[E0277]: `<T as pallet::Config>::Bar` doesn't implement `std::fmt::Debug`
|
= help: the trait `std::fmt::Debug` is not implemented for `<T as pallet::Config>::Bar`
= note: required for `&<T as pallet::Config>::Bar` to implement `std::fmt::Debug`
= note: required for the cast from `&<T as pallet::Config>::Bar` to the object type `dyn std::fmt::Debug`
= note: required for the cast from `&&<T as pallet::Config>::Bar` to `&dyn std::fmt::Debug`

error[E0277]: the trait bound `<T as pallet::Config>::Bar: Clone` is not satisfied
--> tests/pallet_ui/call_argument_invalid_bound.rs:38:36
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ error[E0277]: `<T as pallet::Config>::Bar` doesn't implement `std::fmt::Debug`
|
= help: the trait `std::fmt::Debug` is not implemented for `<T as pallet::Config>::Bar`
= note: required for `&<T as pallet::Config>::Bar` to implement `std::fmt::Debug`
= note: required for the cast from `&<T as pallet::Config>::Bar` to the object type `dyn std::fmt::Debug`
= note: required for the cast from `&&<T as pallet::Config>::Bar` to `&dyn std::fmt::Debug`

error[E0277]: the trait bound `<T as pallet::Config>::Bar: Clone` is not satisfied
--> tests/pallet_ui/call_argument_invalid_bound_2.rs:38:36
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ error[E0277]: `Bar` doesn't implement `std::fmt::Debug`
= help: the trait `std::fmt::Debug` is not implemented for `Bar`
= note: add `#[derive(Debug)]` to `Bar` or manually `impl std::fmt::Debug for Bar`
= note: required for `&Bar` to implement `std::fmt::Debug`
= note: required for the cast from `&Bar` to the object type `dyn std::fmt::Debug`
= note: required for the cast from `&&Bar` to `&dyn std::fmt::Debug`
help: consider annotating `Bar` with `#[derive(Debug)]`
|
34 + #[derive(Debug)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ error[E0277]: `<T as pallet::Config>::Bar` doesn't implement `std::fmt::Debug`
|
= help: the trait `std::fmt::Debug` is not implemented for `<T as pallet::Config>::Bar`
= note: required for `&<T as pallet::Config>::Bar` to implement `std::fmt::Debug`
= note: required for the cast from `&<T as pallet::Config>::Bar` to the object type `dyn std::fmt::Debug`
= note: required for the cast from `&&<T as pallet::Config>::Bar` to `&dyn std::fmt::Debug`
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Invalid genesis builder: expected `GenesisBuild<T>` or `GenesisBuild<T, I>`
error: Invalid genesis builder: expected `BuildGenesisConfig` (or the deprecated `GenesisBuild<T>` or `GenesisBuild<T, I>`)
--> tests/pallet_ui/genesis_invalid_generic.rs:36:7
|
36 | impl GenesisBuild for GenesisConfig {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ error[E0046]: not all trait items implemented, missing: `Call`, `Error`, `INHERE
36 | impl<T: Config> ProvideInherent for Pallet<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Call`, `Error`, `INHERENT_IDENTIFIER`, `create_inherent`, `is_inherent` in implementation
|
= help: implement the missing item: `type Call = Type;`
= help: implement the missing item: `type Error = Type;`
= help: implement the missing item: `type Call = /* Type */;`
= help: implement the missing item: `type Error = /* Type */;`
= help: implement the missing item: `const INHERENT_IDENTIFIER: [u8; 8] = value;`
= help: implement the missing item: `fn create_inherent(_: &InherentData) -> std::option::Option<<Self as ProvideInherent>::Call> { todo!() }`
= help: implement the missing item: `fn is_inherent(_: &<Self as ProvideInherent>::Call) -> bool { todo!() }`