Search code examples
blockchainparitysubstrate

Fees for re-dispatched functions


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?


Solution

  • 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
    }