本文深入探讨了Optimism Rollup的链下故障证明虚拟机(FPVM) Cannon,它是用Go语言编写的,与链上MIPS.sol协同工作,负责处理争议游戏中更多的步骤。文章详细介绍了Cannon的组成部分,包括ELF加载器、内存和状态管理、MIPSEVM以及见证证明生成,阐述了它们在故障证明过程中的作用,以及如何保证链上和链下VM执行结果的一致性。
故障证明深度解析系列是由 Coinbase 的区块链安全(BlockSec)团队和 OP Labs 合作推出,旨在提供关于故障证明所有主要组件的深入信息。通过分享这些信息,我们希望鼓励其他人更多地了解故障证明的架构和技术方面。 我们可以一起朝着 OP Stack L2 区块链的去中心化未来迈进。
在本博文中,我们将介绍链下 Cannon 故障证明虚拟机 (FPVM) 的实现。请注意,链上和链下 FPVM 实现共同构成了 Cannon。 但是,为了本博文的目的,我们将仅用 Cannon 指代链下实现。
在前一篇博文中,我们介绍了 MIPS.sol,即链上 FPVM。 Cannon 是 MIPS.sol 的链下对应物,用 Golang 编写。 但是,与 MIPS.sol 不同,链下 Cannon 实现负责争端游戏中更多的步骤。 此外,Cannon 是 OP Stack 中用于故障争端游戏的唯一 FPVM。
让我们再次回顾一下故障证明过程,以了解 Cannon 所在的环节。
在上图中,该图是从 Clabby 的 故障证明演练视频 中重新创建的,我们可以看到 Cannon 与 OP-Challenger 和 OP-Program 交互。 OP-Challenger 是处理发起挑战和与争端游戏交互的组件,OP-Program 处理从 L1 输入派生 L2 输出。 但是,该图简化了 OP-Challenger、Cannon 和 OP-Program 之间的交互。
在活跃的争端游戏过程中,二分游戏将从围绕 L2 输出根的枢轴转移到状态见证哈希。 Cannon 负责生成状态见证哈希,这是 FPVM 中 MIPS 指令计算结果的承诺。 只有在争端游戏到达该点时才会运行 Cannon。 二分游戏的这一部分称为执行跟踪。 在此之前,OP-Challenger 一直在咨询 OP-Node 以获取状态输出根,并且没有使用 OP-Program 或 Cannon。 但是,一旦到了为争端游戏运行 Cannon 的时候,已经编译好的 OP-Program 将被加载到 Cannon 中的 VM 中,然后开始运行 MIPS 指令。
在二分游戏的执行跟踪部分,Cannon 将运行许多 MIPS 指令,最初将向 OP-Challenger 提供状态见证哈希。 最终,将识别出单个 MIPS 指令作为活跃争端游戏中参与者之间分歧的根源。 现在,Cannon 将生成见证证明,其中包含在 MIPS.sol 上链运行 MIPS 指令所需的所有信息。 然后,MIPS 指令的最终后续状态将用于解决故障争端游戏。
Cannon 由多个 Golang 文件组成,这些文件共同具有比链上 MIPS.sol 更多的功能。 这是必要的,因为 Cannon 负责比 MIPS.sol 更多的争端游戏部分。 这些 Golang 文件可以按它们实现的 Cannon 的核心组件进行分组,其中包括:可执行和可链接格式(ELF)加载器、内存和状态管理、MIPSEVM 和见证证明生成。
OP-Program 是将被编译成 ELF 文件的代码,该文件反过来包含要在 Cannon 中运行的 MIPS 指令。 为了将 ELF 文件的内容放入 Cannon 中运行,需要将其加载到 MIPSEVM 中。 此过程涉及迭代 ELF 标头以确定需要加载到 32 位内存空间中的所有程序,定位程序计数器(PC)和 NextPC 的初始值,在内存中实例化堆栈、堆和数据段指针,并修补掉任何不兼容的函数。 修补掉不兼容的函数只是用返回到原始指针的返回指令和无操作(NOP)覆盖函数中的第一个指令。 修补加载到 MIPSEVM 中的二进制文件非常重要,因为 FPVM 无法执行许多系统调用,并且不支持诸如并发之类的功能。
Cannon 存储和维护 MIPSEVM 可用的整个 32 位内存地址空间。 对链下存储的内存大小没有限制,但是对于 MIPS.sol 而言,存储整个 32 位内存地址空间是不可行的。 因此,内存存储在 Cannon 中的二进制 Merkle 树数据结构中。 对于 MIPSEVM,此数据结构通过使用 GetMemory()、ReadMemoryRange() 和 SetMemory() 函数来抽象化。 当需要生成见证证明时,Cannon 将编码多达两个内存 Merkle 证明,供 MIPS.sol 在运行 MIPS 指令时使用。
Cannon 中包含 MIPSEVM,它实现了 32 位、大端序、MIPS III 指令集架构(ISA)。 与 MIPS.sol 不同,MIPSEVM 将运行许多 MIPS 指令,并且还负责跟踪内存访问,该内存访问将用于编码第二个内存证明。 但是,链下和链上 VM 实现都必须在给定相同指令、内存和寄存器状态的情况下产生完全相同的结果。 这对于确保来自 MIPSEVM 的预期后续状态与 MIPS.sol 生成的实际后续状态相同至关重要,实际后续状态将用于解决争端游戏。
一旦单个 MIPS 指令被确定为故障争端游戏中参与者之间分歧的根源,Cannon 将生成见证证明,以便可以在 MIPS.sol 中链上运行相同的指令。 编码在见证证明中的信息如下:VM 执行状态、要运行的指令地址的内存证明,以及仅在加载、存储或某些系统调用指令中才需要的附加内存证明。 此外,如果 MIPS 指令需要预映像,Cannon 还会将预映像密钥和偏移量传达给 OP-Challenger,以便可以将其链上发布到 PreimageOracle.sol。
我们的 Cannon 深度解析到此结束。 除了这篇博文之外,Coinbase 还创建了深入的文档,提供了有关构成 Cannon 的每个组件的更多详细信息。 请在 Fault Proof VM - Cannon | Optimism Docs 上查看,如果你对 Optimism 的官方 Cannon 技术规范感兴趣,可以在 Cannon Technical Specification 上查看。
- 原文链接: optimism.io/blog/fault-p...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!