If I have some extrinsic with weight W
and I call another pallet function inside it which has weight X
, does it mean I have to annotate my function's weight as W + X
? What happens if I don't? For eg: do I run the risk of potentially missing out building valid blocks as a result of weight underestimation?
1 Answer
Weight annotations are only needed for Call
s, not for internal pallet functions.
The weight of the internal pallet function will be included in the weigh of the Call
. So for example:
#[pallet::weight(T::WeightInfo::my_call())]
pub fn my_call(origin: OriginFor<T>) -> DispatchResult {
ensure_signed(origin)?;
Self::do_my_call()
}
Now when the FRAME benchmarking estimates the Weight of my_call
, it will include do_my_call
. These do_*
function patterns are quite common in Substrate as it makes the functionality re-usable. For example in the ranked-collective which just delegates the real work to an internal do_
function. Having these do_
functions is also useful to implement traits later on, so it is a good idea anyway.
-
I see, however my question is regarding calling other "extrinsics" meaning from PalletA::Call to PalletB::Call.– b0zeroMar 3, 2023 at 13:30
-
Pallet calls should not call each other. That is what traits are for. Mar 3, 2023 at 14:33
-
could you elaborate a bit more with the context behind "traits". I understand you can have a trait that's implemented by some pallet, and we can thus make use of foreign pallet code via the trait methods, but what happens with the weight calculation? If for instance the other pallet expects a signed origin, and our pallet received a signed call, we can maybe bypass the requirement in the other pallet, but what about the total weight calculation?– b0zeroMar 14, 2023 at 9:09
-
The weight of the
do_function
will be included in the call itself, no need to pass it around explicetly. Mar 14, 2023 at 12:25