提议者承诺的 BAL

本文为机器翻译
展示原文

感谢ToniLadislaus的讨论和反馈。

EIP-7928引入了区块级访问列表 (BAL),以改进 L1 上的并行执行。除了扩展之外,BAL 还为提议者承诺协议(尤其是执行预置)奠定了更简单的基础。BAL 不再依赖于多个 Merkle Patricia Tries 中的碎片化证明,而是提供了所有可与承诺绑定的交易后值的规范记录。

话虽如此,当前的 EIP-7928 规范并不直接适用于高效的EVM 级证明。本文旨在鼓励使用 BAL 进行预配置,重点介绍为使其易于证明而提出的规范变更,并概述Discord 中正在讨论的复杂性权衡。

动机

执行预置机制允许提议者(或委托人)在交易上链之前就向用户提供关于交易结果的早期承诺。这将预确认时间缩短至从提议者到用户只需一次“ping”,从而提供比共识协议更快的用户体验。用户无需等待区块确认,而是在收到可信的执行预置后即可自信地采取行动。

如今,可信承诺要求能够以无需信任的方式证明承诺何时被违背,以便对已绑定的预置合约强制执行链上罚没条件(例如,使用URC )。这些证明分散在多个 trie 中:用于包含/排序的交易 trie、用于执行成功的收据 trie、用于 nonce 或余额变化的账户 trie,以及用于存储的状态 trie。这种方法虽然可行,但存在碎片化问题,需要定制的证明逻辑,并且粒度有限。

  1. 碎片化:完整覆盖需要对每个修改状态进行多次尝试并提交值。

  2. 逻辑:每个承诺都会做出不同的承诺并影响不同的状态,需要自定义逻辑。

  3. 粒度:这些树只记录应用所有交易后的状态,这意味着中间状态更新(例如,第四次交易后 Alice 的余额)无法直接证明。

一些提议的设计针对 1) 和 3) 进行了改进,如果事后状态与用户预期不符,则撤销交易,例如“以至少 0.98 ETH 的价格出售 1000 USDC ” 。虽然实用,但这将负担转移到了合约开发者身上,他们必须手动编码这些条件。实际上,它类似于意图式编程,每个操作都带有定制的有效性条件。

通过提供交易级状态差异的规范记录,BAL 提供了一种更简单的构建提议者承诺协议的原语。执行预置可以表示为对BAL子集的承诺,并且可以根据规范BAL证明承诺的违反。这使得承诺的推理、执行和标准化更加简单,从而降低了协议设计者和用户的摩擦。因此,一个有效利用 BAL 的通用提议者承诺协议可以涵盖当今所有的预置用例。

今日 BAL

BAL是一个 RLP 编码的List[AccountChanges] ,其中AccountChanges对象记录了每笔交易中地址 nonce、余额、存储空间和/或代码的状态变化。通过迭代应用所有AccountChanges ,客户端可以确定性地并行重建每个受影响账户在整个The Block中的演变过程。

这足以解决我们执行预置所面临的挑战:

  1. 碎片化:仅需要BAL做出承诺,无需多次尝试

  2. 逻辑单个通用协议足以捕获当今所有的预配置用例,而无需意图式编程。

  3. 粒度 AccountChanges对象允许对每个交易状态差异做出承诺。

电流限制

显然,BAL 可以改进预配置协议;然而,挑战在于如何编码 BAL。根据当前的 EIP-7928 规范,BAL 采用 RLP 编码,并且The Block块头包含BAL哈希值。

这使得向 EVM 证明承诺被违反变得非常繁琐。用户需要将整个BAL作为调用数据 (calldata) 传递,将其哈希值与父区块哈希值进行验证,然后手动进行 RLP 解码以找到冲突值。目前,未压缩的BAL大小约为 100KB,在调用数据的限制范围内。鉴于承诺被违反的情况很少发生,因此这种做法并非不合理。

拟议的 EIP 变更(更难)

随着区块和 BAL 规模的扩大,将BAL作为调用数据传递的成本将更加昂贵。拟议的变更将使从 EVM 证明BAL成员身份变得更加容易。

由于执行客户端不太可能使用 SSZ 来编码BAL,因此另一种方法是将BAL编码为其自己的 MPT ,正如 Toni 所建议的那样。The Block块头将包含BAL根而不是哈希值,从而可以针对 EIP-2935 父哈希进行高效的 MPT 证明。

理想的预置文件编码应该包含两层 trie。外层 trie 将bal_index (又称交易索引)键映射到subTrieRoot值,其中每个bal_index代表一个唯一的交易索引。内层subTrie包含涵盖所有不同账户变更的唯一键:

  • RLP(["balance_change", address])

  • RLP(["storage_change", address, slot])

  • RLP(["nonce_change", address])

  • RLP([“code_change”, address])

其值包含 RLP 编码的交易后数据(即RLP([uint256]) )。

这将允许预协商者对交易后状态差异做出简洁的承诺,即对给定bal_index的子subTrieRoot进行签名。证明承诺被违背,就简化为证明该bal_index处的实际子subTrieRoot与签名的子树根 (subTrieRoot) 不同。子subTrie中单个账户的变更已从承诺协议中抽象出来。

这比现在的情况要简单得多,因为现在的情况是,预协商者需要对交易涉及的每个位置,在多次尝试中提交后状态差异。现在,每笔交易都会被压缩成一个单一的、整齐打包的subTrieRoot

然而,这种方法需要引入另一个 trie,这增加了 EIP 的复杂性。

提议的 EIP 变更(更简单)

假设The Block块头仍然提交到 RLP 编码的BAL哈希,稍微重构一下BAL布局就可以大大简化提交。本提案使用bal_index而不是账户来索引BAL ,这样BAL就被编码为 RLP 编码的List[TransactionDiff]

TransactionDiff将包含给定交易的所有 nonce、余额、存储和代码更改。这将把多个AccountChanges值中的承诺合并到一个TransactionDiff中,其功能类似于先前提案中的subTrieRoot

简洁地提交TransactionDiff将使连续区块构建更加现实,因为钱包和 PBS 管道的其余部分可以在应用执行预置后跟上最新状态。

BAL 的其他好处

  • 主流 Rollup 已经在尝试通过诸如ShredsFlashblocksFrags等承诺方案来加快确认速度,以改善用户体验。目前,这些方案依赖于第三方实现,并且承诺需要完全信任排序器。

    BAL 标准化了这种模式:使用 BAL 的 rollup 不再需要维护自己的自定义承诺方案,用户可以更轻松地从可信承诺中受益。实际上,BAL 体现了实践中已经开始发生的事情。

  • Vitalik 指出, BAL作为一种 MPT 方法,允许部分无状态节点仅验证他们关心的 BAL 部分的证明,即我的余额在The Block过程中是如何变化的。

  • 执行预置是有效载荷分块等思想的非协议前身。


来源
免责声明:以上内容仅为作者观点,不代表Followin的任何立场,不构成与Followin相关的任何投资建议。
喜欢
收藏
评论