-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Minimize Macro Magic #3001
Comments
For 1, 2 and 3 I generally agree that it adds difficulty for using and understanding the macro and all in all doesn't help that much more than removing a few lines maybe. For the point 4 there is different solutions:
|
In short term, I want to rework this. In my "vision" the user has just to add
As long as Rust does not support specialization, we can not drop |
@bkchr does that mean that tricks like removing the "Call" type from a module, as I did with the sudo-contract project would not be possible? |
We could probably support opt-out of features. |
I'm ok with 1 and 3. assuming 4 will just force users to add an extra
|
We should address bullet 3 before v2.0 |
Not sure that this should be a blocker for 2.0. Who will work on this? |
To remove feature 3 should be trivial? The other 2 Gav says he would like to keep. |
Ahh I didn't read 3 properly 😅 I thought it is already about what I have in my mind, because that would take more time. |
A compromise on 2 might be |
I wanted to formally share some feedback I have seen regarding new developers building on Substrate, and some of the ways we can improve the experience by reducing the "magic" done by our Substrate macros.
I think it obvious that the Substrate macros are both a blessing and a curse. It helps users write clean and concise code, and reduces the amount of boilerplate code needed to get things working. However, it is also the place where users get the most complicated errors to solve, where it is hardest to gain visibility about what is happening in the background, and where it is hard to get help to resolve issues without talking to our team directly (versus talking to the Rust community or Rust references for example).
I suggest that we update some of the "features" in our various Substrate macros to increase consistancy and clarity on certain aspects, while having a minimal impact on the amount of code written.
Here are a list of "features" which I think should be removed, plus a small argument as to why I think this:
decl_module
: Omittingorigin
as the first parameter makes a function require root origin.origin
as the first parameter of a dispatchable function. When this happens, the macro automatically adds origin back as the first parameter, and also addsensure_root(origin)?
as the first line of the function. To begin, this decreases clarity of the "rules" when writing dispatchable functions. It is very easy to say "all dispatchable functions require origin as the first parameter to determine where the call is coming from, and the first check made in that function is to verify the origin is as expected." However, with this "feature", users who look at the Substrate code base will notice that we do not includeorigin
with all of our functions, and it is not clear at all in the program that the function is "privileged" in some way. Furthermore, in terms of auditing high privileged calls, our current syntax makes it impossible to do things like search forensure_root
to get a list of all the function which require ROOT origin. By removing this feature, we introduce at most ~25 characters to each privileged function, but increase the clarity of these functions and our rules immensely.decl_module
: Omitting when functions returnResult
and automatically addingOk(())
at the end.Result
and to not haveOk(())
returned at the end. When the macro detects this, both of these items are added back to the function automatically. Again, this causes confusion to new users who are told that all dispatchable functions should return aResult
, and then they look at our code and see that this is not the case. It will increase the number of characters by ~15 in functions which use the feature, but again drive clarity and simplicity where the alternative really is not needed.construct_runtime
: the use of "no types" ordefault
when defining your modules.Module, Call, Storage, Event, Config
. Theconstruct_runtime
macro is only ever defined one time for a blockchain, so trying to optimize the number of characters written here seems silly. Users are confused when they look at a runtime definition, and see thatsystem
usesdefault
+ another type, thatbalances
uses nothing, and that their custom runtime usesModule, Call, Storage, Event
. Being explicit about the types that each runtime exposes can be good to inform users building a runtime and picking from various modules created by third parties, and to users who want to better understand what is going on. Having greater visibility into the types here I think can only be a positive for new users trying to understand how things work. Again, since this is only ever defined once, I do not see the reason to choose optimization over clarity here.decl_module
: containing functions which are not dispatchable/callabledecl_module
macro has a set of "reserved function names" likeon_initialize
,on_finalize
,deposit_event
, and soonoffchain_worker
. These functions live next to all the dispatchable functions in your module, yet behave completely differently from them. It seem that thedecl_module
macro should be split into two parts, one which handles only your dispatchable functions, and the other which handles these special reserved functions. This is not actually something which drives a lot of confusion to users (at least not that I have seen), but I think something worth doing for additional clarity, and reducing the amount of work a single macro does.I would love feedback to understand if these opinions do not resonate with others.
The text was updated successfully, but these errors were encountered: