Skip to main content

简介

本文档介绍激活 MIP-8 的运维方面:将节点的数据库从 slot 编码迁移到 page 编码,实时进行且无需从创世块重新同步。每个节点在双写两种编码,直到分叉将网络切换到 page 编码数据库,然后删除旧的 slot 编码数据库。

背景

MIP-8

MIP-8 重新组织了 EVM 状态 trie 使其页感知:存储 slot 被分组到 4 KB 的页中,而不是通过哈希独立分散在磁盘上。对于节点运营者来说,重要的是这改变了磁盘上的 trie 布局 — 这就是为什么需要迁移。

TrieDB 时间线

时间线是磁盘上 trie 状态的完整副本,通过将每个已提交的区块以给定编码写入其中构建而成。节点可以一次运行一个或两个时间线,每个都有自己的编码:
  • Slot 编码时间线使用当前的 trie 布局,每个存储 slot 的磁盘位置由哈希独立确定。这是 MIP-8 之前的格式。
  • Page 编码时间线使用 MIP-8 布局,slot 被打包到 128 个连续 slot 的页中。这是 MIP-8 之后的格式。
双模式是一种过渡状态,节点同时运行两种编码,作为磁盘上的两个时间线,并将每个已提交的区块写入两者。节点在激活 page 时间线和停用 slot 时间线之间的整个窗口期都处于双模式。 只是标记磁盘上的两个时间线。它们对执行或共识没有影响。在迁移过程中,主和次会交换,然后次被丢弃(参见迁移计划)。

状态机类型

节点的数据库工具(monad-mptmonad-cli)将 slot 和 page 编码称为状态机类型: 对于执行而言,重要的是哪个时间线是规范的还是影子的。规范时间线是其 state_root 用于规范链上区块的时间线;影子时间线在另一种编码上并行计算相同的区块,但其 state_root 不会在任何地方使用。 MIP-8 激活正是这两者之间的翻转:
  • 激活前,ethereum(slot)是规范的,monad(page)是影子
  • 在硬分叉时交换,monad(page)成为规范的,ethereum(slot)成为影子。
这就是为什么激活需要通过全网共识发生。

迁移计划

迁移分三个阶段进行:两个运营者操作和一个硬分叉。阶段 A 在每个节点上激活 page 时间线。阶段 B 是 MIP-8 硬分叉:在固定时间戳,规范链从 slot 时间线切换到 page 时间线。阶段 C 停用现在已成为遗留的 slot 时间线。
1

初始状态

DB 模式是 Legacy/Slot — 单个 slot 时间线。执行为 MIP-8 激活前状态。
2

阶段 A — Page 激活

运营者激活 page 次时间线,将 DB 模式变为 Dual。执行仍处于 MIP-8 激活前状态 — 在执行层面尚未发生变化。
3

阶段 B — 硬分叉

在分叉时间戳,MIP-8 在全网激活:page 时间线成为规范,slot 时间线成为其影子。节点保持在 Dual 模式。
4

阶段 C — Slot 停用(最终)

运营者将 page 时间线提升为主时间线,并停用现在成为次时间线的 slot 时间线。DB 模式翻转到 Page — 单个 page 时间线。节点现在已完全迁移。

运维

网络状态

获取当前状态

直接使用 monad-mpt 检查节点当前的磁盘状态:
Legacy/Slot — 未开始迁移:
Dual — 迁移进行中:
Page — 迁移完成:

Prometheus 指标

您可以通过 Prometheus 指标 monad_triedb_migration_phase 监控双 DB 迁移阶段:
  • 0:slot 编码(初始阶段的预期值)
  • 1:双模式(阶段 A 和阶段 B 的预期值)
  • 2:page 编码(阶段 C 的预期值)

Monad 状态

monad-status 脚本已更新以反映 TrieDB 模式,例如:

硬重置节点

硬重置流程本身没有改变 — 仍然遵循硬重置说明。下面的 DB 模式逻辑在同一个 restore-from-snapshot 步骤中自动发生;无需学习新的手动操作。 硬重置不会迁移您现有的数据库 — 它会清除数据库并从快照中重建。这意味着重置工具无法查看节点先前的磁盘状态来决定要重建什么(重置会在其他操作运行之前截断 DB),因此它会使用以下逻辑选择目标 DB 模式:
  • 如果 MIP-8 硬分叉已经通过,它会仅创建 page 时间线,并将快照导入其中。
  • 如果分叉尚未通过且它也可以创建 page 时间线,则结果为 Dual 模式,快照会导入两个时间线。
  • 如果分叉尚未通过且无法创建 page 时间线,则结果为 Legacy/Slot,快照仅导入 slot 时间线。
第一行是有意为之的:一旦 MIP-8 在网络上激活,就没有理由建立一个 slot 时间线,只是为了在下一阶段再次停用它 — 重置的节点直接进入 page-only 模式。

迁移任务

这适用于全节点和验证者。 迁移分三个阶段进行。阶段 A 和 C 是您在每个节点上执行的操作;阶段 B 是按计划发生的全网硬分叉。

阶段 A - Page 激活

请勿执行此程序。请等待 Monad 基金会的官方公告。验证者迁移将分批进行。 请确保您知道自己所在的批次,仅在您所在批次被宣布时才执行这些步骤。 部署日期和批次将通过官方渠道传达。
此过程从 0.15.2 开始支持。 此步骤使用从该版本开始的新 monad-mptmonad-cli 二进制文件。 停止 monad 服务:
快照转储将打开许多文件描述符(每个 shard 8 个)。如果您的系统打开文件限制为默认的 1024,转储将崩溃。 在运行之前提高限制:
准备快照文件夹并清理任何预先存在的次时间线:
激活次时间线:
预期输出:Activated secondary timeline; stamped state-machine kind to monad. 转储当前主时间线的快照:
预期输出:snapshot dump success=true。大约需要 5 分钟。 将快照加载到 page 次时间线中:
预期输出:load_to_secondary=true。大约需要 3 分钟。 清理快照:
验证 TrieDB 的状态:
该命令应打印类似于以下的输出:
验证两个时间线的 latest 值接近(此示例中为 47536183):
  • Primary: latest is 47536183
  • Secondary: latest is 47536183
几个区块的差异(最多约 10 个)是正常的。 启动 Monad 服务:
所有服务都应显示 Active:active (running)。确认节点重新加入并推进区块。 完成后,节点处于双写模式 — 下次启动时它将把每个新区块提交到两个时间线。 monad-execution 日志会打印 state_root primary=<slot root> secondary=<page root>,两个时间线都应出现在每个区块中。 在每个节点上运行此操作以将节点带入双模式。 每个节点必须在 MIP-8 硬分叉时间戳之前完成此阶段。

阶段 B - MIP-8 硬分叉

MIP-8 激活 阶段 B 是计划中的协议升级,而不是运营者的操作。其时间戳编码在全链范围的版本中,对每个节点都相同 — 只有当整个网络完成阶段 A 后才会发布。 在该时间戳,MIP-8 在执行层激活,规范的 state_root 从 slot 时间线翻转到 page 时间线,全网范围内,在同一个区块中:
  • 分叉之前 — slot 时间线是规范的;page 时间线跟随它。
  • 分叉时及之后 — page 时间线是规范的;slot 时间线跟随它。
磁盘上的主时间线是哪个与规范的是哪个无关。

阶段 C - Slot 停用

此阶段将停用 TrieDB 中的 slot 时间线。此操作只能在 MIP-8 激活硬分叉时间戳之后进行。
验证者迁移将分批进行。 请确保您知道自己所在的批次,仅在您所在批次被宣布时才执行这些步骤。 部署日期和批次将通过官方渠道传达。
状态归档节点状态归档节点不运行此阶段 — 请参见状态归档节点
另请注意,在 MIP-8 激活时间戳后进行硬重置的节点将仅恢复为 Page 时间线,无需停用任何时间线。 验证节点是否需要此阶段:
预期输出:
只有当主时间线是 ethereum(slot)且次时间线是 monad(page)时才继续。任何其他组合都意味着节点不应运行此阶段。 停止 monad 服务:
将 page 次时间线提升为主时间线:
停用现在已过时的 slot 时间线,回收其磁盘空间:
验证 TrieDB 的状态:
该命令应打印类似于以下的输出:
应仅保留一个状态机类型为 monad 的主时间线 — slot 时间线现在已消失。 启动 Monad 服务:
所有服务都应显示 Active:active (running)。确认节点重新加入并推进区块。现在它是一个单一的 page 时间线。 Monad 未来的版本将强制要求 slot 编码时间线被停用。

状态归档节点

状态归档节点(也称为历史全节点)在其本地 TrieDB 数据库中存储自创世以来的每个区块,而不是对旧状态进行剪枝。这使其在 MIP-8 迁移中成为特殊情况:
  • 阶段 A — 无差异。状态归档节点像其他任何节点一样升级并运行 Dual-DB 迁移。
  • 阶段 B — 在硬分叉时间戳时,在状态归档节点上重新运行阶段 A 程序。这会在主时间线当前位置重新播种辅助时间线 — 这是仅适用于状态归档节点的特殊情况。
  • 阶段 C状态归档节点不运行 slot 停用。 跳过此阶段:slot-encoded 时间线永久保持活动状态,以便节点保留其完整历史。

延伸阅读