Optimism的Fault proof

1. 引言

fault proof(错误证明),又名欺诈证明,或,交互游戏,其包含3大要素:

  • 1)Fault Proof Program(客户端角色):已知对所有rollup inputs(L1数据)的承诺值,和,dispute争议,可statelessly无状态地验证该争议。
  • 2)Fault Proof VM(服务端角色):已知某stateless无状态程序及其输入,追踪任意指令步骤,并在L1证明。
  • 3)Fault Proof Interactive Dispute Game:将争议一分为二为一条指令,并使用VM解决base-case基本情况。

这3大要素可具有不同的实现,从而组合为不同的proof stacks,并为解决某争议贡献proof多样性。

程序及其单独指令的“无状态执行”是指通过使用Pre-image Oracle的authenticating输入来再现完全相同的计算。
在这里插入图片描述

2. Pre-image Oracle

Program(客户端)与 VM(服务端)之间的唯一通讯方式为:

  • pre-image oracle

二者通讯使用简单的request-response wire协议。具体见后面的Pre-image communication。

Program使用pre-image oracle来查询用户可以使用的任意输入数据:

  • 用于bootstrap该program的初始输入。具体见后面的Bootstrapping章节。
  • 还不是程序代码的外部数据。具体见Pre-image hinting routes。

pre-images以bytes32 type-prefixed key来表示:

  • 第一个字节标识request类型。
  • 剩下的31个字节标识该pre-image key。

其中requestleix you :

  • Type 0:Zero key。0前缀是非法的。
  • Type 1:Local key。用于program bootstrapping,以通过索引或名称来标识初始输入参数。
  • Type 2:Global keccak256 key。用作global pre-image store contract,其是完全上下文独立和无许可的。
  • Type 3:Global generic key。保留。
  • Type 4-128:保留范围。
  • Type 129-255:应用使用。

3. Bootstrapping

初始输入是确定性的,但不一定是单一的或全局的:可能同时存在多个不同的争议,每个争议都有自己的争议主张和L1上下文。

为了bootstrap,该program使用pre-image key type 1 来从VM请求初始输入。

VM知道外部上下文,并基于它们的类型映射所请求的pre-image keys,即type 1的local lookup或 type 2的global lookup,且可选地支持其他key类型。

4. Hinting

客户端与服务端之间还有另一可选通讯方式:

  • pre-image hinting

hinting是可选的,为L1 VM实现中的no-op。

hint本身在链上的成本非常低:

  • hint可为单个write系统调用,这是即时的,因为作为hint的内存写入实际上不需要作为链上证明的一部分加载。

hinting允许程序在生成链外证明时,指示VM其所感兴趣的数据。

VM可选择在任何时候执行所请求的hint:

  • 本地执行(对于标准请求),
  • 或者通过将hint重定向到VM program附带的工具,以模块化的形式执行。

hints不必直接执行:它们可能首先被记录下来以显示program的意图,最新的hint可能会被缓冲以供延迟执行,或者在只读模式下完全删除(如onchain链上)。

当pre-image oracle服务某请求,并且不能从现有的pre-images集合(如,某local pre-image缓存)服务时,VM可以执行该hint以检索丢失的pre-image(s)。该program有责任为每个pre-image请求提供足够的hinting。某些hints可能需要重复:在处理丢失的pre-image时,VM只需要执行最后一个hint。

注意,hint可以产生多个preimage:如,具有交易列表的以太坊区块的hint可为:

  • 区块头
  • 每笔交易
  • 形成交易列表merkle-Pricia Trie的中间merkle节点

准备pre-image。

hinting是通过阻塞双向流上的request-acknowledgement协议实现的:

<request> := <length prefix> <hint bytes>

<response> := <ack>

<length prefix> := big-endian uint32  # length of <hint bytes>
<hint bytes> := byte sequence
<ack> := 1-byte zero value

ack通知客户端该hint已处理。服务端可能会异步回复hints和pre-image请求,因为这是分开的streams。为避免正在请求的pre-images暂未获取,客户端应在观察到该hint acknowledgement之后再请求该pre-image。

5. pre-image通信

pre-images通过通过阻塞双向流上的最小wire-protocol来通信。该协议以阻塞读写系统调用来实现:

<request> := <bytes32>  # the type-prefixed pre-image key

<response> := <length prefix> <pre-image bytes>

<length prefix> := big-endian uint64  # length of <pre-image bytes>, note: uint64

其中:

  • <length prefix>:可为任意高的值:若其所需的pre-image内容已读取,客户端可随时停止读取。

6. Fault proof program

Fault proof program:

  • 将,L2 rollup的状态变更,的claims,
  • 定义为,
  • 基于L1数据的纯函数。

op-program是指该program的实现,基于op-nodeop-geth来实现的。
该program主要包含:

  • Prologue:加载输入,已知最小bootstrapping,和可能的test-overrides
  • Main content:处理L2状态变更,即,根据L1输入派生该状态更改。
  • Epilogue:检查该状态更改来验证该claim。

6.1 Prologue

program以2个主要输入来bootstrap:

  • l1_head:将其看成是L1链tip的L1区块哈希,证实所有之前L1的真实性。
  • dispute:标识所验证的claim。

bootstrapping,通过对program host的特殊输入请求来启动。

此外,还有隐含输入,这些输入源于上述主要输入,但可出于测试目的被覆盖:

  • l2_head:l2区块哈希,它将被视为l2链tip的之前共识,用于验证所有先前的L2历史。
  • 链配置:链配置可嵌入到程序中,也可根据L1上已标识的dispute属性来确定。
    • l1_chain_config:L1链的链配置(也称为l1_genesis.json)
    • l2_chain_config:L2链的链配置(也称为l2_generation.json)
    • rollup_config:rollup节点使用的rollup配置(也称为rollup.json)

隐含输入依赖于L1-introspection,通过争议游戏接口在L1历史(直到指定的L1_head)中加载争议的属性。争议可能是claim本身,也可能是指向L1中特定先前claimed数据的指针,这取决于争议游戏接口。

在实际的核心状态转换函数执行之前,隐含的输入被加载到“prologue”中。在测试期间,可以使用加载重写的简化prologue。

注意:目前只支持test-prologue,因争议游戏接口正在积极更改。

6.2 Main content

为验证L2 state的某claim,program首先基于之前认可的L2历史,应用L1数据,重新生成L2 state。该流程称为L2派生过程,且匹配 rollup节点L2 execution engine内的处理流程。

不同于通过RPC来获取输入并对disk应用状态变更,输入通过pre-image oracle加载,并在内存中累加状态变化。

以2个数据源来派生该执行:

  • 1)对L1链只读的接口,由pre-image oracle来back:
    • l1_head:确定了可用的L1数据:后续没有可用的L1数据。
    • 链的实现从l1_head向下遍历header-chain,以按区块号查询服务。
    • l1_head:为L1 unsafe head、safe head和finalized head。
  • 2)L2 engine API接口:
    • 之前的L2链历史由pre-image oracle back,与L1链类似:
      • 初始的l2_head确定了可用的L2数据:后续没有可用的L2数据。
      • 链的实现从l2_head向下遍历header-chain,以按区块号查询服务。
      • l2_head:为L2 unsafe head、safe head和finalized head。
    • 新的L2链历史在内存中累加:
      • 若内存有限,尽管可使用pre-image oracle,按哈希来恢复数据,但program应首选在内存中保持最新创建的链数据,以最小化pre-image oracle访问。
      • L2 unsafe head、safe head和finalized head,可随着派生流程而变化。
      • L2 state包含了内存中的变化差量,可通过只读L2历史来访问任意未变化状态节点。

6.3 Epilogue

当main-content生成了disputed L2 state,epilogue会对该disputed claim下结论。

program会生成二进制输出来验证该claim,使用标准的single-byte Unix exit-code:

  • 0:成功,即该claim是正确的。
  • 非零值:表示失败,即该claim是不正确的:
    • 推荐使用1来标识不正确的claim
    • 其它非零值来表示runtime错误:如program代码中的bug所导致的panic或unexpected error。

7. Fault proof VM

fault proof VM实现:

  • 一个智能合约:来验证单个execution-trace step,如单个MIPS指令。
  • 一个CLI命令行:来为单个execution-trace step,生成proof。
  • 一个CLI命令行:来计算在第 N N N个step的VM state-root。

fault proof VM依赖于fault proof program,来基于hints提供任意丢失pre-images的接口。

VM仿真该program,为目标架构VM准备,并通过VM CLI生成state-root或指令proof。

Fault proof VM有:

  • Cannon:big-endian 32-bit MIPS proof,由OP Labs开发,当前已Public archive了。
  • Asterisc:little-endian 64-bit RISC-V proof,由protolambda开发,当前正在活跃开发中。

8. Fault proof interactive dispute game

互动纠纷游戏允许参与者通过链上挑战响应游戏解决纠纷,该游戏将不一致的区块 n → n + 1 n\rightarrow n+1 nn+1状态转换,然后基于为该状态转换建模的VM的executiont race,以证明单个VM trace步骤的基本情况为界。

游戏是多玩家的:不同的不结盟参与者可以在bond时参与。

响应时间是根据树分支中的剩余时间以及与claim的一致性来分配的。分配的响应时间受到争议游戏窗口的限制,当bond不足时,基于L1费用所需的任何额外时间都会发生变化。

注:计时、bond、一分为二争议游戏正在开发中。

9. Fault Proofs:MIPS.sol

MIPS.sol合约 是虚拟机 (VM) 的链上实现,包含 32 位、Big-Endian、MIPS III 指令集架构 (Instruction Set Architecture,ISA)。该合约与同一 ISA 的链下 MIPSEVM golang 实现相对应。链上和链下虚拟机实现共同构成了 Cannon——Optimism 的Fault Proof Virtual Machine (FPVM)。Cannon 是 FPVM 的一个单一实例,可以用作 Optimism(和 Base)乐观汇总 L2 区块链Dispute Game的一部分。Dispute Game自身是模块化的,允许在争议中使用任何 FPVM;然而,Cannon 是目前唯一实现的 FPVM,因此将在所有争议中使用。

OP团队于2023年9月发布了Fault Proof System alpha版本,详情见:

从该视频可知,MIPS.sol 合约与其他两个合约交互:【更多详情,参考:Fault Proofs: MIPS.sol

  • FaultDisputeGame.sol合约:
    • 是针对活动争议的故障争议博弈的部署实例
    • 在高层次上,故障争议博弈将有效地确定当前达成一致的 L2 状态,并遍历 L2 状态,直到找到第一个不一致的状态。如何确定Pre-images并将其填充到 PreimageOracle.sol 合约中超出了 MIPS.sol 合约参考文档的范围,因为该合约仅使用已由链下Cannon提供的Pre-images。
  • PreimageOracle.sol合约:
    • 存储预映像。
    • 原像包含来自 L1 和 L2 的数据,其中包括区块头、交易、收据、世界状态节点等信息。原像用作推导过程的输入,用于计算真实的 L2 状态,随后真实的 L2 状态用于解决争议博弈。

以仅有16条指令的trace为例,在Mock VM中模拟的相应Dispute Game示例为:
在这里插入图片描述

总体架构为:
在这里插入图片描述
根据2023年11月视频 Onchain Summit: Fault Proof Workshop by Protolambda,OP的L2角色总览为:
在这里插入图片描述
L2 state-transition为:
在这里插入图片描述
在这里插入图片描述
类似于L1客户端多样性,L2 Proof多样性,多样性可创造恢复能力:
在这里插入图片描述
为此,需采用Multi-Proof架构:
在这里插入图片描述
为支持proof多样性,实现更模块化、去中心化的生态,OP L2架构设计为:
在这里插入图片描述
在这里插入图片描述
Fault Proof Virtual Machine(FP-VM):

  • execution-trace proving

为“Bare-metal裸机”:无环境的简单执行:
在这里插入图片描述
每条指令都是简单的:
在这里插入图片描述
这些简单的指令会重复数十亿次:
在这里插入图片描述
无需证明所有,只需证明有分歧的单一指令即可。
交互式二分游戏为,对execution trace进行二分:
在这里插入图片描述
FP(Fault Proof)program为:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

10. Goshen Network的Optimistic rollup

Goshen Network协议使用RISC-V虚拟机来支持链上计算,且当有挑战时,其仅需识别RISC-V-Chain程序中的“one step”来执行prune fraud state。

区别于其它Optimistic rollup,Goshen Network 通过分层架构确保简单性和多功能性。底层是基于 RISC-V 的 L2 通用计算环境,以去信任的方式将 L1 计算迁移到链下。这样,L2 实现了 L1 的状态转换逻辑,确保与 L1 生态系统的完全兼容。进一步构建可靠的跨层消息通信机制,提供L1和L2之间的互操作性,用于构建token bridge等上层应用。对于链上挑战,交互式挑战协议不仅降低了链上成本,还提高了协议的鲁棒性。

参考资料

[1] Optimism的Fault proof
[2] 2023年3月 RISC-V for L2 state transition computation by Goshen
[3] Fault Proofs: MIPS.sol
[4] 2023年10月视频 Walkthrough: OP Stack Fault Proof System alpha release
[5] 2023年11月视频 Onchain Summit: Fault Proof Workshop by Protolambda

  • 12
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值