重新派遣功能的费用

Fees for re-dispatched functions

Substrate 允许你 "re-dispatch" 一个外部函数,例如当调用 sudo 模块中的 sudo 函数时,我们有:

            let res = match proposal.dispatch(system::RawOrigin::Root.into()) {
                Ok(_) => true,
                Err(e) => {
                    let e: DispatchError = e.into();
                    sr_primitives::print(e);
                    false
                }
            };

在这个模型中,正在执行的底层extrinsic(proposal)不经过SignedExtension流程,因此不会收取任何费用(费用是根据sudo功能收取的,不是基础 proposal.

在这个例子中,这可能是合理的(因为 sudo 帐户是特殊的,可以被认为是可信的),但在其他情况下(例如,使用重新发送提议交易的多重签名)这似乎不是正是如此。

是否有任何方法可以通过 SignedExtension 流程将提案传回,以便可以对基础交易进行评估 TakeFee 之类的事情?

您确实可以看到 pallet_sudo 采取 Dispatchable, this dispatchable doesn't contains the weight information available in DispatchInfo,也没有任何计算费用的逻辑。

如果你想计算费用,也许你不想要一个可调度的,而是真正的外部执行。 frame-executive crate 是通用的,你应该可以使用类似的 trait bounds.

然后在运行时定义 (bin/node/runtime/src/lib.rs) 中,您应该能够做出如下内容:

impl pallet_mine::Trait for Runtime {
    extrinsic: UncheckedExtrinsic
}

@thiolliere 推荐的内容对我来说听起来很合理。详细说明一下:

  • executive 中需要运行时的通用 Extrinsic 类型才能具有特征 Applyable。在Applyable的实现中,你看到内部调用是Dispatchable.
  • 已签名的扩展管道在同一特征的 fn apply() 内触发。所以你可能想要做: type Extrinsic: Applyable<_, _> 在你的特征中,并且如前所述将运行时的外部类型传递给它。

在一天结束时,它归结为对高级、不透明 Extrinsic 或更精细的内部 Dispatchable Call 枚举变体进行抽象。

请注意,根据您想要实现的目标,您也可以只对内部调用保持抽象,并手动扣除更多费用。您可以将提案类型(如果类似于民主,它只是一个 Call)绑定到 GetDispatchInfo(即 type Proposal: Dispatchable + ... + GetDispatchInfo)。这允许您通过 poposal.get_dispatch_info() 读取重量值。结合编码长度,您实际上可以复制或做类似于 TakeFees 正在做的事情。