Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Create attribute macro for defining common defaults for config associated types #9916

Closed
wants to merge 8 commits into from

Conversation

KiChjang
Copy link
Contributor

@KiChjang KiChjang commented Oct 2, 2021

May potentially fix paritytech/polkadot-sdk#367.

This PR introduces two new attributes, #[pallet::default_type] and #[frame_support::use_default_config_for], for the purpose of simplifying the setup of commonly used types for the associated types in a pallet's Config trait.

#[pallet::default_type(type)] can be put before a Config trait associated type to indicate the default value that the associated type should have. Note that the type provided to the attribute does not get evaluated during pallet construction and only during runtime construction. This means the following is possible:

// pallet.rs
trait Config: frame_system::Config {
    #[pallet::default_type(Call)] // can be used here even though `Call` is not defined in this pallet
    type Call: Parameter + GetDispatchInfo;
}

// runtime.rs
#[frame_support::use_default_config_for(Call)]
impl pallet::Config for Runtime {}

construct_runtime! {
    // ...
}

#[frame_support::use_default_config_for(ident)] can only be put on trait impl items that implement the Config trait for pallets. The type names provided to the attribute must exist in the Config trait definition as associated type items and must also have a #[pallet::default_type] declared, otherwise the compiler will emit the following error:

error: associated type `YourTypeNameHere` does not have a default type specified, or does not exist

If this is a desired change, we could then begin documenting Config associated type items and explaining what the default types are and how they behave.

@KiChjang KiChjang added A0-please_review Pull request needs code review. B3-apinoteworthy C1-low PR touches the given topic and has a low impact on builders. D3-trivial 🧸 PR contains trivial changes in a runtime directory that do not require an audit labels Oct 2, 2021
@bkchr
Copy link
Member

bkchr commented Oct 4, 2021

#[frame_support::use_default_config_for(Call)]
impl pallet::Config for Runtime {}

But this still means that the user needs to know what kind of fields a trait has to add them there? So, the only thing that is taken away from the user is the passing of the value? But even here we just assume that "Call" exists, which is true, but also rather shitty experience if that isn't true.

@KiChjang
Copy link
Contributor Author

KiChjang commented Oct 5, 2021

Yes, you'd still need to specify the names of the associated type items that you'd want to use the default for. I suppose I could also make an attribute macro or a new syntax that allows you to use the default types for all associated types in a Config impl, perhaps it's just #[frame_support::use_default_config] or impl_default_config_for!(path::to::Config).

Either way, the problem that you describe (i.e. default type being Call but it isn't actually defined during runtime construction) can possibly be solved by more documentation on the config associated type items, detailing what the default is and what is expected to exist. I suppose we could also try creating a special mechanism for types that are defined by construct_runtime!...

@xlc
Copy link
Contributor

xlc commented Oct 5, 2021

I am not sure how much code this is saving.

An alternative approach is instead of use associated type, replace as much of them as possible to methods with default implementation. Something similar to

https://github.com/paritytech/frontier/blob/7e6ab0ca9ffc074ebba4329606ecb90cfc27ec72/frame/evm/src/lib.rs#L146-L148

So this

/// The maximum length of a block (in bytes).
#[pallet::constant]
type BlockLength: Get<limits::BlockLength>;

can become this

/// The maximum length of a block (in bytes). 
 #[pallet::constant] 
 fn block_length() -> limits::BlockLength> { 10000 }

But this is going to be another major breaking change and changes the macro syntax.

@kianenigma
Copy link
Contributor

@xlc's idea is interesting. The downside would be lack of enforcing const, but I think it is a worthwhile approach. I think we can and should retire all these types and move to a combination of fn and const.

@shawntabrizi
Copy link
Member

I think XLC's idea is one we should follow anyway. Sounds like it would simplify a lot of the definitions, and practically speaking provides the same functionality.

@stale
Copy link

stale bot commented Dec 24, 2021

Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the A5-stale Pull request did not receive any updates in a long time. No review needed at this stage. Close it. label Dec 24, 2021
@stale stale bot closed this Jan 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review. A5-stale Pull request did not receive any updates in a long time. No review needed at this stage. Close it. C1-low PR touches the given topic and has a low impact on builders. D3-trivial 🧸 PR contains trivial changes in a runtime directory that do not require an audit
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Vision: Simplify test setup
5 participants