ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Optimism Cannon mipsevm 深度解析:MIPS64 状态机从 ELF 加载到链上 Witness 验证的完整工作流

Optimism Cannon mipsevm 深度解析:MIPS64 状态机从 ELF 加载到链上 Witness 验证的完整工作流 Optimism Cannon mipsevm 深度解析MIPS64 状态机从 ELF 加载到链上 Witness 验证的完整工作流【免费下载链接】optimismOptimism is Ethereum, scaled.项目地址: https://gitcode.com/GitHub_Trending/op/optimismmipsevm是 Optimism 仓库中 Cannon 故障证明Fault Proof系统里的 MIPS64 软件模拟器负责把编译为 MIPS 的 Go 程序逐步执行并生成可供 EVM 链上复验的 witness 数据。读完本文你将掌握 mipsevm 的核心接口FPVMState、FPVM、PreimageOracle、文档给出的七步运行工作流对应的真实源码入口LoadELF、PatchStack、Step(proof)以及其支持的全部约百条 MIPS 指令的分类语义并理解 witness 数据如何交给 MIPS64.sol 在链上完成单步复现。一、mipsevm 在 Cannon 中的角色Cannon 的验证模型是本地执行 链上逐步复现off-chain 的 Go 程序被编译为 MIPS64 可执行文件op-geth 的 MIPS 构建mipsevm 在内存中模拟该 CPU每执行一条指令就产出 witnesson-chain 的 MIPS64.sol 用 witness 中携带的内存证明与寄存器快照独立复算同一条指令从而以密码学方式验证整条执行轨迹。mipsevm 包cannon/mipsevm即本地模拟器一侧的全部核心代码其包结构如下子目录/文件职责cannon/mipsevm/iface.go定义FPVMState、FPVM、Metadata、FeatureToggles等核心接口cannon/mipsevm/oracle.go定义PreimageOracle接口cannon/mipsevm/state.goCpuScalars结构与 VM 状态码cannon/mipsevm/witness.goStepWitnesswitness 数据结构cannon/mipsevm/program/LoadELF加载与PatchStack等运行时补丁cannon/mipsevm/multithreaded/支持 Go 抢占式调度的多线程 MIPS 实现与NewInstrumentedStatecannon/mipsevm/exec/指令解释执行、系统调用与 preimage 访问逻辑cannon/mipsevm/memory/分页 哈希树的可证明内存cannon/mipsevm/tests/模拟器与链上 EVM 实现的一致性差分测试difftester核心接口FPVMState 与 FPVMiface.go 中的FPVMState是可被序列化、可被单步推进的 VM 状态抽象关键查询方法包括GetMemory()返回可证明内存*memory.Memorywitness 中的内存证明即来自它GetHeap()/GetPC()/GetStep()分别给出堆顶、当前程序计数器与全局步进计数GetCpu()返回CpuScalarsPC、NextPC、LO、HI见 state.goGetPreimageKey()/GetPreimageOffset()当前正在访问的 preimage 键与偏移这是 syscall 与预映像服务对接的桥梁GetLastHint()记录最近一条 preimage hint带 4 字节长度前缀用于从任意状态恢复时重新发出上一条 hint保证 preimage 请求可被服务EncodeWitness()把当前状态编码为 witness 字节并计算状态哈希CreateVM(...)基于该状态构造一个可Step的FPVM实例。FPVM接口则定义运行期行为Step(includeProof bool) (*StepWitness, error)执行单条指令并返回该步 witness另有CheckInfiniteLoop()、LastPreimage()、Traceback()、GetDebugInfo()、InitDebug()等调试与诊断能力。PreimageOracle是整个VM 与外部数据交互的唯一通道定义极为简洁oracle.gotype PreimageOracle interface { Hint(v []byte) GetPreimage(k [32]byte) []byte }VM 内被模拟的 Go 程序无法真正发起网络/文件操作它通过 hint preimage 系统调用把请求交给宿主进程宿主再据此填充GetPreimage的返回值。二、七步运行工作流文档标准用法 源码级说明文档给出的标准用法是七步流程。下面逐条对照仓库中的实际实现补充可直接落地的细节。1. 用LoadELF把程序装入状态入口是 program/load.go 中的泛型函数LoadELFT mipsevm.FPVMState。它的工作方式是以f.EntryELF 入口地址和HEAP_START初始化状态遍历 ELF 的 program segment跳过PT_MIPS_ABIFLAGS对PT_LOAD段若Filesz MemszBSS 区域自动补零填充若Filesz Memsz则报错校验内存范围MIPS64 使用 48 位虚拟地址空间MIPS32 为 32 位段末地址越界、或与堆区间HEAP_START重叠时直接报错防止程序段覆盖堆。测试代码中常用 testutil/elf.go 的LoadELFProgram封装完成打开文件 LoadELF 返回元数据的完整链路可作为本地试验的参考。2. 按需补丁PatchGo 程序被装入裸内存后并非开箱即用需要构造出符合 Go 运行时期望的进程环境。典型补丁是 program/patch.go 中的PatchStack它完成将栈指针SP设到arch.HighMemoryStart并在其下方分配 5 页1 页栈内容 4 页 16KB 栈增长空间在栈顶写入 argc/argv/envp/auxv 布局argc 1、argv[0] op-program、envp[0] GODEBUGmemprofilerate0禁用内存 profiler保证执行确定性、auxv中声明_AT_PAGESZ 4096与AT_RANDOM随机数为固定值4;byfairdiceroll同样是确定性要求。对 Go 程序还涉及帧指针等运行时补丁PatchGo类逻辑确保解释器可以正确解析调用栈。文档中Patch the program if necessary即指这一步装载完 ELF 后必须补齐 Go 运行时依赖的初始化内存布局否则程序启动即 panic。3. 实现PreimageOracle接口如上文 oracle.go 所示实现方需提供Hint接收 VM 发来的提示字节与GetPreimage按 32 字节键返回 preimage 内容。Hint通常把 VM 内的请求转发给本地 HTTP 服务op-program 的 preimage oracle 端点GetPreimage则等待服务端推送的对应数据。测试场景下testutil/oracle.go 提供了内存版的模拟实现。4. 用NewInstrumentedState装配被测量的状态iface.go 的CreateVM与 multithreaded/instrumented.go 的NewInstrumentedState把状态 preimage oracle stdOut/stdErr Metadata FeatureToggles组装成可运行的 instrumented VM。FeatureTogglesiface.go 的注释用于在同一套代码里区分多个历史状态版本的特性差异实现多版本共存Metadata提供符号表LookupSymbol用于 trace 时把地址翻译成函数名。5.Step(proof)单步推进并产出 witnessFPVM.Step(includeProof bool)执行单条指令返回*StepWitnesswitness.gotype StepWitness struct { State []byte // 编码后的状态快照 StateHash common.Hash // 状态哈希 ProofData []byte // 内存证明等复验数据 PreimageKey [32]byte // 本步未访问 preimage 时为零值 PreimageValue []byte // 含 8 字节长度前缀 PreimageOffset arch.Word }文档特别指出proof true时才生成完整的复验数据proof false时步进更快——因此批量跑 trace 时可以先关 proof只在需要提交/复验的步打开。HasPreimage()通过PreimageKey是否为零值判断本步是否发生了 preimage 访问。6. 用退出状态判定执行结果模拟结束后程序状态由VmStatus(exited bool, exitCode uint8)state.go映射为四种状态码未退出为VMStatusUnfinished退出码 0 为VMStatusValid有效执行退出码 1 为VMStatusInvalid无效执行证明程序明确判否其余退出码为VMStatusPanic。这四个值与链上VMStatuses类型一致是故障证明争议判定的最终输出。7. 在链上用 MIPS64.sol PreimageOracle.sol 复现最后一步把 witness 交给 EVMMIPS64.solpackages/contracts-bedrock/src/cannon/MIPS64.sol的注释说明该合约模拟单条 MIPS 指令支持 MIPS64 指令与多任务其ThreadState结构约 298 字节状态编码与StepWitness的字段一一对应内存哈希树由MIPS64Memory.sol等库校验PreimageOracle.sol 则负责链上 preimage 的提交与查询PreimageKeyLib.sol提供键构造规则。这样本地每步Step(true)的 witness 都能在链上以可验证成本被独立复算构成完整的本地-链上闭环。三、支持的 MIPS 指令集完整清单mipsevm 解释器支持约百条 MIPS 指令覆盖算术、逻辑、移位、分支跳转、数据搬运、比较、序列化与系统调用八大类。以下按类别整理完整清单描述与文档一致算术类Arithmetic指令说明add加法addi立即数加法带符号扩展addiu无符号立即数加法addu无符号加法dadd双字加法daddi双字立即数加法daddiu双字无符号立即数加法daddu双字无符号加法ddiv/ddivu双字除法有符号 / 无符号div/divu除法有符号 / 无符号dmult/dmultu双字乘法有符号 / 无符号mul乘法仅取 word 结果mult/multu乘法有符号 / 无符号结果入 LO/HIdsub/dsubu双字减法有符号 / 无符号sub/subu减法有符号 / 无符号逻辑与移位类Logical指令说明and/andi按位与 / 立即数按位与nor/or/ori按位或非 / 按位或 / 立即数按位或xor/xori按位异或 / 立即数按位异或clo/clz统计前导一 / 前导零个数dclo/dclz双字前导一 / 前导零统计sll/sllv逻辑左移 / 变数逻辑左移sra/srav算术右移 / 变数算术右移srl/srlv逻辑右移 / 变数逻辑右移dsll/dsll32/dsllv双字逻辑左移 / 左移 32 位 / 变数左移dsra/dsra32/dsrav双字算术右移 / 右移 32 位 / 变数右移dsrl/dsrl32/dsrlv双字逻辑右移 / 右移 32 位 / 变数右移分支与跳转类类别指令说明条件分支beq/bne相等跳转 / 不等跳转条件分支bgez/bgtz/blez/bltz大于等于 0 / 大于 0 / 小于等于 0 / 小于 0 时跳转条件分支bgezal/bltzal条件跳转并回写返回地址到 link 寄存器无条件跳转j/jal/jalr/jr跳转 / 跳转并链接 / 寄存器跳转并链接 / 寄存器跳转数据搬运类Data Transfer含访存与寄存器移动指令说明lb/lbu加载字节有符号 / 无符号lh/lhu加载半字有符号 / 无符号lw/lwu加载字有符号 / 无符号lwl/lwr加载字的左 / 右对齐部分ld/ldl/ldr加载双字及左 / 右对齐变体lui加载立即数高 16 位ll/sc锁加载load-linked/ 条件存储store-conditionalmfhi/mflo从 HI / LO 乘除结果寄存器取值mthi/mtlo写入 HI / LO 乘除结果寄存器movn/movz非零时移动 / 为零时移动sb/sh存储字节 / 半字sw/swl/swr存储字及左 / 右对齐变体sd/sdl/sdr存储双字及左 / 右对齐变体比较类Comparison指令说明slt小于则置 1有符号slti/sltiu立即数小于则置 1有符号 / 无符号sltu小于则置 1无符号序列化与系统调用指令说明sync同步共享内存syscall系统调用——VM 与宿主preimage oracle、I/O交互的唯一入口解释实现见 exec/mips_syscalls.go其中ll/sc成对出现支撑多核 Go 运行时的锁实现syscall则是 op-program 与 preimage 服务通信的底层机制witness 中的PreimageKey/Value/Offset字段正是在该路径上产生。四、一致性保障模拟器与链上合约的差分测试本地 witness 可被链上复算这一核心假设并非口头保证而是由 cannon/mipsevm/tests/ 中的 difftester 持续验证difftester.go驱动随机指令序列与内存操作evm_common_test.go、evm_common64_test.go、evm_multithreaded_test.go、evm_multithreaded64_test.go等用例把 mipsevm 每步执行结果与 Solidity 侧MIPS64.sol的 EVM 实现逐步比对fuzz_evm_*.go还以模糊测试放大覆盖率。若你修改了 exec/mips_instructions.go 等解释器逻辑这一层测试就是回归验证的第一道关口。五、小结与延伸阅读mipsevm 以一套极小的接口面FPVMStateFPVMPreimageOracleStepWitness承载了加载 ELF → 补丁运行时 → 实现 preimage 服务 → 单步生成 witness → 链上复验的完整故障证明数据通路。建议按以下路径继续深入接口与状态模型cannon/mipsevm/iface.go、cannon/mipsevm/state.go装载与补丁cannon/mipsevm/program/load.go、cannon/mipsevm/program/patch.go多线程 instrumented 实现cannon/mipsevm/multithreaded/instrumented.go指令解释与系统调用cannon/mipsevm/exec/mips_instructions.go、cannon/mipsevm/exec/mips_syscalls.go链上复验合约packages/contracts-bedrock/src/cannon/MIPS64.sol、packages/contracts-bedrock/src/cannon/PreimageOracle.sol 及其测试 packages/contracts-bedrock/test/cannon/MIPS64.t.sol版本演进cannon/mipsevm/versions/ 中保存了各历史状态版本快照versions/states/*.bin.gz与检测逻辑供多版本共存场景使用【免费下载链接】optimismOptimism is Ethereum, scaled.项目地址: https://gitcode.com/GitHub_Trending/op/optimism创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表