L1 至 L2 的消息传递
概述
L1 至 L2 的消息传递由 L1 触发的 L2 交易实现。(资产转移基于此机制)
Rooch 具备多链资产结算的能力,对于每一条 L1 来说,其 L1 to L2 流程一致(注:合约名及其参数受不同智能合约语言影响在 L1 上略有不同),都是由 Rooch 上的轻节点验证来自 L1 的事件后执行 L2 交易:
L1
L1 需要对 L2 的调用生成相关事件,事件中包含了 L2 调用所需的所有信息以及发生在 L1 上的过程信息,这些信息将会被 rooch_node 解析并中继给 L2。
-
用户通过调用
l1_stub中的call_remote函数发起 L1 to L2 请求,所需参数包括:action: 编码后的 Rooch MoveActionmin_gas_amount: L2 上允许使用的最小 gas 数量,即对调用action的估计值。 考虑到 L2 需要在调用action之前的处理开销,实际开销肯定会超过这个值。详见 Gas Fees。
l1_stub提供了较为友好的接口,调用者只需关心 L2 调用信息而无需关注信息封装和传递。 -
l1_stub将调用rooch_transport的send_l1_to_l2函数完成 L1 上的事件记录和 gas 燃烧,参数包括:msg_sequencemsg_senderactionmin_gas_amount
-
send_l1_to_l2在完成检查后,发出L1ToL2Event事件,其中包括:msg_sequencemsg_senderactionmin_gas_amountfrom:send_l1_to_l2的发起者。在这里是l1_stub。gas_amount: 基于min_gas_amount以及根据action尺寸估算得到的 L2 上的基础 gas 开销。也是 L1 上燃烧的 gas 数量主要依据。L1ToL2Event_version: event 版本号
L2
rooch_node监听L1ToL2Event事件,解析其中的参数,生成 L1 事件包含证明(证明该事件在 L1 上发生),最终封装为 L2 tx- 将 L2 tx 传递给 executor 验证 L1 事件包含证明,executor 将使用 L1 对应的轻节点合约验证事件的包含证明。
- 验证成功后执行
action
Gas Fees
Gas Fee 分为两个部分:
- L1 合约调用开销
- L2 合约调用开销(由 L1 燃烧实现)
其中 L1 合约开销占据整体开销的绝大部分,L2 合约开销相对较小且有一定的免费额度(对于绝大多数资产转移场景而言,L2 免费额度是绰绰有余的)。 对于超过免费额度的部分,将以一定比例在 L1 上燃烧:
这就像是一个 Gas 变速装置,对于不同的链来说,我们只要替换 L1 的变速齿轮(调整 L2:L1 gas 比例)自动实现 L1 上的燃烧。这样无论是哪一条 L1, 使用者仅需要关注 L2 上目标函数的开销即可,无需关注复杂的 gas 定价。
燃烧将以在 L1 中以 while loop 形式实现,伪代码如下:
i = 0
while (i < burn_amount) {
i++
}安全性
Rooch 的 L1 to L2 消息机制保障的是 L1 上的合约调用能够被正确的中继到 L2 上,L2 上的合约自行负责对 L1 的调用者的检查,这要求
将相关的 sender 等信息作为参数封装进 l1_stub.call_remote 中的 action。