来源 | ethresear.ch
作者 | Vitalik Buterin
翻译|EthereumCN
原标题:《Vitalik: 两个 slot 的提议者/构建者分离方案》
译者注:目前新的分片方案 Danksharding 融合了 PBS (提议者/构建者分离方案) 和 crList 的设计。其中,PBS 方案的构造设计采用的是两个 slot 的 PBS,这也是 crList 的设计基础。关于这种“混合式 PBS” 的抗审查分析,可以参见《Vitalik: 如何提高 PBS 方案的交易抗审查性》。本文是两个 slot 的 PBS 方案的具体设计。
在一个 slot 对里的事件顺序
就在 0 秒之前 — 发布执行头部发布:任何人都可以发布一个执行头部,它包含一个执行哈希,一个出价,和一个构建者的签名。
0 秒 — 信标区块期限:信标区块必须打包胜出的执行头部
0 — 2.67 秒 — 对信标区块做证明:只有一个委员会对信标区块做证明投票
8 秒 — 中间区块的期限:胜出的区块构建者发布一个中间区块,由执行区块主体和他们可以找到的对信标区块尽可能多的证明组成。
8 — 10.67 秒 — 对中间区块的证明:剩下的 N-1委员会对中间区块做证明投票
10.67 — 13.33 秒 — 聚合中间区块的证明
13.33 — 16 秒 — 发布下一个执行头部
如果错失了一个信标区块,下一个 slot 会被换为信标区块而不是中间区块。
图表解释
关键的特性
从分叉选择的角度来看,该系统可以被描述为就像现在的信标链,只是委员会的规模是不平均的,且会有一个 (区块,slot ) 分叉选择。唯一的区别是有些区块只是用来选择为紧随其后的区块选择提议者。这就简化了分析。
每个步骤之间的委员会有助于确保每个步骤都是“安全的“,并且减少被单个行动者滥用带来的影响。
构建者的安全特性
在发布出价那一步,构建者看到执行头部,并知道它是否安全 (如果有很多反对票或缺失的证明,这个执行头部可能是不安全的)。
如果执行头部是安全的,除非出现大于 45% 的攻击、非常大量的罚没,或非常严重的网络延迟,执行头部才可能被回滚。在这种情况下,构建者可以放心进行安全出价。
如果执行头部是不安全的,在他们发布他们的主体后区块链还是有重组的风险,以“偷走”他们的 MEV 机会。在这种情况下,构建者看到这个风险后可以调低他们从这个风险获得风险溢价的出价。
在发布中间区块时,会有两种情况:
信标区块还未被发布。在这种情况里,证明委员会已经对该区块投反对票,因此中间区块产生者 (即构建者) 可以安全地不发布,也不会受到惩罚。
信标区块已经发布。在这种情况下,中间区块会有“提议者得分激励 (proposer boost)',这个激励会比整个证明委员会幅度的大,因此如果构建者发布了,他们的区块将在其余 N-1 证明委员会的证明里获胜。
这确保了如果证明委员会是诚实的,且网络延迟没有非常严重的情况下,构建者就能保证:
如果他们发布了区块就能被打包
如果他们因为信标区块头缺失而不发布区块是不会被惩罚的
构建者有大约 5.33—8 秒的时间发布区块。在他们看到信标区块时可以放心马上发布;但是,他们可能会想等看到更多证明时再发布,因为他们打包证明会得到奖励 (被打包的证明者也会得到奖励)。他们可以自由地在这段时间内 ( 即 5.33 秒的窗口,获得打包证明奖励与第 8 秒的窗口没能获得打包证明奖励)协商权衡。
信标链规范变更的概要
提议者索引定义
把 get_random_proposer_index(state: State) 设为现在 get_beacon_proposer_index(state) 返回的内容。
添加状态变量 chosen_builder_index 和 chosen_exec_block_hash。如果 slot 是空的,设 state.chosen_builder_index = NO_BUILDER (一个等于 2**64 - 1 的常量)。如果 slot 包含一个信标区块,它会包含 BuilderBid,设:
state.chosen_builder_index = builder_bid.message.builder_index
state.chosen_exec_block_hash = builder_bid.message.exec_block_hash
get_beacon_proposer_index(state: State) 的定义如下:
如果 state.chosen_builder_index == NO_BUILDER,返回 get_random_proposer_index(state)
否则,返回 state.chosen_builder_index
携有出价区块的条件
如果 state.chosen_builder_index == NO_BUILDER,这个区块需要包含一个 BuilderBid,且可能不包含一个 ExecBody。builder_bid 需要通过以下检查,且其中 val = state.validators[builder_bid.message.builder_index]:
bls.Verify(val.pubkey, compute_signing_root(builder_bid.message), builder_bid.signature)
val.activation_epoch == FAR_FUTURE_EPOCH or val.withdrawable_epoch <= get_current_epoch(state)
val.balance >= builder_bid.bid_amount
在处理逻辑中添加余额转账:
val.balance -= builder_bid.bid_amount
state.validators[get_beacon_proposer_index(state)].balance += builder_bid.bid_amount
把 get_committee_count_per_slot 改为接受输入 (state: BeaconState, slot: Slot) ( 而不是 epoch )。如果一个 slot 出现 state.chosen_builder_index == NO_BUILDER,委员会数应该返回 1。
携有执行主体的区块的条件
如果 state.chosen_builder_index != NO_BUILDER,区块需要包含一个 ExecBody 且可能不包含 BuilderBid。ExecBody 需要通过以下的检查:
hash_tree_root(exec_body) == state.chosen_exec_block_hash
eth1_validate(exec_body, pre_state=state.latest_exec_state_root)
在处理逻辑中添加:
state.latest_exec_state_root = exec_body.post_state_root
get_committee_count_per_slot 应该返回 (get_epoch_committee_count(epoch) - state.committees_in_this_epoch_so_far) // (slots_remaining_in_epoch)
如果 state.chosen_builder_index != NO_BUILDER,设 state.chosen_builder_index = NO_BUILDER,无论是否有区块。
请注意
slot 时间减少到 8 秒 (请记住:执行区块会是每 2 个 slot 出现一个)。
所有信标区块,包括携有出价和执行主体的,在分叉选择时都应该有 proposer boost。
分叉 slot 应该改为 (block, slot)
可能的延展:通过一项费用延迟发布
如果中间区块的构建者在 slot N 不发布区块,在 slot N+1 就没有交易捆可选。整个提议者序列会被往后推一个 slot (因此 slot N+1 的构建者会变成 slot N+2 的提议者,以此类推),且 slot N+1 需要选出一个新的随机提议者。构建者会获得另一个机会 (即额外的 12 秒作为松弛空间) 来发布。该 slot N+1 执行区块不能包含任何高价值的共识交易 (例如罚没)。但是,他们会被罚款 block.basefee * block.target_gas_limit。
原因是他们的执行区块被延迟了一个 slot,并前置了一个空的执行区块,因此他们需要为这个 slot 付费。提议者序列被延迟确保延迟某个提议者的执行区块对于当被提议的区块是高价值时窃取未来的提议权是没用的。