EigenPod 重新设计 - 检查点证明

本文讨论了EigenPod重设计中的检查点证明系统,详细介绍了如何解决传统M2证明系统中的问题,通过设置有效验证者集合与快照的结合,提供了一种保证ETH来源和数量的机制,从而支持部分提款和防止算计攻击。文章结构清晰,涵盖了系统的工作原理、主要问题及解决方案,并提供了代码示例和逻辑解释。

EigenPod 重新设计 - 检查点证明

参考文献

Pods 的问题

EigenPod 信标状态证明面临的主要技术问题是如何使用这些证明来准确地确定 ETH 的位置。

我们要求状态证明的原因是确保 如果我们授予股份,它们能够保证与最终将通过 pod 流动的 ETH 一对一对应。

  • 这个属性对于支付很重要,决定了质押者因其委派的股份而赚取的金额。
  • 这个属性对于削减更为重要,因为它提供了 保证的下行风险,如果质押者不当行为,他们的股份可以被削减,这直接代表了他们可能失去的 ETH。

因此,EigenPod 证明系统的 最终目标 是确定支持所授予股份的资产当前的位置。理想的证明系统不应是 模糊的。当我们处理一个证明时,我们应该明确知道两件事:

  1. 支持 pod 的 ETH 量
  2. ETH 的位置(是在信标链上还是在 pod 中)

只要我们能确定这些信息而没有歧义,我们可以安全地授予我们知道有支持的股份。

M2 证明系统

M2 证明存在模糊性并且具有一些会使实施新功能(特别是删减)变得更困难的会计特性。为了理解其原因,我们需要了解 M2 系统使用了什么信息——也就是说,我们 实际上在证明什么

目前,我们有三种类型的证明:

  • 提款凭证证明
  • 余额更新证明
  • 部分/完全提款证明

在这三种证明类型之间,我们主要使用了两个关于信标链的信息:有效余额提款。我们用这些信息来确定:

  • 支持 pod 股份的 ETH 量
  • 支持 ETH 的位置(信标链或 pod)

M2 利用这些信息相应地授予或删除股份。

有效余额

提款凭证和余额更新证明使用了信标链中 validator 的 effective_balance,该信息位于信标链的 Validator 容器 中。

有效余额的问题在于它们仅在 每个纪元 更新,而不是 每个块。这意味着有效余额证明可能会最多陈旧 32 个块——遗漏了 validator 余额的变化,例如:

  • 提议者或见证者的削减
  • 提议者奖励
  • 存款
  • 部分或全部提款

仅依靠有效余额证明,我们无法知道 validator 当前在信标链上的 ETH 具体有多少。我们也不知道 validator 是否已经提款。

提款

部分/全部提款证明使用信标链的 Withdrawal 容器 中找到的 amount。它们还将 Withdrawal 创建的纪元与 Validator 容器 中找到的 withdrawable_epoch 进行比较。这作为启发式方法来确定 Withdrawal 是被视为 “部分” 还是 “完全” 的提款。

使用信标链的 Withdrawals 的好处在于,当 EigenPod 看到 Withdrawal 证明时,被证明的精确 ETH 数量已经保证在 pod 中。

然而,依赖信标链的 Withdrawals 也有几个缺点:

  • 信标链的 Withdrawals 每个块创建,并且自 Dencun 升级以来,每个块最大处理 16 次提款。
    • 这些提款可以是部分提款或全部提款;它们会在同一个队列中。无法区分部分和全部提款。
  • Validatorwithdrawable_epoch 无法准确指示完全提款—它仅指示“在 withdrawable_epoch 之后的某个时间点,validator 将被提款。”
    • 还要注意,块中存在的 Withdrawal validator 的 withdrawable_epoch 之后,确实意味着该 validator 已经完全提款。但没有办法判断特定的 Withdrawal 是否是整个提款的金额!

提款边缘案例 - 情景

单个提款证明本身告诉你 ETH 移动到 pod 的数量,但什么都没有告诉你信标链上还剩余多少 ETH。这意味着 我们不能确定 我们看到的提款是否是来自该 validator 的 所有 ETH,或是否有更多正在路上。

这使得基于提款证明调整股份变得困难,并导致 M2 股份会计中的模糊性和边缘案例。考虑以下场景:

0) 我有一个在信标链上拥有 32 ETH 的 validator,我已经证明我的 validator 的提款凭证指向我的 pod。

ETH 股份
32 ETH 在信标链上 32 ETH 的股份

1) 然后,我退出了我的其中一个 validator。 我 没有证明 这一点到我的 pod。

ETH 股份
- 0 ETH 在信标链上 <br> - 32 ETH 在我的 pod - 32 ETH 的股份

2) 接下来,我向我已退出的 validator 存入 1 ETH。 这将自动被提款到我的 pod,但并不是立即的。现在,它仅记录在我 validator 的 effective_balance 中。

ETH 股份
- 1 ETH 在信标链上 <br> - 32 ETH 在我的 pod - 32 ETH 的股份

3) 最后,我进行余额更新证明,显示我的 pod 里我的 validator 只有 1 ETH。 由于上次我 pod 看到的证明余额是 32 ETH,因此这导致了股份减少 31 ETH。

ETH 股份
- 1 ETH 在信标链上 <br> - 32 ETH 在我的 pod - 1 ETH 的股份

最终,这使得一个 validator 可以误报他们在其 pod 中的股份数量,这在被削减的上下文中特别危险。攻击者可以进行恶意行为,然后如上所述操纵其信标股份,以减少可以被削减的股份数量。

这对攻击者的风险很小,因为 m2 证明系统仍会接受缺失的提款证明——因此攻击者可以在削减的危险过后恢复其股份。

M2 证明 - 结论

使用信标链证明,我们无法区分部分和全部提款,也无法依赖提款证明来确定事件的顺序。在 M2 中,我们应用一个启发式方法来获得对此的“最佳猜测”,但这个猜测有一些会计特性导致未来 EigenLayer 削减发布的显著攻击向量。

我们需要在发布削减之前解决这个问题。


检查点证明系统

检查点证明系统基于 pod “活动 validator 集合”的概念。即 - 在信标链上被 pod 知道具有指向 pod 的提款凭证的 validator 集合。

当你证明一个 validator 的提款凭证时,该 validator 会进入 pod 的活动 validator 集合。当你显示一个 validator 已退出时,该 validator 会离开 pod 的活动 validator 集合。M2 系统已经使用了这个状态模型:

  • verifyWithdrawalCredentialsvalidatorInfo.status 设置为 ACTIVE,并将 activeValidatorCount 增加 1
  • 处理全额提款时,verifyAndProcessWithdrawalsvalidatorInfo.status 设置为 WITHDRAWN 并将 activeValidatorCount 减少 1

检查点证明结合了 pod 的活动 validator 集合与信标链状态和 EigenPod 状态的快照,以明确确定 支持 pod 的 ETH 量ETH 的去向

什么是检查点证明?

struct Checkpoint {
  bytes32 beaconBlockRoot;  // 检查点开始之前的块的信标区块根
  uint256 podBalanceGwei;   // 检查点开始时 pod 的余额(以 gwei 计),减去已经由股份支持的余额
  int256 balanceDeltasGwei; // 信标余额的总变化,在检查点进展时更新

  uint256 proofsRemaining;  // 完成检查点之前需要证明的 validator 数量
}

检查点证明有两个步骤:

  1. pod 所有者调用 startCheckpoint。这是对信标链和 EigenPod 状态的快照:
uint256 podBalanceGwei =
  (address(this).balance / GWEI_TO_WEI) - withdrawableRestakedExecutionLayerGwei;

// 使用上一个块的根创建检查点证明,并将当前 `activeValidatorCount` 作为最终izing
// 检查点所需的证明数。
Checkpoint memory checkpoint = Checkpoint({
  beaconBlockRoot: _getParentBlockRoot(uint64(block.timestamp)),
  podBalanceGwei: podBalanceGwei,
  balanceDeltasGwei: 0,
  proofsRemaining: activeValidatorCount
});
  1. 通过 verifyCheckpointProofs,pod 所有者(或其他任何人)为 ACTIVE 状态的每个 validator 提交一个余额证明。这会减少检查点的 proofsRemaining,并将自上次看到的余额以来的差异更新到检查点的 balanceDeltasGwei 中。
struct BalanceProof {
  bytes32 pubkeyHash;  // 被证明的 validator 的公钥哈希
  bytes32 balanceRoot; // validator 的编码余额
  bytes proof;         // 在信标状态根中的包含默克尔证明
}

function verifyCheckpointProofs(
  BeaconChainProofs.StateRootProof calldata stateRootProof,
  BeaconChainProofs.BalanceProof[] calldata proofs
)
  external;

verifyCheckpointProofs 一旦提交足够的证明便会自动完成检查点。要完成检查点,pod 计算总股份增量并将其发送到 EigenPodManager

int256 totalShareDeltaWei =
  (int256(checkpoint.podBalanceGwei) + checkpoint.balanceDeltasGwei) * int256(GWEI_TO_WEI);

// 将 pod 中的任何原生 ETH 添加到 `withdrawableRestakedExecutionLayerGwei`
// ... 这笔金额可以通过 `DelegationManager` 提款队列来提取
withdrawableRestakedExecutionLayerGwei += uint64(checkpoint.podBalanceGwei);

// 完成检查点
lastFinalizedCheckpoint = currentCheckpointTimestamp;
delete currentCheckpointTimestamp;
delete currentCheckpoint;

// 更新 pod 所有者的股份
eigenPodManager.recordBeaconChainETHBalanceUpdate(podOwner, totalShareDeltaWei);
emit CheckpointFinalized(lastCheckpointTimestamp, totalShareDeltaWei);

部分提款的股份(及更多)

检查点证明系统的一个关键细节是 任何我们无法归因于现有股份的 pod 中的 ETH 必须授予股份。因为 pod 中的原生 ETH 从根本上是无法归因的——我们不知道这些 ETH 来自哪里,因为有几个 ETH 来源绕过了合同执行:

  • 信标链全额提款
  • 信标链部分提款
  • Selfdestruct
  • 优先费用转移到区块生产者的费用接收方

在以上每个来源中,有一个特别需要考虑:对于具有经过验证提款凭证的 validator ,来自信标链全额提款的任何 pod 中的 ETH 已经授予了股份!我们需要确保不会盲目地为 pod 中的任何 ETH 授予股份,因为这可能意味着我们在退出 validator 的股份上进行了重复计数。

为了避免重复计数,完成检查点证明会导致一个股份增量,遵循这个公式,其中

v(i) 是 pod 中一个单独的 validator,具有

具有验证的提款凭证的 n 个 validator:

ΔpodShares=ΔpodBalance+∑i=0nΔbeaconBalance[v(i)]

当一个 validator 退出时,

ΔbeaconBalance 将是一个负数:它当前的余额(0)减去它之前证明的

beaconBalance。这个数字被加到

podBalance,确保这些股份不会被重复计数。

这也意味着 将为部分提款授予股份(以及任何其他我们无法归因来源的 ETH)。

什么被快照?

startCheckpoint 采取的快照使我们能够阐明 ETH 的 “去向”,而通过 pod 的活动 validator 集合总余额证明使我们能够阐明 “数量”。这创建了一个我们可以用来授予股份的保证:

image

这个保证的关键在于 startCheckpoint 使用的快照过程,它执行了两个操作:

  • 直接以当前的 block.timestamp 作为输入调用 EIP-4788 信标区块根预言机。这返回前一个信标区块的块根——即对应于 block.number - 1 的信标区块根。
  • 读取 pod 的:
    • activeValidatorCount
    • 当前 ETH 余额(减去任何已经由股份支持的余额)

这个检查点用于所有后续证明的起始点。

uint256 podBalanceGwei =
  (address(this).balance / GWEI_TO_WEI) - withdrawableRestakedExecutionLayerGwei;

// 使用上一个块的根创建检查点证明,并将当前
// `activeValidatorCount` 作为最终izing
// 检查点所需的证明数。
Checkpoint memory checkpoint = Checkpoint({
  beaconBlockRoot: _getParentBlockRoot(uint64(block.timestamp)),
  podBalanceGwei: podBalanceGwei,
  balanceDeltasGwei: 0,
  proofsRemaining: activeValidatorCount
});

为什么这个快照有效?

执行层/信标链块处理的一个奇怪特点是,在执行层中,信标链的提款在所有区块交易之后处理(这实际上导致了我们在 Cantina 中的唯一 “高” BUG)。

这个特点意味着,如果我们快照了 当前 信标区块根和 当前 pod ETH 余额,则可能会出现:

  • 我们的余额证明显示 “0”,因为提款刚刚被处理
  • 当创建检查点时,ETH 未在 pod 中,因为 ETH 在块结束时才会到达 pod。

这就是为什么当调用 startCheckpoint 时,它查询 EIP-4788 预言机,使用当前的 block.timestamp,这实际上返回 上一个区块的根!这意味着,调用 startCheckpoint 时:

  • 上一个区块的信标链提款 已经在 pod 中
  • 针对上一个块的根的证明 如果 validator 在那块中有提款(或如果他们在先前的块中完全提款) 将显示 0 余额
  • 在上一个块之后没有信标链 ETH 进入 pod

这些特性意味着在检查点中证明的

beaconBalances 与在检查点开始时快照的

podBalance 是 100% 不同的,我们可以安全授予股份,而不必担心重复计数。

检查点激励与信标链削减

随着 EigenLayer 原生支付和削减的即将发布,EigenLayer 和 AVS 将依赖于核心协议报告的 EigenPod 股值,以:

  • 根据他们拥有的股份数量支付质押者/操作员
  • 削减表现不当的质押者/操作员,直到其持有股份的数量

因此, pod 会计系统一个重要的考虑因素是:如何确保 pod 股始终保持最新? 毕竟,pod 会计系统的准确性在很大程度上取决于是否定期获得余额更新证明,因为这是它了解信标链状态的唯一 “视图”。

请注意,validator 的信标链余额可能因几个事件而下降:

  • validator 被削减
  • validator 离线
  • validator 离线,并且超过 1/3 的所有信标链 validator 也处于离线状态

M2 针对这个问题的回答是 EigenPod.verifyBalanceUpdate,此方法可以由任何人调用(不仅仅是 pod 所有者),以证明自上次看到的证明以来,validator 的信标链余额是否上升或下降。然而,如果 validator 的余额下降, pod 所有者永远不会有动机去证明这一点,因为这样会减少他们的股份。

检查点有些不同:因为部分提款会授予股份,因此 pod 所有者有动力在以下情况下证明余额更新:

  • 他们想要完全退出一个 validator
  • 他们的 pod 累积了足够的部分提款以补偿余额的下降

在大多数情况下,检查点系统提供了足够的激励来保持 pod 股份的最新状态。

陈旧余额证明

通常,startCheckpoint 只能由 pod 所有者调用。这是因为检查点必须在启动新检查点之前完成——作为一个可能耗费气体的过程,我们希望允许 pod 所有者决定何时进行检查点。

然而,如果 pod 中有大量 validator 在信标链上被削减, pod 所有者可能不想执行检查点。在这种情况下,我们依赖于一个 “陈旧性证明”,以允许第三方代表 pod 所有者启动检查点。

任何人都可以向 EigenPod.verifyStaleBalance 提交陈旧性证明:

function verifyStaleBalance(
  uint64 beaconTimestamp,
  BeaconChainProofs.StateRootProof calldata stateRootProof,
  BeaconChainProofs.ValidatorProof calldata proof
) external;

verifyStaleBalance 允许任何人提交证明,证明 pod 中的一个活动 validator 已在信标链上被削减。

如果成功,这将允许调用者启动一个检查点。请注意,如果已存在一个检查点,调用将失败——需要在成功之前完成现有检查点!


来自 M2 的更改

请在这里跟进进行中的合同工作:eigenlayer-contracts/#515。以下是更改的简要总结。

注意:目前没有这个发布的具体 ETA! 这些说明是在发布时会伴随的合同更改的首次预览——我们希望尽早获得对此的反馈,以了解这些更改是否给任何人带来重大问题!

更改:证明接口

已移除

  • 余额更新证明
    • EigenPod.verifyBalanceUpdates()
  • 提款处理
    • EigenPod.verifyAndProcessWithdrawals()
    • EigenPod.provenWithdrawal()
    • EigenPod.sumOfPartialWithdrawalsClaimedGwei()

已添加

interface IEigenPod {

  /// 状态变更方法

  function startCheckpoint(bool revertIfNoBalance) external;

  function verifyCheckpointProofs(
    BeaconChainProofs.BalanceContainerProof calldata balanceContainerProof,
    BeaconChainProofs.BalanceProof[] calldata proofs
  ) external;

  /// 事件

  /// @notice 当创建一个检查点时触发
  event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot);
  /// @notice 当一个检查点被完成时触发
  event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei);
  /// @notice 当一个 validator 在给定的检查点被证明时触发
  event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex);
  /// @notice 当一个 validator 在给定的检查点被证明余额为 0 时触发
  event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex);

  /// 结构体

  struct Checkpoint {
    bytes32 beaconBlockRoot;
    uint24 proofsRemaining;
    uint64 podBalanceGwei;
    int128 balanceDeltasGwei;
  }

  /// 查看方法

  function activeValidatorCount() external view returns (uint256); // 注意 - 这个变量在 M2 中已存在;这个更改只让它可公开访问!
  function lastCheckpointTimestamp() external view returns (uint64);
  function currentCheckpointTimestamp() external view returns (uint64);
  function currentCheckpoint() external view returns (Checkpoint memory);
}

上下文

有关这些方法如何工作的背景和解释,可通过阅读本文件上部的部分内容找到。

概括而言,此版本删除了两个主要的 EigenPod 方法:

  • verifyBalanceUpdates
  • verifyAndProcessWithdrawals

相应地,pod 所有者将使用:

  • startCheckpoint
  • verifyCheckpointProofs

这两种新方法应提供与已删除的方法相同的功能,并带来以下额外好处:

  • 检查点证明复合执行层奖励;即,当检查点完成时,部分提款将获得可委托的股份
  • 检查点证明批处理信标链的提款(部分和全部)。 不再需要为每次提款提交一次证明,检查点证明要求为每一个 validator 提交一次证明以收回 pod 中的所有提款。
    • 气体估算显示,这将耗费大约 50-60k 气。
  • 不再依赖于第三方信标链预言机时间戳,也不需要等待第三方将时间戳添加到信标链预言机。
  • 不再有 DelayedWithdrawalRouter 相反,完成的检查点将部分提款赠予可以通过 DelegationManager 提款队列提取的股份,方式与其他所有 EigenLayer 股份相同。

用户流程示例 - 申请部分提款

  1. 等待一些部分提款在你的 pod 中累积。
  2. 调用 EigenPod.startCheckpoint()。这将更新:
    • EigenPod.currentCheckpointTimestamp
    • EigenPod.currentCheckpoint
  3. 查询 EigenPod.currentCheckpoint() 并获取将用于生成新检查点证明的 beaconBlockRoot
  4. 为 pod 中每个 ACTIVE 状态的 validator 生成一个余额证明。
    • 你可以通过查询 EigenPod.validatorStatus(pubkeyHash). 检查 validator 是否处于 ACTIVE 状态。ACTIVE validator 已通过 verifyWithdrawalCredentials 进行验证,但尚未被证明为 WITHDRAWN
    • 请注意,此余额证明不使用 Validator.effective_balance,而是使用在 BeaconState.balances 中找到的当前余额。
  5. 将这些证明提交给 EigenPod.verifyCheckpointProofs。你可以单独提交这些证明,也可以全部一次性提交。
    • 请注意,如果你多次调用 verifyCheckpointProofs,后续调用可以在 stateRootProof 参数中留空;这个值在第一次为给定检查点证明时会被缓存。
    • 对于每个提交的余额证明:
      • currentCheckpoint.proofsRemaining 将减少 1
      • currentCheckpoint.balanceDeltasGwei 将更新,包括该证明计算的余额增量
    • currentCheckpoint.proofsRemaining 达到 0 时,检查点会自动完成,你的部分提款将获得股份。

一些重要说明

  • 一旦启动了一个检查点,它不能被取消。 pod 所有者必须完成现有检查点后才能启动新检查点。

    • 这主要是由于在检查点中期难以更新/维护状态。试图让检查点可取消实际上增加了大量复杂性,因此我们采用了这一设计。
  • 完成一个检查点不会授予在检查点启动后进入 pod 的任何部分提款的股份。

  • 提供一个证明表明一个 validator 的余额为 0 将标记该 validator 为 WITHDRAWN 并减少 EigenPod.activeValidatorCount 这意味着在未来的检查点证明中你不需要为该 validator 提供证明。

    • *

添加:过期证明

已添加

interface IEigenPod {
  function verifyStaleBalance(
    uint64 beaconTimestamp,
    BeaconChainProofs.StateRootProof calldata stateRootProof,
    BeaconChainProofs.ValidatorProof calldata proof
  ) external;
}

在大多数情况下,pod 所有者无需考虑此方法——此方法的存在是为了允许第三方在 validator 在信标链上被削减时启动检查点。

如上所述,在检查点激励与信标链削减部分中有进一步解释。

更改:验证提款凭证

已移除:

  • EigenPodManager.beaconChainOracle()
  • EigenPodManager.updateBeaconChainOracle(...)
  • EigenPodManager.getBlockRootAtTimestamp(...)

已更改:

  • EigenPod.verifyWithdrawalCredentials(...)
    • 移除了在 VERIFY_BALANCE_UPDATE_WINDOW_SECONDS (4.5 小时) 内使用 oracleTimestamp 的要求
    • 移除了使用第三方添加到信标根预言机的时间戳的要求
    • 添加了在24小时内针对任何有效信标链时间戳进行证明的能力,而无需等待预言机更新
    • 更改时间戳的语义:oracleTimestamp 参数现在对应于用于证明的信标区块根之后的 下一个有效块
    • 添加了证明时间戳必须大于 currentCheckpointTimestamp 的要求
    • 添加了被证明的 validator 不能已经设置缺席纪元的要求

上下文

verifyWithdrawalCredentials 正在进行一些小更改,以确保与新检查点系统兼容。接口将保持相同,但我们已调整确定可以处理提款凭证证明的条件。

在 M2 中,verifyWithdrawalCredentials 证明:

  • 需要使用特定的 oracleTimestamp 添加到第三方控制的 beaconChainOracle
  • 需要使用的 oracleTimestamp 年限不超过 4.5 小时

这两项都是我们在前 Deneb 系统中的遗留,依赖于由受信方提供信标链块根的 EigenPods。然而,我们现在处于后 Deneb 世界, EIP-4788 为我们提供了保障!

我们正在删除上述两项要求。相反,verifyWithdrawalCredentials 证明:

  • 可以使用最近24小时内的任何有效 block.timestamp,只要时间戳比 currentCheckpointTimestamp

    • 请注意,这个 block.timestamp 应该与被证明的信标块后面块的时间戳匹配!这是由于 EIP-4788 的工作原理
  • 如果被证明的 Validator 容器 显示该 validator 已经设置 exit_epoch != FAR_FUTURE_EPOCH,则证明会回滚。

    • 这是为了防止已经退出/正在退出的 validator 证明提款凭证,因为这样在检查点证明中引入了一个边缘案例问题。
    • *

已弃用:Pre-M2 Pod 激活和 DelayedWithdrawalRouter

已移除:

  • EigenPod.activateRestaking
  • EigenPod.withdrawBeforeRestaking
  • EigenPod.withdrawNonBeaconChainETHBalanceWei
  • EigenPod.hasRestaked()
  • EigenPod.nonBeaconChainETHBalanceWei
  • EigenPod.mostRecentWithdrawalTimestamp

已更改:

  • EigenPod 不再调用 DelayedWithdrawalRouter
  • DelayedWithdrawalRouter 中队列的现有提款将不受影响,将按预期日期可主张
  • 所有未来提款将通过 DelegationManager 提款队列进行。

上下文 - Pod 激活

activateRestaking 原本旨在允许 pre-M2 pod 所有者通过选择调用 activateRestaking 以启用在其 EigenPod 上进行的证明来 “选择加入” M2 升级。同样,withdrawBeforeRestaking 旨在允许未 “选择加入” 的 pod 所有者继续提取共识奖励,而无需参与 M2 证明系统。

通过检查点证明,这种在 M1 和 M2 pods 之间的区分变得不再重要,因为检查点过程直接支持这两个功能集:

  • M1 pod 所有者可以通过调用 startCheckpoint 继续不重新质押其validator 的信标链 ETH 和直接接入共识奖励。
    • 未通过 verifyWithdrawalCredentials 重新质押任何 validator,startCheckpoint 将自动完成一个检查点,授予 pod 所有者与 pod 的原生 ETH 余额相等的股份。这些可以通过 DelegationManager 进行重新质押或提取。
  • M2 pod 所有者可以正常与检查点证明系统交互。

上下文 - 移除 DelayedWithdrawalRouter

由于这两个功能集现在涉及到 pod 所有者申请股份和通过 DelegationManager 进行股份的重新质押/提款,我们看到一个机会,通过完全移除 DelayedWithdrawalRouter 进一步简化 EigenPod 系统。

这非常可取,因为 DelegationManager 队列是 EigenLayer 进行取款处理的方式,而保持 DelayedWithdrawalRouter 意味着我们需要有 2 条资金离开系统的单独路径。

既然我们正在移除 DelayedWithdrawalRouter,其通过 withdrawNonBeaconChainETHBalanceWei 的用法也将被移除。


已弃用:杂项

  • 移除 EigenPod.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR

    • 这是来自 pre-M2 代码的遗留,旨在将 validator 的余额限制为 32 ETH。它在 M2 代码中并未真正使用,也不会在检查点代码中使用。自 Pectra 硬分叉 以来,validator 的余额可能会远远超过 32 ETH。
    • *

附加说明

与 Pectra 的兼容性

Pectra 硬分叉 带来了几个重大变化,其中最重要的变化如下。

1) MaxEB 增加到 2048 ETH,意味着 validator 的余额可以更高,并且可能具有自定义部分提款清扫上限。M2 证明系统将难以支持这一点,因为它试图区分部分/全部提款。然而,检查点证明对此无关紧要!

2) Validator 合并 允许两个具有相同提款凭证的 validator(sourcetarget)被合并。这将把 source validator 的余额设置为 0,target validator 的余额设置为 target + source

目前尚不清楚合并是在共识层上发起还是在执行层上发起(详情见下文)。在后者的情况下,EigenPod 本身将公开方法,允许 pod 所有者启动合并。

一般来说,检查点证明可以毫无问题地处理合并。因为 source 将余额为 0,检查点证明将其移至 WITHDRAWN 状态,因此不需要对其进行进一步证明。 同样, target validator 的余额增量将简单地包含 source validator 的以前余额,因此整体股份增量不应改变。

然而,考虑到检查点证明仅要求对 pod 的 ACTIVE validator 集合(经过验证的提款凭证 + 不 WITHDRAWN)就是意味着有一些重要的边缘案例需要考虑:

  • source: INACTIVE, target: ACTIVE:如果 source 没有经过验证的提款凭证,则 target 的余额变化将在下一个检查点中被记录。

    • 对于共识层合并,这可能允许一个边缘案例,其中 source 合并到 target,然后在 同一纪元中 调用 startCheckpoint。如果随后 source 使用 startCheckpoint 后但仍在同一纪元中 的时间戳验证提款凭证,则在提款凭证证明中使用的 effective_balance 将未反映合并。
    • 目前现有的 EIP 规范尚不清楚合并是否会以任何方式改变 Validator 容器的状态。如果,例如,它设置了该 validator 的 exit_epoch,则在这种情况下验证提款凭证将变得不可行,因此这不是问题(verifyWithdrawalCredentials 会在 validator 不再缺席时回滚)
    • 如果未对 Validator 容器做出修改,我们将需要更改 verifyWithdrawalCredentials 使用 current_balance,就像检查点系统所做的那样。
    • 对于执行层合并,这不是一个问题——我们可以简单地拒绝没有经过验证的提款凭证的合并。
  • source: ACTIVE, target: INACTIVE:如果 target 没有经过验证的提款凭证,则 target 的余额变化 不会被下一个检查点记录。

    • 出于共识层合并,这是一个令人烦恼的问题。该检查点的完成将显示出 source 的余额下降到 0,而 pod 的 ETH 余额没有相应的增加。它将似乎 ETH 消失——同样,检查点系统会相应地减少股份。这不会让用户的资产面临风险,但对于未来的 EigenLayer 削减功能,我们不希望质押者能“暂时移除”他们可以被削减的资产!
    • 解决方案是允许 verifyWithdrawalCredentials 可以由任何人调用(而不仅仅是 pod 所有者),并运行观察者以监控 pod 的这种类型的活动。这并不理想,但实际上没有其他选择。
    • 对于执行层合并,这不是一个问题——我们可以简单地拒绝没有经过验证的提款凭证的合并。目前主要问题是合并是在共识层发起,还是在执行层发起。 在前一种情况下,我们需要做以下几件事:
  • 打开 verifyWithdrawalCredentials,使其可被任何人调用,而不仅仅是 pod 的所有者

  • 运行监视器以监控 source -> target 合并,其中 targetINACTIVE

  • 根据合并后 Validator 容器的变化,我们可能需要改变 verifyWithdrawalCredentials,使其除了使用当前使用的 Validator 容器证明外,还能使用 current_balance 证明。

如果合并是在执行层发起的,我们不需要立即进行任何更改! 我们可以选择在稍后的日期向 EigenPod 接口添加合并支持,并包含上述规则以避免相关的边缘案例。

尚未提及

(可能不完整)此文档尚未明确提及的事项集合 - 想先让大家在今天的会议上了解一下;如果你们想,我们可以讨论这些内容!

  • 检查点证明重新引入当前余额证明以取代 effective_balance 证明,因为后者导致了模糊。
    • 然而,由于我们之前的当前余额证明在 validatorscurrent_balances 树中都需要证明某种内容,因此开销较高,而新的余额证明将只需要后者。我们在证明提取凭证后不需要检查 Validator 容器。
  • 我们不再使用提取证明 - 只使用 verifyWithdrawalCredentials 和余额证明快照。
    • 如果某个验证器的快照余额证明显示“当前余额”为0,则我们将其移入 WITHDRAWN 状态。
  • 当验证器在被标记为已提取后重新存款时会发生什么?那些退出到 pod 但从未验证提取凭证的验证器呢?
    • 当检查点被确定时,如果发生了其中任何一种情况,该 ETH 会在 pod 中显示为“未计算”(即在检查点的 podBalance 部分)。我们将像处理其他任何资产一样授予它股份。
  • 更新余额的激励(以及在支付/削减之间平衡这些激励)。等待讨论!
  • 原文链接: hackmd.io/@-HV50kYcRqOjl...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
-HV50kYcRqOjl_7du8m1AA
-HV50kYcRqOjl_7du8m1AA
江湖只有他的大名,没有他的介绍。