延迟执行与免费DA - 执行层研究

文章探讨了以太坊中引入延迟执行(Delayed Execution)后可能出现的“免费DA(数据可用性)”问题,并分析了几种应对该问题的设计方案,包括乐观证明、预先验证和预收费等。文章还讨论了这些方案在用户体验、构建者复杂性、分叉选择复杂性、静态验证以及与FOCIL(强制包含列表)的兼容性等方面的权衡。

延迟执行与免费DA

作者:ToniFrancesco

感谢 Łukasz, Ansgar, DankradTerence 的反馈!

今天,免费 DA (Data Availability,数据可用性) 不是一个问题。每个交易发送者必须支付交易执行期间消耗的所有资源。放置在链上的数据,包括 calldata 中的数据或 EIP-2930 访问列表中列出的条目,都会产生 gas 成本,因此不可能在不支付费用的情况下发布数据。

以太坊目前通过要求验证者在证明该区块之前,完全执行和验证区块中的每个交易来保证每个区块的有效性。如果一个交易没有足够的余额来支付执行时所需的 gas,那么包含它的整个区块将变为无效。

然而,延迟执行 (EIP-7886) 的引入修改了这个过程。在延迟执行下:

  • 验证者在完全交易执行之前证明区块的有效性,而是依赖于预先检查。
  • 因此,即使最初看起来有能力支付其成本的交易在实际执行时缺乏足够的资金,区块也必须能够保持有效。

例如,假设有两个账户 A 和 B,每个账户都提交交易(分别为 a 和 b)。交易 'a' 在区块中排在 'b' 之前。如果交易 'a' 耗尽了账户 B 的余额,那么交易 'b' 尽管最初看起来有资金,但在执行时变得无法支付,从而使区块无效。

查看包含初始设计的帖子here

延迟执行设计空间

延迟执行的引入开启了几个设计的可能性。

不同的变体各有优点缺点,下面我们主要关注以下几类:

  • 发送者 UX
  • 构建者复杂度
  • 分叉选择复杂度
  • 静态验证
  • FOCIL 兼容性
  • 区块打包效率低

1. 乐观证明

乐观证明是指验证者在没有完全确定其有效性的情况下对区块进行投票的做法。经过最低限度的检查后,在 N Slot的证明者对在该Slot中提议的头区块进行投票。如果该区块在执行后被证明无效,则由 N{+}1 Slot中的下一个提议者将其从链中重组出去。

这种方法解决了延迟执行下的免费 DA,因为它确保了没有为他们写入的数据付费的交易不会被包含在链上。

棘手的部分在于分叉选择规则:N Slot的证明者合法地投出他们的选票,这些证明不仅代表对区块本身的支持,也代表对其整个祖先链的支持。因此,我们可能需要保留对无效头区块的证明,并允许来自这些区块的某些artifact保留在 Store 中。

优点

  • 发送者 UX 与今天保持不变。
  • 构建者复杂度 也保持不变。
  • 区块打包 与现在一样保持不变。

缺点

  • 分叉选择 必须处理无效区块及其证明。
  • 静态验证方面,我们实际上什么也得不到。交易仍然可以在执行期间失效。
  • FOCIL交互并不理想,因为 FOCIL 依赖于执行后的检查来确保区块遵守 IL。

有关乐观证明的更多详细信息,请参见 Francesco 的this post

2. 预先验证和预先收费

通过预先交易验证,我们在静态验证和执行之间引入了一个新步骤。

在静态验证区块及其交易之后,我们对所有交易执行以下有状态的检查直接向发送者收费

  • 验证 nonce 是否与发送者当前的帐户 nonce 匹配;当有来自同一发送者的多个交易时,确保 nonce 是连续的。
  • 确保帐户余额充足,检查区块中每个交易的发送者在相应索引处的余额。
  • 预先收取全部 gas 费用 (即,tx.gas * gas_price)

    • 这包括 blob 的 gas 和 ETH 中的交易值
  • 强制执行区块 block_gas_limit > block_gas_used
With `block_gas_used = sum(tx.gas for tx in block.transactions)`.

其中 block_gas_used = sum(tx.gas for tx in block.transactions)

  • 在所有交易发送者都预先收费后,开始执行第一个交易

由于严格的预付款验证,在同一区块中资助一个帐户并立即从中进行交易的模式可能会变得不可能。这可以通过引入区块 coinbase 的基本费用赞助来解决。

这意味着交易不仅经过静态验证,还针对当前状态进行检查 - 确保 nonce 匹配并且有足够的资金可用。费用会立即被预留。

与今天不同的是,交易在执行期间不再相互干扰。因此:

  • 帐户无法在同一区块中被资助然后执行交易
  • 交易无法耗尽另一个帐户的余额,从而使后续交易无效

这种方法有助于缓解免费 DA 问题,因为区块可以更早地被拒绝 - 执行开始之前。一旦预先验证完成并且费用被预留,验证者就可以自信地证明区块,因为他们知道其交易将按顺序成功执行。

这种设计在 FOCIL 兼容性方面存在权衡。

FOCIL 需要完全执行以验证 IL 合规性。仅仅访问区块及其交易是不够的 - 你无法仅从这些信息中确定是否遵守了 IL。相反,FOCIL 要求检查任何未包含在区块中但位于 IL 上的交易是否可以在给定的最终执行后状态下被包含。

在将包含执行前检查的 FOCIL 纳入考量时,一个重要的点是 “如何处理 gas_left 退款?”:

2.1 带有 gas_left 退款

与今天相比,允许发送者取回他们的 gas_left 并不会改变任何东西 - 交易的总成本仍然相同。

真正的问题出现在 FOCIL 中。一个交易可能看起来消耗了整个区块 gas 限制,但实际上并没有。例如,一个简单的 21,000 gas 的 ETH 转账可以提交一个等于完整区块限制 (例如 3600 万 gas) 的 gas 限制。在 FOCIL 下,区块构建者可以包含这个 “表面上很大的” 交易并忽略 IL。

问题在于,证明者 - 在执行区块之前 - 无法知道区块是否真的已满。如果区块被认为是满的,FOCIL 允许跳过 IL 上的交易。但是因为我们直到执行后才知道包含的交易实际会使用多少 gas,所以我们无法确定排除的 IL 交易是否可以放入区块中。

有两种可能的解决方案来解决这个问题。第一个是消除 gas 退款。第二个选择是使 FOCIL 无条件 - 也就是说,无论区块是否显得已满,都要强制执行包含列表。这完全消除了 gas 使用量的歧义,确保包含列表条目不能以区块空间不足为借口跳过。

2.2 带有上限的 gas_left 退款

我们可以简单地限制退款,而不是像 2.1 中那样将所有 gas_left 退还给发送者。例如,将 gas_left 退款限制为交易实际使用的 gas 的 50% 将使审查攻击 (在攻击中指定高 gas 限制但仅消耗少量 gas) 在经济上不可行。在一个 3600 万 gas 的区块中,选择跳过 IL 的审查构建者需要一个至少使用 2400 万 gas 的交易才能获得 50% 的最高退款,即 1200 万 gas。

这种方法的缺点是它使区块打包效率降低。与跟踪累积 gas 使用量的当前模型相比,我们最终可能会遇到每个交易都包含更大缓冲区的情况,从而有效地限制了吞吐量。为了缓解这个问题,可以使用较低的上限 - 例如,将退款限制为 gas_used 的 10%,这将显着减少缓冲区开销。

2.3 没有 gas_left 退款

消除 gas_left 退款将使伪造大量 gas 使用量在 经济上不可行,因为用户必须完全支付他们声明的 gas 限制,而不管实际消耗量如何。

这解决了对 FOCIL 的攻击,在这种攻击中,构建者包含看似很大的交易 - 声明高 gas 限制 - 但最终执行起来非常便宜,从而有效地伪造一个完整的区块以绕过包含列表。

显然,此选项是对 UX 的相当激进的更改。

2.4 带有 gas_left 退款和乐观的 gas_used

解决 FOCIL 不兼容性的另一种方法是将预先验证与乐观证明结合起来。在这种方法中,我们引入了一个新的标头字段 block_gas_used,构建者必须设置该字段。执行后,我们验证 block_gas_used 是否与实际使用的 gas 匹配。如果不匹配,则该区块被认为是无效的,必须重新组织出去。

这将有利于 FOCIL,因为验证者可以根据声明的 gas 使用量可靠地检查 IL 中是否可以将交易添加到区块中。

但是,与乐观证明相关的 分叉选择复杂性 仍然适用。具有不正确的 block_gas_used 的区块不会成为规范,但我们可能仍然希望允许对此类区块的证明影响分叉选择。

3. 预先向<实体>收费

在执行前向实体预先收费,并在之后发放退款是解决免费 DA 的有效方法。每当数据被写入链上而没有人为此付费时,协议可以简单地从预先收费方扣留退款。这确保了即使在没有人明确为数据付费的情况下,协议始终得到补偿。

3.1 Coinbase 承担包含成本

延迟执行的初始版本 预先向 COINBASE 帐户收取所有交易的包含成本。包含成本包括 calldata、blob 和 EIP-2930 访问列表的 gas。Coinbase 承担成本,并且在执行期间变为无效的交易将被跳过,其数据占用空间已经得到支付。

优点

  • 对用户来说没有任何改变,这很棒。
  • 没有围绕仍然具有权重的无效区块的分叉选择更改。
  • 没有因使用 tx.gas 而导致的区块打包效率低。相反,我们可以使用实际使用的 gas。

缺点

  • 区块构建变得更加复杂,因为我们要求 coinbase 帐户保持足够的 ETH 余额来承担包含成本。执行客户端只会构建基于 coinbase 余额有效的区块 - 在最坏的情况下为空区块。
  • FOCIL 不兼容
  • coinbase 密钥的管理成为一件事情 - 特别是当验证者需要单独的密钥来签名区块和提取奖励时。ERC-1271 合约可能是必要的,这会增加复杂性,尤其是在需要本地构建作为后备时。

与 FOCIL 的不兼容源于无法在执行前强制执行 IL。即使静态验证了一个区块,也没有预先向 coinbase 收取包含成本,并且允许跳过交易,但如果一个区块没有包含位于 IL 上的交易,即使区块中会有空间,那么该区块仍然会在 FOCIL 下变为无效。

3.2 预先验证带有退款 + Coinbase 承担 gas_claimed

为了解决 FOCIL 不兼容性,一种潜在的解决方案是转向预先验证交易,由 coinbase 承担区块中所有交易的全部 gas_used * base_fee。一个新的标头字段 gas_claimed 将允许区块构建者声明区块消耗了多少 gas。这使验证检查能够确定是否应该将来自 IL 的交易放入区块中。

在这种模型下,构建者预先支付所有声明的 gas 的基本费用。在执行期间,对于已执行的交易,会将全部交易费用 - 包括优先级费用 - 退还给构建者。如果 gas_claimed 值准确反映了实际的 gas 使用量,则构建者只需获得报销,再加上他们收到的优先级费用。但是,如果声明的 gas 超过了实际使用的 gas - 例如,为了避免包含 IL 交易 - 构建者最终会为此付费。

3.3 提议者惩罚

与 EL 上的通用请求类似,我们可以在执行payload中引入一个名为 proposer_penalty 的新字段,该字段表示来自所有跳过交易的总 gas 费用。当在 CL 上处理 payload 时,将从提议者处扣除此 proposer_penalty。请求需要被推迟一个区块,以便我们处理来自Slot n 在Slot n{+}1 中的惩罚。

这种方法的优点是它消除了对 EL 上资金帐户的需求。相反,它利用了 CL 上现有的 stake。

但是,缺点是它增加了提议者的财务风险。在最坏的情况下,他们不仅会错过奖励 - 他们实际上可能会赔钱。对于 MEV-Boost 用户而言,这意味着签署一个可能花费他们成本的区块,依赖于中继提前进行适当的验证。

优点

  • 不需要 EL 余额。提议者已经 stake ETH 并保持足够的余额来管理这些惩罚。

缺点

  • 引入了一个新的范例:验证者现在因为构建 “坏” 区块而在共识层受到惩罚。
  • 对于 MEV-Boost 用户而言,中继行为不端会增加财务风险。以前,恶意中继可能只会导致提议者错过Slot;现在,提议者可能会遭受直接的财务损失。

包含成本通常非常低 (假设非常高的 100 gwei 基本费用,则约为 0.55 ETH)。因此,平均而言,惩罚也应该很低。最坏的情况就是 gas_limit * base_fee

让提议者用 stake 来支付也可以用作让 coinbase 承担成本的后备方案。

4. Payload 空操作

与乐观证明相关的想法如下:

  1. 仅对区块执行静态验证。
  2. 确保没有跳过交易。
  3. 如果在执行期间发现任何交易无效,将整个 EL payload 视为 no-op。这意味着,将状态恢复到预状态并从那里继续。客户端仍然需要保留 payload 以验证同步期间恢复的正确性。

这种方法的关键好处是证明者仍然可以尽早证明区块。但是,与乐观证明不同,即使其 payload 无效,该区块仍将保持规范。这避免了处理对后来被重组的区块的诚实验证的复杂性。相反,证明者将证明一个其执行 payload 仅变为 no-op 的区块。

从提议者的角度来看,为了利用此机制进行免费 DA,你至少需要获得作为 MEV-Boost 支付的报酬,或者对于本地构建者而言,区块的优先级费用作为补偿。因此,从利用该机制进行 “免费 DA” 中无法获得可持续的利润 - 这根本不是免费的。恢复状态意味着恢复所有交易及其优先级费用。这也意味着恢复构建者对提议者的付款,因此提议者极不可能参与此类策略。

优点

  • 分叉选择不需要关心无效区块,因为 BeaconBlock 仍然像以前一样 “有效”。

缺点

  • 实际上并没有解决免费 DA。需要保留交易以验证 payload 实际上是 no-op 并且用于同步。
  • 我们只能在执行期间/之后将 payload 变成 no-op。因此,blob 交易可能仍然被认为是 “可用的”。

4.1 预先向发送者收费,并对 gas_used 使用 Payload 空操作

在这种设计中,发送者仍然在执行之前预先支付其交易的 gas 限制,并在执行后取回 gas_left。为了强制执行 gas 限制,构建者必须将区块使用的 gas 量写入标头。如果事实证明 gas_used 与区块中指定的 gas 不同,则 EL payload 变为 no-op。变为 no-op 意味着恢复到区块之前的状态。

使用 Ethereum execution-specs 查看 Francesco 的实现

优点

  • 没有复杂的分叉选择更改,证明者可以证明一个 payload 变为 no-op 的 BeaconBlock
  • 可以保留 gas_left 退款,因此 UX 保持不变,
  • 对构建者和 IL 友好,
  • 免费 DA” 实际上并没有解决,但实际上执行利用它的策略是不可持续的。

缺点

  • 在一个区块中资助一个帐户并从中进行交易变得不可能,除非另外引入 COINBASE 的基本费用赞助。

选项概述

  1. 乐观证明
  2. 预先向发送者收取全部 tx.gas 的费用
  3. 预先向 Coinbase 收费
  4. EL Payload 空操作

^ 跟踪对无效区块的证明

^^ 静态验证要求 inclusion_gas <= claimed_gas_used,因此包含成本在预先支付,我们可以跳过超过 gas 限制的 tx

方法 发送者 UX 构建者复杂度 分叉选择复杂度 静态验证 FOCIL 兼容性 需要 sum(tx.gas) < block_gas_limit
(1) :green_square: 相同 :green_square: 相同 :red_square: 更高^ :red_square: :red_square: 低 (两阶段强制执行) :green_square:
(2) 没有 gas_left 退款 :red_square: 始终支付全部 tx.gas :green_square: 相同 :green_square: :green_square: :green_square: :red_square:
(2) 带有 gas_left 退款 :green_square: 相同 :green_square: 相同 :green_square: :green_square: :red_square: 低 (两阶段强制执行) :red_square:
(2) 带有 gas_left 退款 + (1) (乐观的 gas_used) :green_square: 相同 :green_square: 相同 :red_square: 更高^ :red_square: :green_square: :green_square:
(2) 带有 gas_left 退款 + (3) 针对声明的 gas_used :green_square: 相同 :red_square: 资金充足的 coinbase :green_square: :green_square: 是^^ :green_square: :green_square:
(3) 针对包含成本 :green_square: 相同 :red_square: 资金充足的 coinbase :green_square: :green_square: :red_square: 低 (两阶段强制执行) :green_square:
(4) :green_square: 相同 :green_square: 相同 :green_square: :green_square: :red_square: 低 (两阶段强制执行) :green_square:
(2) 带有 gas_left 退款 + (4) 针对 gas_used :green_square: 相同 :green_square: 相同 :green_square: :green_square: :green_square: :green_square:

image\ image1024×1024 34 KB

  • 原文链接: ethresear.ch/t/delayed-e...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
以太坊中文
以太坊中文
以太坊中文, 用中文传播以太坊的最新进展