1. 引言
Succinct Labs团队CEO和CTO,以及Ellipsis Labs合伙人一起,于2023年6月22日发布博客 Shared Validity Sequencing,认为:
如今,主流的 rollup 都是 optimistic rollup,大多数 rollup-as-a service公司也在构建 optimistic rollup。
目前,optimistic rollup的设计存在两个主要问题:
- 1)问题一:rollup 依赖于集中式sequencer,这是软审查和 MEV 集中化寻租的载体。
- 2)问题二:目前还没有针对 optimistic rollup 之间的原子互操作性提供好的解决方案。由于 optimistic rollup 安全模型中的 7 天挑战期,optimistic rollup 无法在不等待欺诈证明窗口期通过的情况下验证另一个的状态。
- 因此,现有的跨 Rollup 桥和互操作性(任意消息传递)设计本质上是集中式和异步的。
有人提议使用共享的、去中心化的sequencer集来分散 rollup sequencer角色。但现有设计仅做交易排序,仅解决了问题一,而没有解决跨 rollup 原子互操作性。
本文提出了一种共享sequencer架构,可实现跨 rollup 原子互操作性。
- Shared Validity Sequencing:解锁了原生资产可为整个rollup生态服务的统一层。
2. 背景
本文场景可扩展为N个rollup的情况,此处为简化以2个rollup来描述—— 2个 optimistic rollup A 和 B。
当前,A 和 B 的两个sequencer各自独立地对两个rollup的交易进行排序。
目标是:
- 实现 A 和 B 之间的原子跨链操作。
- 具体来说:A中的某交易 a i a_i ai可被打包并成功执行(不revert),当且仅当B中的相应交易 b j b_j bj被打包且成功执行。
使用上述原语的典型示例是burn
和mint
两个rollup 之间的共享代币。将共享代币从 rollup A 桥接到 rollup B 的用户,要求rollup A 上的burn
交易成功,当且仅当rollup B 上的mint
交易成功。否则,资金可能会丢失(如,如果burn
成功但mint
失败)或被错误铸造(如,如果burn
由于用户资金不足而撤销,但mint
仍被打包)。
注意,若不执行交易 a i a_i ai,则无法知道该交易是否将执行成功,或其成功是否能满足跨域条件。如果没有在sequencer 层面进行一定程度的执行,则可能无法实现跨 rollup 原子性。
现有的共享sequencer设计不需要sequencer执行交易,因此它们仅通过条件包含实现弱形式的互操作性。非执行共享sequencer提供的原子交易包含不支持代币的原子桥接,因为代币铸造/销毁不变量无法以与底层防欺诈机制相同的安全性来执行。一般来说,原子条件交易执行比原子交易包含更具表现力。
3. Shared Validity Sequencing
Shared Validity Sequencing:
- 为一种共享sequencer设计,可实现 optimistic rollup 之间的原子跨链互操作性。
该设计有三个关键组件:
- 1)共享sequencer接受跨链操作的方法
- 2)共享sequencer的区块构建算法,用于处理这些跨链操作,同时尊重原子性和条件执行保证
- 3)在相关 rollup 之间共享欺诈证明,以强化这些跨链操作的保证
所设计的系统,可在两个 rollup 之间实现原子式的burn
和mint
操作:
- rollup A 上的
burn
操作成功,当且仅当,rollup B 上的相应mint
操作成功。
之后,可将该系统推广到任意跨 rollup 消息传递。
3.1 具有系统合约的跨链操作
当前,rollups 已包含系统合约,以实现特定的 rollup 功能,如 L1 和 L2 之间的双向消息传递以及其他特殊预编译。为此,建议再添加一个系统合约,允许其他智能合约触发跨链操作。
contract MintBurnSystemContract {
uint256 burnNonce = 0;
// Tree containing all `burn` actions
MerkleTree burnTree;
uint256 mintNonce = 0;
// Tree containing all `mint` actions
MerkleTree mintTree;
// Any contract/EOA can call this function on Chain A, which will trigger the
// sequencer calling `mint` on Chain B
function burn(address sender, address token, uint256 amount) external {
IERC20(token).transferFrom(sender, amount);
// Notice msgHash only gets inserted into burnTree if the `transferFrom`
// succeeds, otherwise the entire `burn` transaction will revert.
bytes32 msgHash = keccak256(abi.encode(sender, token, amount, burnNonce++));
burnTree.insert(msgHash);
emit SystemContractBurn(sender, token, amount, burnNonce);
}
// Only the sequencer can call this function
function mint(address sender, address token, uint256 amount) external onlySequencer {
IERC20(token).mint(sender, amount);
bytes32 msgHash = keccak256(abi.encode(sender, token, amount, mintNonce++));
// Notice msgHash only gets inserted into mintTree if the `mint` succeeds,
// otherwise the entire `mint` transaction will revert.
mintTree.insert(msgHash);
emit SystemContractMint(sender, token, amount, mintNonce);
}
}
该合约的副本存在于两个 rollup 中,用于原生代币的原子桥接。rollup A上 burnTree
包含所有burn
操作。rollup B上 mintTree
包含所有mint
操作。所需的是A 上的burnTree
不变量与 B 上的mintTree
不变量相同,或者说二者的 Merkle 根相等。
3.2 Shared Validity Sequencing的区块构建
Shared Validity Sequencing设计中:
- rollup A 和 B 共享一个sequencer。该共享sequencer负责将交易batch和声明的状态根发布到两个 rollup 的 L1。共享sequencer:
- 可以是中心化sequencer,如目前实际生产环境的 rollup sequencer,
- 也可以是去中心化sequencer网络中的leader。
唯一要求是:
- 共享sequencer必须在同一笔交易中将两个 rollup 的交易batch和声明状态根发布到 L1。
- 虽然不同的 rollup 可选择不同的交易排序和区块构建方法,但对区块builder的修改应该与大多数排序机制兼容。
- 共享sequencer接收交易并为 A 和 B 构建区块。对于 A 上的每笔交易,sequencer都会执行该交易并检查它是否与
MintBurnSystemContract
进行交互。如果交易成功执行并与burn
函数交互,则共享sequencer尝试在 B 上执行相应的mint
交易。- 如果
mint
交易成功,则共享sequencer打包A 上的burn
和 B 上的mint
; - 如果
mint
交易失败,则共享sequencer将排除这两笔交易。
- 如果
上述区块构建修改是对现有区块构建算法的简单扩展。
- 仅要求共享sequencer为两个 rollup 构建区块,sequencer执行交易并将条件触发的交易从一个 rollup 插入到另一个 rollup。
3.3 Shared Fraud Proofs 共享欺诈证明
optimism rollup 最重要的部分是:
- 可行、无需许可的欺诈证明;
- 这是 rollup 从底层 L1 继承安全性的方式。
截止2023年6月时,Optimism 没有欺诈证明,而 Arbitrum 已将欺诈证明列入白名单。
之前已描述了共享sequencer如何有条件地将交易包含在其同时排序的两条rollup链上。现在描述如何使用欺诈证明来强制执行条件包含。
欺诈证明是 L1 上的一种机制,用于确保 rollup sequencer诚实地处理交易并更新状态。有一种简单而优雅的方法可以扩展现有的欺诈证明机制,以确保sequencer诚实地处理跨链操作并正确地包含这些条件交易。
之前所提及的MintBurnSystemContract
中,在rollup A上维护了所有burn
交易的Merkle tree,在rollup B上维护了所有mint
交易的Merkle tree。只有当且仅当交易成功时,相应交易条目才会进入 Merkle 树。因此,为了确保rollup A 上的所有交易在 rollup B 上都有对应交易,只需检查 A 上burnTree
的 Merkle 根是否与B 上mintTree
的 Merkle 根匹配即可。
只需要对现有rollup A 和 B 的防欺诈机制进行微小的更改。如果 A 上burnTree
的根与B上mintTree
的根不匹配,则被视为排序不当,并且可以对负责的排序者进行惩罚。
强化跨链原子性保证的另一种机制是,对于接受rollup交易batch的 L1 智能合约,在batch提交时额外要求提供 Merkle 证明,即A 上burnTree
的根与 B 上mintTree
的根与声明的状态根相匹配。
4. Mint和Burn之外的通用消息传递
至此,仅用mint
和burn
函数概述了Shared Validity Sequencing。但其很容易推广到多个 rollup 之间的任意消息传递和条件交易执行。可以调用跨 rollup 操作,其中强制不变的是所有触发的合约调用都成功并被打包,或者都不成功。
contract GeneralSystemContract {
uint256 triggerNonce = 0;
MerkleTree triggerTree;
uint256 actionNonce = 0;
MerkleTree actionTree;
address crossChainSender = address(0);
// Any contract/EOA can call this function on Chain A, which will trigger the
// sequencer calling `action` on Chain B
function trigger(address addr, bytes calldata_, uint256 gasLimit) external {
bytes32 msgHash = keccak256(
abi.encode(msg.sender, addr, calldata_, gasLimit, triggerNonce++)
);
triggerTree.insert(msgHash);
emit SystemContractTrigger(msg.sender, addr, calldata_, gasLimit, triggerNonce);
}
// Only the sequencer can call this function
function action(
address sender,
address addr,
bytes calldata_,
uint256 gasLimit
) external onlySequencer {
crossChainSender = sender; // Set the crossChainSender
(bool status, bytes data) = addr.call{gas:gasLimit}(calldata_);
require(status == true); // Require call succeeded
bytes32 msgHash = keccak256(
abi.encode(sender, addr, calldata_, gasLimit, actionNonce++)
);
actionTree.insert(msgHash);
emit SystemContractAction(sender, addr, calldata_, gasLimit, actionNonce);
crossChainSender = address(0); // Reset the crossChainSender
}
// Allows triggered actions to get the original msg.sender on the source chain
function messageSender() external returns(address) {
require(crossChainSender != address(0));
return crossChainSender;
}
}
5. Shared Validity Sequencing数学
5.1 与单片链对比
通过Shared Validity Sequencing支持原子跨 rollup 交易的一组 rollup 在逻辑上可被认为是一条具有多个分片的大链。 与单体 rollup 相比,其具有以下优势:
- 每个单独rollup的本地手续费市场
- locks集的定价机制:跨 rollup 操作可有效获取两条链上的lock
- 开箱即用的分片:可选择信任某些分片并验证其他分片
- 支持不同的执行环境,如针对特定用例优化运行时的应用链
这些都是与当今的单体 Rollup 不同的因素。与支持并行执行和弱形式的本地费用市场的高性能基础层 Solana 相比,最大的区别在于:
- 对不同执行环境的原生支持以及与以太坊路线图的兼容性。
但是,相对于从第一天开始就支持并行性的基础层,多个 Rollup 组合在一起在Shared Validity Sequencing下形成单个分片状态机是一种粗糙且低效的实现。吞吐量、手续费和最终确定时间将始终受到以太坊的限制。
5.2 sequencer和节点要求
与共享sequencer设计(对交易进行排序但不执行交易)相比,Shared Validity Sequencing会给共享sequencer带来更多负载。共享sequencer需要执行所有交易,以便访问当前状态并确定它们是否应触发其他交易的执行。请注意,默认情况下,跨不同 rollup 的执行仍可分片。
Rollup A 的全节点operator也必须运行 Rollup B 的全节点:
- 因为 A 的有效性不仅取决于 A 的有效状态转换,还取决于跨 Rollup 状态(A + B)的有效性。
- 为了验证 A 的有效性,节点operator还必须验证跨 Rollup 状态(A + B)的有效性,这需要验证 B 的有效性。
5.3 主权
该模型将 rollup A 和 B 的有效性结合在一起,因为它们各自状态的有效性现在相互依赖。这是 rollup 为了实现可组合性而做出的主观决定。与部署在单片链上相比,它们的应用程序拥有更多的自主权,但与应用链相比则较少。
6. 跨ZK rollup的原子互操作
ZK Rollup 具有开箱即用的异步互操作性,因为可直接验证彼此的 ZK 证明。但原子互操作性仍有好处,包括更好的用户体验和同步可组合性。
虽然此Shared Validity Sequencing设计是为optimistic rollup构建的,但可对其进行轻微修改以与 ZK rollup配合使用。MintBurnSystemContract
和sequencer
区块构建算法保持不变。 共享欺诈证明替代为:
- 接受batch交易并验证rollup状态转换的 ZK 证明的 L1 智能合约,现在还必须验证rollup A 上
burnTree
的根是否与rollup B 上mintTree
的根相匹配。
在这个设计下,有了 ZK rollups,A 的全节点operator不需要运行 B 的全节点。为了验证交叉 rollup 不变量,可简单地验证 B 的状态转换证明,并使用 Merkle 证明来获取B 的MintBurnSystemContract
状态。
7. 结论
本文描述了Shared Validity Sequencing——一种共享sequencer设计:
- 可实现 Rollup 之间的原子互操作性。
在该设计中,sequencer除了负责对交易进行排序外,还负责执行交易,从而允许执行跨链不变量,同时增加sequencer和节点operator的负载。通过选择与其他 rollup 共享有效性,rollup 可获得原子互操作性及其相关优势(如统一的原生资产层)。该系统可推广到多个 Rollup,包括 ZK Rollup。
Shared Validity Sequencing及其权衡可能对某些rollup生态系统有意义。
参考资料
[1] Umbra Research团队2023年6月22日博客 Shared Validity Sequencing