Substrate allows you to "re-dispatch" an extrinsic, for example when calling the sudo
function in the sudo module we have:
let res = match proposal.dispatch(system::RawOrigin::Root.into()) {
Ok(_) => true,
Err(e) => {
let e: DispatchError = e.into();
sr_primitives::print(e);
false
}
};
In this model, the underlying extrinsic being executed (proposal
) does not go through the SignedExtension flow, so will not collect any fees (fees are collected based on the sudo
function, not the underlying proposal
.
In this example that may be reasonable (since the sudo account is special and can be considered to be trusted), but in other cases (e.g. with a multisig which re-dispatches a proposed transaction) this doesn't seem to be the case.
Is there any way to pass a proposal back through the SignedExtension flow so that things like TakeFee
can be assessed on the underlying transaction?
Indeed you can see pallet_sudo take a Dispatchable, this dispatchable doesn't contains the weight information available in DispatchInfo, nor any logic to compute fees.
If you want to compute fees maybe you want not a dispatchable but the actual extrinsic to execute. The frame-executive crate is generic over the extrinsic, you should be able to make use of similar trait bounds.
Then in the runtime definition (bin/node/runtime/src/lib.rs) you should be able to make something like:
impl pallet_mine::Trait for Runtime {
extrinsic: UncheckedExtrinsic
}