Alert Source Discuss
⚠️ Draft Standards Track: Core

EIP-7732: 锚定提议者-构建者分离

将以太坊区块在共识和执行部分分离,增加共识提议者选择执行提议者的机制。

Authors Francesco D'Amato <francesco.damato@ethereum.org>, Barnabé Monnot <barnabe.monnot@ethereum.org>, Michael Neuder <michael.neuder@ethereum.org>, Potuz (@potuz), Terence Tsao <ttsao@offchainlabs.com>
Created 2024-06-28
Discussion Link https://ethereum-magicians.org/t/eip-7732-enshrined-proposer-builder-separation-epbs/19634

摘要

本 EIP 从根本上改变了以太坊区块的验证方式,通过在逻辑上和时间上将执行验证与共识验证分离。它通过为以太坊验证者引入一个新的可选属性(作为构建者)和一个新的义务(提交payload timeliness attestations)来实现这一点。BeaconBlockBodyExecutionPayload 字段被移除,取而代之的是来自构建者的签名承诺(一个 SignedExecutionPayloadHeader 对象),以便稍后显示相应的执行 payload。此承诺特别指定了执行区块的 blockhash 和要支付给信标区块提议者的value。当处理 BeaconBlock 时,承诺的 value 会从构建者的信标链余额中扣除,并记入信标区块提议者的账户。信标委员会中的一个验证者子集被分配到 Payload Timeliness Committee (PTC),这些验证者的任务是通过广播 PayloadAttestationMessage 来证明相应的构建者是否及时地显示了承诺的执行 payload(具有正确的 blockhash)。PTC 成员不需要验证执行 payload,因此执行验证被推迟到下一个信标区块验证。

动机

本 EIP 解决了几个不同的、不相关的且重要的问题。

  • 绝大多数信标区块提议者将其区块内的执行 payload 的构建外包给第三方(以下称为构建者)。为了做到这一点,他们请求承诺的执行 payload 的哈希树根 (HTR),并将 SignedBlindedBeaconBlock 提交给受信任的方,该方负责在广播之前将 HTR 替换为完整的执行 payload(从构建者处接收)。本 EIP 允许信标区块提议者和构建者之间进行无需信任的公平交换,保证诚实的信标区块提议者将收到构建者的付款,无论构建者的行为如何;并且保证诚实的构建者的 payload 将成为链的规范头部,无论提议者的行为如何。
  • 目前,验证者在收到完整的信标区块(包括执行 payload)和证明截止日期(以太坊主网为 4 秒)之间的时间内,需要执行共识状态转换函数和执行状态转换函数,检查 blob 数据的可用性,并评估区块链的新头部。剩余的 slot 时间用于执行 CPU 密集程度较低且不太关键的任务。通过分离区块的执行部分和共识部分的验证,验证者只需在证明之前的这段关键时间内执行共识状态转换函数,而执行和数据可用性验证则推迟到 slot 的剩余时间(构建者的显示时间和下一个证明截止日期之间)。
  • 通过从共识区块中删除完整的执行 payload 大小,可以加快关键路径上的网络传播速度。
  • 鉴于 DA 可用性检查时间线的自然增加,以及构建者可能甚至在信标区块的证明发布之前广播 blob sidecars 的事实,它可以防止在区块中包含 blob 交易时增加重组的可能性。
  • 它可以防止验证者错过证明,并加强在构建者生成无效 payload 的情况下分叉选择的权重属性。
  • 它消除了使用受信任的中间件来将区块构建委托给构建者的需要。

规范

执行层

不需要更改。

共识层

完整的共识更改可以在 consensus-specs Github 存储库中找到。它们分为:

下面包含主要更改的摘要,Rationale 部分包含有关这些更改的大多数设计决策的解释。

信标链更改

常量
名称
PAYLOAD_ABSENT uint8(0)
PAYLOAD_PRESENT uint8(1)
PAYLOAD_WITHHELD uint8(2)
PAYLOAD_INVALID_STATUS uint8(3)
预设
名称
PTC_SIZE uint64(2**9) (=512)
DOMAIN_BEACON_BUILDER DomainType('0x1B000000')
DOMAIN_PTC_ATTESTER DomainType('0x0C000000')
MAX_PAYLOAD_ATTESTATIONS 2**2 (= 4)
容器
class PayloadAttestationData(Container):
    beacon_block_root: Root
    slot: Slot
    payload_status: uint8
class PayloadAttestation(Container):
    aggregation_bits: Bitvector[PTC_SIZE]
    data: PayloadAttestationData
    signature: BLSSignature
class PayloadAttestationMessage(Container):
    validator_index: ValidatorIndex
    data: PayloadAttestationData
    signature: BLSSignature
class IndexedPayloadAttestation(Container):
    attesting_indices: List[ValidatorIndex, PTC_SIZE]
    data: PayloadAttestationData
    signature: BLSSignature
class SignedExecutionPayloadHeader(Container):
    message: ExecutionPayloadHeader
    signature: BLSSignature
class ExecutionPayloadEnvelope(Container):
    payload: ExecutionPayload
    builder_index: ValidatorIndex
    beacon_block_root: Root
    blob_kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]
    payload_withheld: boolean
    state_root: Root
class SignedExecutionPayloadEnvelope(Container):
    message: ExecutionPayloadEnvelope
    signature: BLSSignature

BeaconState 容器通过添加以下内容进行修改:

  • latest_block_hash,类型为 Hash32,用于跟踪区块链中最后一个执行 payload 的 blockhash。
  • latest_full_slot,类型为 Slot,用于跟踪包含执行 payload 的最新 slot。
  • latest_withdrawals_root 类型为 Root,用于跟踪处理 SignedBeaconBlock 时在信标链中扣除的最新提款的哈希树根。

BeaconBlockBody 通过添加以下内容进行修改:

  • signed_execution_payload_header 类型为 SignedExecutionPayloadHeader,带有构建者的承诺。
  • payload_attestations 类型为 List[PayloadAttestation, MAX_PAYLOAD_ATTESTATIONS],是来自前一个 slot 的 PTC 证明列表。

ExecutionPayloadHeader 对象已更改为仅跟踪提交构建者 payload 所需的最低信息。

状态转换逻辑通过以下方式进行修改:

  • 一个新的信标状态 getter get_ptc 返回给定 slot 的 PTC 成员。
  • 修改 get_attesting_indices 以不返回包含在 PTC 中的信标委员会成员。
  • process_withdrawals 修改如下。提款直接从信标状态获得,而不是从执行 payload 获得。它们从信标链中扣除。信标状态 latest_withdrawals_root 使用此列表的 HTR 进行更新。下一个执行 payload 必须包含与 state.latest_withdrawals_root 匹配的提款。
  • process_block 中删除 process_execution_payload。相反,包含了一个新的函数 process_execution_payload_header,此函数验证 BeaconBlockBody 中包含的 SignedExecutionPayloadHeader,并将付款从构建者的余额转移到提议者。
  • process_operations 中删除 process_deposit_request 并推迟到 process_execution_payload
  • process_operations 中删除 process_withdrawal_request 并推迟到 process_execution_payload
  • process_operations 中删除 process_consolidation_request 并推迟到 process_execution_payload
  • 将一个新的 process_payload_attestation 添加到 process_operations,此函数验证由 PTC 成员广播的 payload 及时性证明。
  • 现在,当在 P2P 层上接收到 SignedExecutionPayloadEnvelope 时,process_execution_payload 作为单独的辅助函数被调用。此函数特别检查生成的信标状态的 HTR 是否与 payload envelope 中承诺的 HTR 一致。

分叉选择更改

常量
名称
PAYLOAD_TIMELY_THRESHOLD PTC_SIZE/2 (=uint64(256))
INTERVALS_PER_SLOT 4
PROPOSER_SCORE_BOOST 20
PAYLOAD_WITHHOLD_BOOST 40
PAYLOAD_REVEAL_BOOST 40
容器
class ChildNode(Container):
    root: Root
    slot: Slot
    is_payload_present: bool

LatestMessage 类被修改为跟踪 slot 而不是 epoch:

@dataclass(eq=True, frozen=True)
class LatestMessage(object):
    slot: Slot
    root: Root

Store 类被修改为跟踪以下字段:

    execution_payload_states: Dict[Root, BeaconState] = field(default_factory=dict)
    ptc_vote: Dict[Root, Vector[uint8, PTC_SIZE]] = field(default_factory=dict)
    payload_withhold_boost_root: Root
    payload_withhold_boost_full: bool
    payload_reveal_boost_root: Root
  • 当从 P2P 网络接收到 PayloadAttestationMessage 时,将调用一个新的处理程序 on_payload_attestation_message
  • 当从 P2P 网络接收到 SignedExecutionPayloadEnvelope 时,将调用一个新的处理程序 on_execution_payload

P2P 更改

  • 用于广播 SignedExecutionPayloadHeader 消息(构建者投标)的新全局主题。
  • 用于广播 PayloadAttestationMessage 对象的新全局主题。

Engine API

无需更改。

理由

质押的构建者

成为构建者是验证者的一种新属性。因此,构建者在信标链中被质押。这允许在协议内无信任地执行构建者向提议者的付款。或者,可以在执行层 (EL) 中强制执行付款,但代价是添加相应的 EL 共识更改逻辑。EL 中的付款的优势在于不需要构建者定期提交存款交易以补充其验证者余额。两种系统都需要在 payload 显示之前提供资金:在共识层 (CL) 中,这是通过让构建者进行质押来完成的。在 EL 中,这是通过余额检查和付款交易来完成的。只有当它是区块的第一个交易时,才能在不执行 payload 的情况下检查此交易。

延迟验证

Payload Timeliness Committee 成员在证明 payload 之前不需要验证它。他们执行基本检查,例如验证构建者的签名以及包含正确的 blockhash。这从以太坊区块验证的热路径中移除了完整的执行 payload 验证,从而使下一个提议者有 6 秒(SECONDS_PER_SLOT * 2 // INTERVALS_PER_SLOT)来验证 payload,而其他每个验证者有 9 秒(SECONDS_PER_SLOT * 3 // INTERVALS_PER_SLOT)。从用户 UX 的角度来看,构建者包含在 slot N 中的交易直到 slot N+1 的提议者首先在其区块 N 之上发布其信标区块,并且 slot N+1 的证明者投票赞成此信标区块作为链的头部时,才会被广泛验证。

(区块, Slot, Payload) - 分叉选择

在指定的安全范围内,保证了分叉选择的以下特性:

  • 提议者无条件付款。
  • 构建者显示安全。
  • 构建者保留安全。

提议者无条件付款是指以下内容。一个以太坊 slot 可以是:

  • 完整:信标区块和执行 payload 都已显示并包含在链上。
  • 跳过:没有信标区块(因此也没有执行 payload)包含在此 slot 的链上。
  • :信标区块已包含在链上,但承诺的执行 payload 尚未包含。

提议者无条件付款是指在第三种情况下,信标区块提议者收到了相应构建者的付款。

构建者显示安全是指如果构建者诚实地行事并及时显示了 payload(正如 PTC 所证明的那样),那么显示的 payload 将包含在链上。这是通过向包含 payload 的分叉选择节点的 LMD 权重添加新的 BUILDER_REVEAL_BOOST 来强制执行的。

构建者保留安全是指如果包含构建者承诺的某些信标区块被保留并迟迟显示,那么该信标区块根将不会成为诚实验证者眼中的区块链规范头部。

为了强制执行这一点,对给定 slot N 上来自先前 slot 的区块的任何证明,不仅不支持 slot N 的区块,而且实际上对其不利。这是 (区块, Slot) 投票的内容。类似地,如果 slot N+1 的共识具有 slot N 的共识区块作为父信标区块,但显示在 N-1 中的执行 payload 作为父执行区块(因此忽略了可能在 slot N 期间显示的执行 payload),那么对该共识区块 N+1 的任何证明不支持从在共识区块 N 中承诺的执行 payload 派生的链,即从完整 slot N 派生。这是 (区块, Slot, Payload) 投票的内容。

构建者及时性提升

当构建者显示预期的 payload 并且 PTC 达成共识,即它是及时的,也就是说,当至少收到 PAYLOAD_TIMELY_THRESHOLDPAYLOAD_PRESENT 的投票时,包含完整 slot 的分叉选择节点(即共识区块及其出现的 payload)会收到相当于信标委员会 40% 的提升。

类似地,当构建者显示一个payload 保留消息并且 PTC 通过至少 PAYLOAD_TIMELY_THRESHOLDPAYLOAD_WITHHELD 的投票达成共识时,父共识区块会收到相当于信标委员会 40% 的提升。鉴于分叉选择投票的 (区块, Slot) 性质,此提升不利于包含构建者承诺的共识区块。

存在这两个提升是为了保证在 Security Considerations 部分中描述的参数下构建者的显示和保留安全。

PTC 伪造

PTC 伪造或 payload 伪造(即同时显示正确的 payload 和保留消息)没有惩罚。控制网络分区的构建者与单个恶意 PTC 成员的勾结可能会通过在 payload 保留和 payload 出现方面都达成共识来导致分裂的看法。可以通过将 PAYLOAD_TIMELY_THRESHOLD 设置为 PTC 的 2/3 来缓解这种情况,在这种情况下,恶意操作者必须控制至少 33% 的 PTC。

另一种缓解机制是为 payload 伪造或 PTC 伪造添加新的削减条件(两者都是验证者签名的消息)。

由于此攻击导致分裂的看法,并且构建者付出了代价(payload 已显示,可能未包含),因此本 EIP 选择了实现的简单性。

提款

来自信标链的提款本质上很复杂,它们涉及从一层中移除资金并将其记入另一层,具有可以从任一层开始的不同触发机制。在将共识层状态转换函数应用于给定的信标状态 pre_state 并处理给定的签名信标区块 block 之前,预计从信标链deduct的提取集完全由pre_state决定。在此 EIP 之前,在执行层上记入的提取集包含在 block 中。如果这些提款不匹配,则该区块被视为无效。通过本 EIP 中包含的分离,这些deduct和 credit 操作变得异步:

  • 在处理信标区块时,从信标链中deduct提款。
  • 刚刚deduct的提款集将提交给信标状态 post_state
  • 当处理任何父信标状态为 post_state 的执行 payload 时,如果该 payload 不包含精确地提交给 post_state 的提款列表,则该 payload 将被视为无效。

这种异步机制有一些后果,因为 slot 可能是如上所述的。在这些情况下,共识层不会处理任何更多的提款,直到执行 payload 满足未完成的提款为止。另一种设计是将所有提款 processing 推迟到执行 payload 验证阶段(即 process_execution_payload)。这具有不需要在信标链上跟踪已完成提款的优点。当缺少多个 payload 时,逻辑会发生变化,在这种情况下,信标链上的余额会发生变化,因此使用前一种机制可能实现的提款可能与后一种机制不同,甚至是无法实现的。

三个状态转换函数

当前的 EIP 向以太坊的区块 processing 添加了一个额外的状态转换函数。Processing SignedBeaconBlock 会更改共识层 BeaconStateSignedExecutionPayloadEnvelope 既会更改执行层状态,也会更改共识层状态。因此,envelope 会提交给共识层后状态转换信标状态根。

兼容的设计

包含列表

本 EIP 完全兼容 EIP-7547 或类似规范中指定的前向包含列表。

Slot 拍卖

本 EIP 的一个简单更改是从 SignedExecutionPayloadHeader 中删除 blockhash 承诺。这允许构建者将任何 payload 提交给 slot。初步安全分析表明,payload 伪造不会削弱分叉选择的 FFG。Slot 拍卖的一些优点包括:

  • 更好的用户体验,因为任何提交的交易都可以包含在下一个区块中(通过区块拍卖,在 slot 的前半部分发送的交易只能包含在以下区块中)。
  • 更长的持续时间来构建区块。
  • 更好地兼容使用分叉选择强制包含列表提案的设计。

向后兼容性

本 EIP 对共识层上的区块验证规则集引入了向后不兼容的更改,必须伴随硬分叉。

安全注意事项

重组抵抗力

PROPOSER_SCORE_BOOST 从 40 减少到 20。但是,这不允许拥有总 stake 的 20% 的提议者进行事前重组,因为攻击者的 payload 也不会被包含。提议者受到勾结的一组验证者和构建者控制的连续区块以及超过总 stake 的 20% 的1-slot sandwich 重组的保护。

构建者安全

  • 一组勾结的提议者和证明者控制连续的区块并超过总 stake 的 20% 可以重组构建者的 payload 并强制其支付投标的 value。
  • 在同一 slot 中不可能对构建者的 payload 进行解绑,也就是说,如果构建者显示链头部的 payload,则当前 slot 不可能存在其他 payload。

恶意 PTC

恶意攻击者控制总 stake 的 35% 在 PTC 上拥有多数控制权的预期时间为 205 000 年。

版权

版权及相关权利通过 CC0 放弃。

Citation

Please cite this document as:

Francesco D'Amato <francesco.damato@ethereum.org>, Barnabé Monnot <barnabe.monnot@ethereum.org>, Michael Neuder <michael.neuder@ethereum.org>, Potuz (@potuz), Terence Tsao <ttsao@offchainlabs.com>, "EIP-7732: 锚定提议者-构建者分离 [DRAFT]," Ethereum Improvement Proposals, no. 7732, June 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7732.