变更记录
- 2023 年 9 月 13 日:初始草案
状态
草稿摘要
引入PreBlock,它会在其他模块的 BeginBlocker 之前运行,并允许修改共识参数,且这些变更对后续的状态机逻辑可见。
背景
升级到 sdk 0.47 时,共识参数的存储格式发生了变化,但在迁移区块中,ctx.ConsensusParams() 始终为 nil,因为新代码无法加载旧格式。按设计应先由 x/upgrade 模块完成迁移,但遗憾的是,迁移发生在 BeginBlocker 处理器中,而它运行在 ctx 初始化之后。
当我们尝试解决这个问题时,发现 x/upgrade 模块无法修改上下文以让其他模块看到共识参数,因为上下文是按值传递的,而 sdk 团队希望保持这种方式,这对模块间隔离是有益的。
备选方案
第一个备选方案引入了一个MigrateModuleManager,目前它只包含 x/upgrade 模块。baseapp 会在其他模块之前运行其中的 BeginBlocker,并在两者之间重新加载上下文中的共识参数。
决策
建议引入这个新的生命周期方法。PreBlocker
这个新的生命周期方法有两层语义:
- 它会在所有模块的
BeginBlocker之前运行 - 它可以修改存储中的共识参数,并通过返回值通知调用方。
ConsensusParamsChanged=true 时,调用方必须在 finalize 上下文中刷新共识参数:
影响
向后兼容性
正面影响
负面影响
中性影响
后续讨论
测试用例
参考资料
Changelog
- Sept 13, 2023: Initial Draft
Status
DRAFTAbstract
IntroducePreBlock, which runs before begin blocker other modules, and allows to modify consensus parameters, and the changes are visible to the following state machine logics.
Context
When upgrading to sdk 0.47, the storage format for consensus parameters changed, but in the migration block,ctx.ConsensusParams() is always nil, because it fails to load the old format using new code, it’s supposed to be migrated by the x/upgrade module first, but unfortunately, the migration happens in BeginBlocker handler, which runs after the ctx is initialized.
When we try to solve this, we find the x/upgrade module can’t modify the context to make the consensus parameters visible for the other modules, the context is passed by value, and sdk team want to keep it that way, that’s good for isolations between modules.
Alternatives
The first alternative solution introduced aMigrateModuleManager, which only includes the x/upgrade module right now, and baseapp will run their BeginBlockers before the other modules, and reload context’s consensus parameters in between.
Decision
Suggested this new lifecycle method.PreBlocker
There are two semantics around the new lifecycle method:
- It runs before the
BeginBlockerof all modules - It can modify consensus parameters in storage, and signal the caller through the return value.
ConsensusParamsChanged=true, the caller must refresh the consensus parameter in the finalize context: