-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Automatic pallet parts in construct_runtime #9681
Conversation
In terms of syntax, I was thinking more of a rustic convention by using |
Holy crud, there's definitely a macro-ception going on in this PR, I think I need some strong caffeine for this. One thing that's immediately apparent from this complexity is the maintainability of it. Could just be an issue with documentation, but I think what's really missing now is some sort of flowchart that explains how everything gets strung together in the end. In addition, compilation times of pallets will definitely increase as a result, and while I think we're not hitting any limits yet (recursion or otherwise), we may need to keep an eye on it sooner or later. |
Lottery: pallet_lottery, | ||
Gilt: pallet_gilt, | ||
Uniques: pallet_uniques, | ||
TransactionStorage: pallet_transaction_storage, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️ This looks a lot cleaner.
I'm not sure about excluded. Better to be explicit with your includes if you want to exclude something - it's a bit more rusty. |
bin/node/runtime/src/lib.rs
Outdated
Balances: pallet_balances, | ||
TransactionPayment: pallet_transaction_payment, | ||
ElectionProviderMultiPhase: pallet_election_provider_multi_phase, | ||
Staking: pallet_staking, | ||
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The <T>
generic here still makes me a bit sad, but that's really what #8743 aims to solve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes but I expect nobody to use this syntax anymore once all pallet use pallet
macro.
maybe we can explicit whitelist syntax like use_parts
as well.
about syntax I'm usually a bit skeptical of using rusty syntax for stuff which are not rust syntax, it sometimes lead to more confusion about the true possible syntax than it helps.
In this example I like to exclude because:
That said if we introduce new parts in the future all those points might not stand anymore. So maybe we can do
Yes agree, I'll improve documentation, with good dev documentation I think this complexity is not so difficult to maintain. |
at some point we can have both |
Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me
/// Test3_DefaultInstance: test3, | ||
/// | ||
/// // with `exclude_parts` keyword some part can be excluded. | ||
/// Test4_Instance1: test4::<Instance1> exclude_parts { Call, Origin }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Test4_Instance1: test4::<Instance1> exclude_parts { Call, Origin }, | |
/// Test4_Instance1: test4::<Instance1>::{ !Call, !Origin }, |
Would such a syntax be possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the thing is I want to be backward compatible.
In case somebody writes: Test: test::{Config}
, does that mean the pallet has a config part with no generic and user want to set it. or does it mean that the pallet has a config part which is maybe generic or maybe not and user want to set it.
In the first case we don't need to retrieve the parts from the pallet, which is needed for pallets with decl_module.
In the second case we need to retrieve the parts from the pallet, which is a breaking change for pallets with decl_module which don't support it.
So the way the PR implements it is:
- either part are manually declared. So no need to retrieve the part from the pallet
- or the part are not declared and just whitelisted/blacklisted. So we will call into the pallet to get the parts.
Maybe we can improve the syntax but we can't mix them together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a way to implemented could to have something like:
Test: test $some_keyword_or_any_token_to_indicate_that_parts_should_be_retrieved_from_pallet {Pallet, !Call}
But also I don't know I implemented this PR so that when you blacklist/whitelist a part, it must be an existing part of the pallet.
Like you can't do use_parts { Call }
if the pallet has no call.
UncheckedExtrinsic = UncheckedExtrinsic | ||
{ | ||
System: system::{Pallet, Call, Storage, Config, Event<T>}, | ||
Pallet: pallet exclude_parts { Pallet } use_parts { Pallet }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pallet: pallet exclude_parts { Pallet } use_parts { Pallet }, | |
Pallet: pallet::{ !Pallet, Pallet }, |
bot merge |
Waiting for commit status. |
@nukemandan those configuration types and the things in the Each pallet has a set of objects generated for each of them depending on which macros you use and what you generate. For example:
Whereas those are configuration types needed for https://github.com/paritytech/substrate/blob/master/frame/system/src/lib.rs#L162 Obviously they are related, but nothing about what the |
Yes this PR is only about construct_runtime declaration, in the past it was mandatory to declare each "parts" to use for a pallet. For example: Config part will put the pallet genesis config into the aggregated runtime genesis config, etc.. |
fwiw I do agree that these types being magically generated is a bit confusing, and I strongly think they should be prefixed with 'Outer', e.g. OuterCall. |
Disagree on the "Outer" prefix, because you need to understand what "inner" is, and it's not self-evident what they are. Stepping back a bit, I think this is a problem that existed even before the implicit part declarations. Before this PR, it was not clear what the |
The key point here are missing docs. We just need more and better docs. I just searched the devhub and couldn't find an article about |
how is naming both the outer call and inner call For example, |
I think |
* implement automatic parts * ui tests * rename * remove unnecessary exclude * better doc * better doc * fix genesis config * fix UI tests * fix UI test * Revert "fix UI test" This reverts commit a910351. * implemented used_parts * Update frame/support/procedural/src/construct_runtime/mod.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * doc + fmt * Update frame/support/procedural/src/construct_runtime/parse.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * add doc in the macro * remove yet some more parts * fix ui test * more determnistic error message + fix ui tests * fix ui test * Apply suggestions from code review Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * do refactor + fix ui tests * fmt * fix test * fix test * fix ui test * Apply suggestions from code review Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * refactor * remove even more part in node-runtime * fix test * Add flow chart for the construct_runtime! execution flow * Fix typo * Ignore snippets that don't contain code * Refactor some code in expand_after * Rename expand_after to match_and_insert * cargo fmt * Fix rename * Remove frame_support argument to construct_runtime_parts * Make use of tt-call to simplify intermediate expansions * cargo fmt * Update match_and_insert documentation * Reset cursor to 0 when no matching patterns are found * Reorder struct fields on MatchAndInsertDef * Add test for dependency renames and fix frame-support import * Add more doc comments * Update frame/support/test/compile_pass/src/lib.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
* implement automatic parts * ui tests * rename * remove unnecessary exclude * better doc * better doc * fix genesis config * fix UI tests * fix UI test * Revert "fix UI test" This reverts commit a910351. * implemented used_parts * Update frame/support/procedural/src/construct_runtime/mod.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * doc + fmt * Update frame/support/procedural/src/construct_runtime/parse.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * add doc in the macro * remove yet some more parts * fix ui test * more determnistic error message + fix ui tests * fix ui test * Apply suggestions from code review Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * do refactor + fix ui tests * fmt * fix test * fix test * fix ui test * Apply suggestions from code review Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * refactor * remove even more part in node-runtime * fix test * Add flow chart for the construct_runtime! execution flow * Fix typo * Ignore snippets that don't contain code * Refactor some code in expand_after * Rename expand_after to match_and_insert * cargo fmt * Fix rename * Remove frame_support argument to construct_runtime_parts * Make use of tt-call to simplify intermediate expansions * cargo fmt * Update match_and_insert documentation * Reset cursor to 0 when no matching patterns are found * Reorder struct fields on MatchAndInsertDef * Add test for dependency renames and fix frame-support import * Add more doc comments * Update frame/support/test/compile_pass/src/lib.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
Fix #8084
can also superseed #8743 (considering that the
exclude_parts
and use_parts` doesn't require giving the generics).for pallet declared with the
pallet
attribute macro, the pallet parts can now be automatically derived.Also it is possible to exclude some parts manually.
the syntax can be discussed, it is currently with 2 new keywords
exclude_parts
anduse_parts
If any part specified in
use_parts
orexclude_parts
are not a part generated by the pallet (like if user writeexclude_parts { Call }
and the pallet has noCall
. Then an error message is generated, telling that only available parts can be excluded or used.(I'll do remove the parts in pallets mock in another PR)
How does it work:
pallet macro generates a macro
tt_default_parts
.construct_runtime will call the macro
tt_default_parts
viatt_call
in order to retrieve the pallet parts.More precisely the macro call:
will generate a macro call:
This will expand to:
And this contains all the parts information and so will finish the expansion.
TODO