这个新分片设计既解决 MEV 带来的问题,也大大简化了原来的设计。
作者 | Dankrad Feist
译者注:近日以太坊研究员 Dankrad Feist 提出新的分片设计,得到了社区的关注。由于其文章技术性较高,Dankrad 在推特上发布文章时用比较浅显的语言对这个设计进行了介绍。为了增强文章的可读性,ECN 也把其推文翻译了,并放在开头。如果正文翻译有不准确之处,还请读者指教。
白话版:
我在构思一个新的分片设计,在这个设计里,不是每个分片都由独立的提议者,而是在一个 slot 里的所有分片区块都与该信标区块一起被提议。这大大简化了分片设计。
在之前的设计里,在每个 slot 里,分片区块是被独立提议的,而数据可用性必须由委员会来验证。我们不能对所有分片进行整体地验证,因为每个提议者都能够破坏整个流程 (活性故障)
在大多数情况下,下一个信标区块应该包含所有被确认的分片数据,这并不能得到保证:投票可能需要更长时间,特别是如果分片提议者有意使数据最低限度可用。这会使事情变得相当复杂。
在这个新设计里,信标区块也会包含所有分片区块,且它们都由一个委员会一起确认 (每个委员会成员仍然只对分片数据的一小部分进行采样)。所有信标和分片数据一起确认。
这会更简单,使得在同一个信标区块里的所有交易访问分片数据 (你甚至可以在 zkrollup 和 L1 之间获得同步交易!) 并大大地简化了 rollup 的构造 (不会延迟确认等)
这种设计之所以成为可能,是因为有两项新进展。以前,我们认为最好是有许多不同的分片提议者,以最大化抗审查性,并最小化对区块提议者的要求。但是,MEV 改变了这个情况。
我们现在认为, 解决 MEV 的唯一可行解决方案是通过提议者/构建者分离方案来对执行区块进行竞拍。因此,常规的验证者(提议者) 只需要从多个区块构建者中选择出价最高的区块。
这意味着对构建者要求的担忧成为一个不那么需要担忧的问题,因为无论如何他们最终都会成为高度专业化的角色。在实践中,如果执行权和分片区块权是一起竞拍的 (就如这个提案所描述的),市场会变得最高效。
但它的抗审查行如何呢?在有 PBS 的环境里,我们需要对此非常谨慎,因为一小部分的专业组织比一个分布良好的验证者网络更可能进行审查。幸运的是,@fradamt 提出了一个解决方法:crLists。
区块提议者可以构建给所有他们想打包到一个区块的交易创建一个列表 (crList)。然后,构建者必须要么全部打包,要么用其他交易填充区块,直到达到 gas 上限。
@fradamt 提的解决方案:https://t.co/JjJR7I4Lf4
这保留了审查的成本应该是连续为交易出价的成本。由于同步设计,我们在 L1 有新的分片数据构造,是直接依赖于和访问分片数据的,这些数据可以进入 crList。
这是一个简短的总结,请阅读正文以了解更多细节。如果有反馈的话,特别是来自研究 MEV 和设计 L2 的,我会非常感谢!
推特来源:
<iframe id="twitter-widget-2" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="" class="" title="Twitter Tweet" src="https://platform.twitter.com/embed/Tweet.html?dnt=false&embedId=twitter-widget-2&features=eyJ0ZndfZXhwZXJpbWVudHNfY29va2llX2V4cGlyYXRpb24iOnsiYnVja2V0IjoxMjA5NjAwLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X2hvcml6b25fdHdlZXRfZW1iZWRfOTU1NSI6eyJidWNrZXQiOiJodGUiLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X3NwYWNlX2NhcmQiOnsiYnVja2V0Ijoib2ZmIiwidmVyc2lvbiI6bnVsbH19&frame=false&hideCard=false&hideThread=false&id=1475995508372131842&lang=en&origin=https%3A%2F%2Fmirror.xyz%2Fwrite&sessionId=95bcc741958ec18c27c5e54040bde57aa2cb5bf2&theme=light&widgetsVersion=9fd78d5%3A1638479056965&width=550px" data-tweet-id="1475995508372131842"></iframe>
正文:
之前的数据分片构造:把 n=64 个数据分片添加到信标链。每个 slot 都有 n 个提议者独立提议他们的分片 blob,这些数据段随后会由委员会确认。 一旦一个分片 blob 被确认了 (这可能需要几个 slot),它就可以被执行链引用。
这里提出一个替代方案:添加一种新的交易类型,可以包含额外的分片数据作为 calldata。然后,区块由一个单一的区块构建者 (这可以不同于提议者/构建者分离方案的提议者) 构建,打包常规交易和有分片 calldata 的交易。这样效率是高的,因为它意味着 rollup 和 L1 之间的紧密集成成为可能,而且预计这种“超级区块构建者”策略无论如何都会在实践中出现,以便最大限度地提取 MEV。
优势:
劣势
MAX_SHARDS = 2**8 # 256
SHARD_SIZE_FIELD_ELEMENTS = 2**12 # 2**12*31 = 126976 bytes
MAX_BLOCK_SIZE = SHARD_SIZE_FIELD_ELEMENTS * MAX_SHARDS # 2**20 field elements / 32,505,856 bytes
TARGET_BLOCK_SIZE = MAX_BLOCK_SIZE // 2 # EIP1559 for data gas
class ShardedBeaconBlockCommitment(Container):
sharded_commitments: List[KZGCommitment, 2 * MAX_SHARDS]
beacon_block_commitments: uint64 # Number of commitments occupied by Beacon block + Execution Payload
# Aggregate degree proof for all sharded_commitments
degree_proof: KZGCommitment
ExecutionPayload
用于数据 gas 市场的新字段class ExecutionPayload(Container):
# Execution block header fields
parent_hash: Hash32
fee_recipient: ExecutionAddress # 'beneficiary' in the yellow paper
state_root: Bytes32
receipt_root: Bytes32 # 'receipts root' in the yellow paper
logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM]
random: Bytes32 # 'difficulty' in the yellow paper
block_number: uint64 # 'number' in the yellow paper
gas_limit: uint64
gas_used: uint64
timestamp: uint64
extra_data: ByteList[MAX_EXTRA_DATA_BYTES]
base_fee_per_gas: uint256
# Extra payload fields
block_hash: Hash32 # Hash of execution block
transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]
# NEW fields for data gas market
data_gas_limit: uint64
data_gas_used: uint64
data_base_fee_per_gas: uint256
ShardedBeaconBlockCommitment
到 beacon_block_commitments
是信标区块的内容 (包括执行负载),以每个字段元素 31 个字节进行编码@dataclass
class TransactionKZGCalldataPayload:
chain_id: int = 0
signer_nonce: int = 0
max_priority_fee_per_gas: int = 0
max_fee_per_gas: int = 0
# New data gas
max_priority_fee_per_data_gas: int = 0
max_fee_per_data_gas: int = 0
gas_limit: int = 0
destination: int = 0
amount: int = 0
payload: bytes = bytes()
# KZG Calldata
kzg_calldata_commitments: List[KZGCommitment, MAX_SHARDS]
access_list: List[Tuple[int, List[int]]] = field(default_factory=list)
signature_y_parity: bool = False
signature_r: int = 0
signature_s: int = 0
kzg_calldata_commitments
都被打包到 ShardedBeaconBlockCommitment
(分片信标区块承诺) 的 sharded_commitments
(分片承诺) 里start}x]_2)$
KZGCALLDATA
,它会把 kzg_calldata_commitments
添加到一个特定的存储位置验证分片承诺是否得到正确编码
< SHARD_SIZE_FIELD_ELEMENTS
, 通过配对等式来检查:
如果有 2N 个分片承诺,第一组 N 是数据,剩下的一组 N 是一个多项式扩张 (polynomial extension)。我们需要验证这 2N 个分片承诺都在一个次数为 N−1 的多项式里。
标准方法:对 2N 大小的数据进行快速傅里叶变换 (FFT),验证 N 个高阶系数为 0。这需要 2Nlog2N 次群乘法,这样开销就会很贵
更便宜的方法:在该阈值的任一点上使用重心拉格朗日插值公式来对前 N 个承诺进行取值,然后对后 N 个承诺做相同的事。如果两点是相同的,那么它们是在次数为 N-1 的同一个多项式上。2N 大小的数据仅需要一个多标量点乘 (MSM),它所需的时间与 2Nlog2N 次群乘法差不多。
BLS12_381
(任何合理的分片实现所必需的)区块构建者有两项新任务。一项是计算样本的 KZG 见证数据,另一项是在 p2p 网络里为样本播种。
现在在以太坊上大多数交易经过的交易池并不处理数据交易。每个节点都处理完整的交易池,但有了分片后,链的容量会增加到 1.3 MB/秒,如果所有交易都经由交易池,1.3 MB/秒也将是预计交易池带宽的下限。
显然,节点需要处理整个交易池的交易但对数据交易进行分片是不合理的。相反,当涉及数据交易时,我们需要在交易池做数据可用性采样。
将交易发送到公共交易池的另一种方法是将他们发送到区块构建者,现在 Flashbots 已经有效地实现了这一点。优点是区块构建者可以承诺不会抢跑交易。如果他们这样做,用户可以简单地转换到另一个区块构建者。
例如,Solana 已经实现了这个设计,并在默认情况下发送交易到下一个区块提议者。
因此,以太坊链对交易池容量的需求很可能会变得小得多,甚至变得不再需要。但是,我们还是希望在设计中保留交易池,原因有两个:
所有交易都通过 libp2p pubsub (发布订阅模式) 的 channel 广播。交易类型 3 包括 kzg_calldata_commitments
,但不包含实际的底层数据。
我们构建了第二组 512 个 pubsub channel,仅用于广播分片数据交易的样本。当有人想发送一笔类型 3 交易到交易池,他们发送这 512 个样本里的每个 kzg_calldata_commitment
到这些样本 channel。
crList
相关阅读:
ECN的翻译工作旨在为中国以太坊社区传递优质资讯和学习资源,文章版权归原作者所有,转载须注明原文出处以及ethereum.cn,若需长期转载,请联系eth@ecn.co进行授权。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!