该文档提出了在 Vanilla Based Rollups 中实现预确认机制的设计方案,旨在提升用户体验。提出了两种新的交易类型:包含预确认和执行预确认,并详细描述了其结构、定价以及预确认的提交与保证流程。同时,文档还讨论了预确认的激励机制和同步处理的问题,并区分了Rollup 的必要支持与设计决策。
中心化排序器在用户体验方面的一个主要优势是能够快速地向发送者预确认交易是否会被包含和/或执行。对于基于原生的排序来说,努力达到甚至超越预期的用户体验,这是一个自然而重要的要求。
本文档概述了在基于原生的 Rollup 中支持预确认的设计和机制。它引入了两种新的交易类型,以支持两种预确认类型:
为了方便预测费用,这两种交易类型都将有自己可预测的定价——作为 EIP 基础费用之上的特定预确认溢价百分比。
为了实现与中心化排序相当的用户体验,这两种交易类型都包含一个 deadline
(截止时间)字段,使钱包能够在不涉及用户的情况下重试预确认请求。
为了激励排序器正确行为,该设计概述了基于签名的预确认承诺——对交易哈希和承诺交易应该出现的 L1 区块的签名。
预确认的主要目标与整体的基于原生的排序目标一致。预确认是 Rollup 用户体验的重要支柱,并且正成为用户期望的标准。该设计旨在通过以下方式保持和改进这一标准:
正如基于原生的排序设计中所建议的,系统需要支持两种类型的预确认。
第一种预确认是交易包含预确认。此预确认保证将交易包含在后续的 Rollup 插槽中。这对于简单的转账等场景非常有用。
第二种预确认是更强的执行状态预确认。它允许指定交易执行后 Rollup 状态的部分期望值。这对于更复杂的用例(如 DEX 交易和/或套利)非常有用。
为了支持这两种类型的预确认,该设计建议引入两种新的 EIP2718 交易类型,专门用于基于原生的排序。
这两种交易类型充当预确认请求,并要求排序器响应预确认承诺或拒绝。这两种交易将使排序器和钱包能够区分请求及其预期属性。拥有两个单独的交易类型提供了几个明显的优势。
首先,两种交易类型将使这两种类型的预确认能够为其用例拥有单独定制的字段。其次,两种交易类型将使交易定价机制能够独立工作,并为每种类型找到正确的定价。最后,将交易类型分开允许 Rollup 选择支持其中一种或两种。
两种交易类型都必须包含一个字段 - deadline
(截止时间)。截止时间指示可以兑现此预确认的最晚 L1 插槽。
deadline
字段的目标是进一步优化用户体验,并使钱包和/或节点能够将复杂性隐藏在用户之外。在两种情况下,deadline
字段可以优化用户体验。
首先,排序器的 Rollup 插槽中迟到的预确认请求可能会被排序器拒绝,因为没有足够的时间来模拟和承诺交易。一种较差的用户体验(特别是考虑到硬件钱包)是重新要求用户签署交易。拥有 deadline
字段允许钱包重复使用相同的已签名交易,并将其发送给下一个排序器进行预确认。
其次,反悔的预确认会带来较差的用户体验。拥有 deadline
字段,使检测到预确认反悔的钱包能够将预确认交易重新提交给下一个排序器。
在这两种情况下,deadline
字段都使钱包软件能够隐藏重新提交的复杂性,而无需用户采取进一步的操作。在排序器端,deadline
引入了一个简单的检查,即在提交之前是否已超过 deadline
。
两种交易类型都将有单独的交易定价。定价机制将类似于 EIP1559。这种类型的定价使钱包能够轻松地发现价格,并保持与中心化排序相当的用户体验。
与 2 型或旧式 TX 相比,预确认交易本质上是一种价格更高的服务。首先,它们需要额外的处理才能处理。其次,由于区块构建限制,它们对排序器具有机会成本。
为了解决这个问题,每种新的交易类型都将以 2 型基础费用之上的百分比 premium
(溢价)定价。这样,所有交易的基础费用将不断被发现,并由协议的总使用量动态调整,以便提供稳定、可预测的交易费用。
每种交易的 premium
参数必须嵌入在协议中,并且是基础费用之上的百分比增加。
设 inclusion_preconfirmation_fee_premium
和 execution_preconfirmation_fee_premium
为目标预确认交易溢价。
交易必须为这两种交易支付的各自的 base_fee_per_gas
可以计算为 *_preconfirmation_base_fee_per_gas = base_fee_per_gas * (1 + *_preconfirmation_fee_premium)
。
与 EIP1559 类似,如果区块使用的 gas 超过区块目标,则所有类型的交易的基础费用都会上涨,反之亦然。
包含预确认交易遵循与以太坊 EIP1559 2 型交易相同的结构,但具有以下附加字段:
deadline
- int
,指示此预确认请求可以有效提交和包含在其中的最新 L1 区块。由于与 2 型交易相比,包含预确认的唯一区别字段是 deadline
字段,因此支持包含预确认交易所需的主要更改在 DApp 和钱包中。
在 DApp 方面,需要支持新的交易类型,建议使用截止时间字段。在钱包方面,显示和签署交易的过程必须包括新字段。
执行预确认交易遵循与以太坊 EIP1559 2 型交易相同的结构。
在 2 型字段之上添加以下字段:
deadline
- uint256
,指示此预确认请求可以有效提交和包含在其中的最新 L1 区块。storage_list
- 将 address
(地址)映射到存储槽 bytes32
及其预期值的元组 (bytes32, bytes32)
列表的对象列表。code_list
- 账户地址及其预期代码哈希的元组 (address, bytes32)
列表balance_list
- 账户地址及其预期余额的元组 (address, uint)
列表如果不受限制,所有三个约束列表都会大大扩展交易大小。交易大小的极大扩展是不 desirable 的,因为它会导致节点增加带宽和处理要求。
为了解决这个问题,每个列表中的项目数必须受到协议的限制。具体的限制由 Rollup 协议本身决定。
storage_list
示例:
[
[
"0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae", // 账户地址
[
[// 元组 (槽, 值)
"0x0000000000000000000000000000000000000000000000000000000000000003",
"0x000000000000000000000000000000000000000000000000000000000000000a"
],
[
"0x00000000000000000000000000000000000000000000000000000000000000e7",
"0x000000000000000000000000000000000000000000000000000000000000000b"
]
]
],
[
"0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
[
[
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x000000000000000000000000000000000000000000000000000000000000000c"
],
[
"0x00000000000000000000000000000000000000000000000000000000000001e9",
"0x000000000000000000000000000000000000000000000000000000000000000d"
]
]
]
]
code_list
示例:
[
[
"0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae", // 账户地址
"0x0000000000000000000000000000000000000000000000000000000000000be9" //代码哈希
],
[
"0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
"0x0000000000000000000000000000000000000000000000000000000000000cd8"
]
]
balance_list
示例:
[
[
"0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
"0x0000000000000000000000000000000000000000000000000000000000000abc"
],
[
"0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
"0x0000000000000000000000000000000000000000000000000000000000000def"
]
]
组合执行预确认交易的过程最终是用面对用户的层——DApp 和钱包开发人员的责任。两种类型的用户角色可以定义为执行预确认的典型用户 - 常规 DApp 用户(不复杂的 DApp 用户希望约束最终结果 - 例如交易的结果)和复杂的用户(例如套利机器人)。
对于常规 DApp 用户,用户的意图最终只能在 DApp 的上下文中才能很好地理解。在其上下文中,只能通过 DApp 应用程序本身来正确约束所需的执行结果。
对于复杂的用户,意图是复杂的,并且可以接受假设他们可以负责正确约束他们期望的执行结果。
预确认交易充当用户向 L2 排序器发出的预确认请求。此请求需要通过承诺或拒绝请求来响应。
预确认将继续重用将交易提交到 RPC 的标准方式,即使用 eth_sendRawTransaction
方法。作为 RPC 调用的规范的一部分,它可以返回交易哈希或零哈希。
零哈希响应必须被视为预确认请求拒绝的指示。非零哈希响应必须被视为预确认请求接受的指示。
为了承诺预确认,接收到非零响应的用户应获得预确认承诺。这可以通过新引入的 RPC 方法 eth_getCommitment
来完成。
此方法的响应必须是 signed_commitment
- 表示已签名承诺的字节。
signed_commitment = sign(tx_hash, l1_blocknumber)
承诺的组成部分是:
tx_hash
- 预确认交易的交易哈希l1_blocknumber
- 应该包含包含预确认交易的排序交易的 L1 区块号。排序器可能会违背其承诺的一种方式是省略他们承诺包含的交易。这是一种应受惩罚的罪行,需要反悔检测机制。
虽然反悔检测和证明(例如 ZKP、乐观挑战、证明)的具体机制最终是 Rollup 的设计决策,但 signed_commitment
为此提供了坚实的基础。
一个理性的区块构建者有自然的动机推迟承诺,直到他们的垄断时段结束,以最大化他们的利润。这将有效地使预确认变慢,并损害 Rollup 的用户体验。
虽然这种行为很难检测和强制执行惩罚,但本文档建议 Rollup 采用可选的“稳健性激励”方法。这种方法可以看到额外的收入(例如作为 Rollup 收入的一部分)提供给始终提供高质量服务排序器。
为了使排序器承诺执行预确认,他们需要确保交易执行之前的状态允许指定的最终条件发生。在 Rollup 插槽期间,预状态条件可能会因其他交易而发生变化,更重要的是因其他执行预确认而发生变化。这意味着为了避免承诺相互冲突的预确认,排序器需要同步而不是异步地处理执行预确认交易。
虽然这种同步处理可能会引入瓶颈,但执行客户端 EVM 实现的最新发展提供了更高的处理速度,以至于同步处理这些交易不会影响排序器和系统的整体性能。
处理执行预确认至少在最初不会引入瓶颈。排序器在技术上能够以 ~200MGas (>1k TPS) 的速率处理执行预确认(不包括 L1 排序和证明)。这比基于 L2Beat 数据 的当前需求高约 40 倍。
eth_getCommitment
RPC 调用
- 原文链接: github.com/LimeChain/bas...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!