在 Substrate 运行时中跨不同模块调用 `on_initialize` 的顺序是什么?

Bed*_*der 6 rust blockchain substrate

我需要确保on_initialize特定模块的处理程序在运行时中的所有其他模块之前的相同处理程序之前运行。

a) 如何确保这一点?

b) 是否有一些编译或运行时检查我可以强制执行以绝对保证这将得到尊重?

Sha*_*izi 9

on_initialize每个 Substrate 运行时模块的函数都通过执行模块调用,该模块处理所有顶级内容;本质上只是执行块/外部。

每次执行一个块 ( execute_block) 时,首先initialize_block调用它,最终调用on_initalizeAllModules类型的块:

srml/executive/src/lib.rs

<AllModules as OnInitialize<System::BlockNumber>>::on_initialize(*block_number);
Run Code Online (Sandbox Code Playgroud)

AllModules类型是在运行时不同的模块标识符的元组。它由construct_runtime!生成并按照您在宏中定义的顺序列出模块。例如,对于给定的construct_runtime!定义:

construct_runtime!(
    pub enum Runtime with Log(InternalLog: DigestItem<Hash, AuthorityId, AuthoritySignature>) where
        Block = Block,
        NodeBlock = opaque::Block,
        UncheckedExtrinsic = UncheckedExtrinsic
    {
        System: system::{default, Log(ChangesTrieRoot)},
        Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
        Consensus: consensus::{Module, Call, Storage, Config<T>, Log(AuthoritiesChange), Inherent},
        Aura: aura::{Module},
        Indices: indices,
        Balances: balances,
        Sudo: sudo,
        // Used for the module template in `./template.rs`
        TemplateModule: template::{Module, Call, Storage, Event<T>},
        TemplateModule1: template1::{Module, Call, Storage, Event<T>},
        TemplateModule2: template2::{Module, Call, Storage, Event<T>},
    }
);
Run Code Online (Sandbox Code Playgroud)

您将获得以下AllModules类型:

type AllModules = (Timestamp, Consensus, Aura, Indices, Balances, Sudo, TemplateModule, TemplateModule1, TemplateModule2);
Run Code Online (Sandbox Code Playgroud)

因此,on_initialize函数的调用顺序是您在运行时中定义模块的顺序。您无需执行任何操作即可“确保尊重这一点”,因为此处的代码流是连续的且具有确定性的。