LUCID:具有分布式有效载荷传播功能的加密内存池

本文为机器翻译
展示原文

作者:安德斯·埃洛森

感谢Julian MaBenedikt WagnerJustin Florentine的反馈和审阅。还要感谢参加一月初柏林会议的各位成员,他们在会上讨论了设计的某些特性: JulianThomasJustinVitalikCasparMariosAnsgarFrancesco

1. 概述

本文介绍 LUCID,一种加密内存池设计,它弥合了包含者和提议者之间的鸿沟,同时遵循现有的以太坊机制,例如ePBSBAL和可审计的构建者出价 ( ABB )。该设计用途广泛,例如可用于发送者无需信任的自解密、受信任方解密或阈值设计。LUCID 是一个首字母缩写词,概括了其关键特性:

  • IL——该设计依赖于分叉选择强制执行的包含列表(IL),类似于FOCIL,但经过初步修改,赋予包含者更公平的包含权以及用于MEV保护的加密功能。因此,包含者的行为更类似于提议者。IL可以错开执行,以提高抗审查性,促进去中心化的包含预确认,并在不造成网络效率损失的情况下奖励包含者。
  • U – 考虑两种 IL 设计方案:统一价格拍卖包含列表 ( UPIL ),根据发送方提供的包含费用对交易进行排名;无条件IL (UIL),其中包含方决定其自身列表的优先级顺序。
  • C – IL 可以携带C密文,这些密文以密封交易 (ST) 的形式存在于加密的内存池中,并且可以捆绑在一起。ST 在 ABB 中提交。
  • D – 有效载荷以D分布式方式传播,并且仅包含对网络表示中 IL 交易的引用。共识表示仍然是一个独立的执行有效载荷,包括用于从 ST 发送者扣款的 ST 票据以及解密的 ST。

本文中描述的许多组件可以单独使用,也可以组合使用。例如,可以只运行加密方案,而不使用分布式有效载荷传播(DPP);唯一的缺点是广播效率会降低。LUCID 的时间表如下所示。

第 2 节向读者介绍所要解决的问题,第 3 节深入探讨加密设计。第 4 节介绍 DPP,第 5 节讨论设计中如何处理揭示选项。第 6 节最后进行简要讨论,其中 6.1 节详细说明了如何构建最小可行 EIP。附录 A 通过提出交错包含列表 (SIL) 完善了 DPP 的愿景,其中包含器在时隙内逐步构建有效载荷。附录 B 提出了一种更严格的设计,其中待解密的 ST 在有效载荷中指定,而不是在 ABB 中指定。附录 C 最后展示了解密器可以部署的一种解密方案。

时间线

图 1 提供了 LUCID 机制的概述。

图 1
图 1 1920×1391 167 KB

图 1. LUCID 时间线。构建者生成包含密封交易承诺的 ABB。这些 ABB 包含在信标块中,以便解密者能够在下一个时隙开始之前及时释放密钥。IL 中列出的交易可以通过引用包含在有效载荷中。

  • T_1 T 1之前——包含器会传播 IL,除了明文交易 (PT) 之外,IL 还可以包含 ST。ST 可以单独包含,也可以捆绑在一起(深蓝色背景),并且可以从公共加密内存池中获取。每个 ST 都包含一个签名的 ST 票据,用于向发送方收费并绑定到解密器,以及包含在 ST 中的密文encrypted_tx encrypted_tx后会生成一个签名的 PT,该 PT 的from字段可以与 ST 不同,并且还包含一个ToB_fee_per_gas字段,该字段用于在解密后将 PT 排序到区块顶部 (ToB)。发送方按照解密器的非协议指令(如果适用,则使用其公钥)以开放设计加密交易发送给解密器,或者也可以自行解密,无需信任。附录 A 描述了如何交错部署 IL 以实现更好的覆盖范围,附录 C 给出了解密器可以部署的一个加密设计示例。
  • T_1 T 1 – 槽位n的证明者(紫色冻结其对传播的 IL 以及前一个块的解密密钥的视图。
  • T_1 T 1之后——一旦构建者确信他们已经观察到所有相关的 IL 和密钥(大多数验证者冻结视图中的那些),他们就会抛出ABB (扩展的ExecutionPayloadBid ),以获得构建该区块的权限(蓝色矩形)。这些 ABB 包含 IL 中 ST 和 ST 包的哈希值的“ST 承诺”。ABB 还会标记来自前一个槽位的已观察到的解密密钥。
  • T_2 T 2 – 在时隙n n开始时,提议者选择一个获胜的 ABB,该 ABB 至少与其自身对所需 IL 和密钥的理解一样全面。它将该 ABB 包含在信标块中。
  • T_2之后——在观测到 ABB 后,节点开始请求任何缺失的 IL 以及 ABB 的 ST 承诺中引用的 ST 字节。发送方和解密方现在也可以独立地传播这些字节。
  • T_3 T 3 – 槽位n验证者对当前链头进行投票。如果信标区块缺失,或者由于冻结视图中缺少 IL 或密钥,导致包含的 ABB 审核失败,则他们会指出其视图中链头所在的前一个区块。如果 ABB 通过审核,则他们会乐观地验证该区块。
  • T_3 T 3 (有效载荷释放)之后——构建者释放有效载荷,其中也包含 ST 票据。第一批交易(白色矩形框)是解密的 ST,之前已在区块n-1提交并按其解密后的每 gas ToB 费用排序。接下来是来自当前时隙的常规 PT(黑色矩形框),由构建者自由排序。构建者通过索引引用 IL 交易,而不是重新传播它们(在网络表示中使用单独的列表)。
  • T_3 T 3 (有效载荷重构)之后——每个客户端根据其本地缓存的 IL 事务引用以及 ST 承诺来解析 IL 事务引用,并组装完整的有效载荷。它计算并验证有效载荷根,然后执行有效载荷。由包含的 ABB 选择的用于下一时隙解密的 ST 在执行有效载荷中以 ST 票据列表的形式表示,这些票据根据其指定的完整gas_limit进行计费。
  • T_3 密钥释放)之后,每个解密器都会观察信标块中包含的 ABB 中的 ST 承诺。它会确认 ABB 拥有其自身 ST 承诺的正确数据(例如,与其gas_obligation相关的数据,该 gas_obligation 指定其消耗的 gas 量),所有gas_obligation条目的总和是否在下一个有效载荷的分配份额( ToB_gas_limit )之内,以及信标块是否已被验证。它会传播用于揭示下一个区块中 ST 的签名密钥。这些密钥会在T_5截止时间之前通过 P2P 泛洪传播,并被下一个区块的验证者观察。然后,就可以使用解密后的 ST 构建有效载荷n + 1ToB。
  • T_4 T 4 – 有效载荷及时性委员会 (PTC) 对有效载荷的及时性进行投票。鉴于分布式设计,有效载荷中引用的事务的 IL 或已提交的完整 ST/ST 包必须在此之前也已到达 PTC 成员处,才能通过投票表明有效载荷是及时的。
  • T_4T_5 发布密钥的截止日期可以通过 PTC 位域投票来强制执行,以评估其时效性;也可以通过槽位n+ 1验证者冻结其对已发布密钥的视图并使用视图合并来强制执行。验证者根据 PTC 位域投票或冻结密钥视图的执行情况,对下一个 ABB 进行投票。
  • T_5之后,该过程遵循与T_1之后(对于前一个时隙)相同的轨迹。时隙 n解密ST 被添加到 ToB 中,并按 ToB 费用排序,然后收取该费用。鉴于 ST 在块n构建之前解密该设计与 BAL 完全兼容:块n+ 1构建器执行并准备 BAL,一切照常。

2. 引言

对于以太坊等去中心化区块链而言,一个令人担忧的问题是单个提议者对每个区块中包含的交易拥有垄断权,这可能导致审查和用户福利欠佳。因此,人们提出了多并发提议者(MCP)的设计方案( 1 , 2 , 3 , 4 )。多年来对包含列表(IL)的研究(例如, 1 , 2 )最终促成了分叉选择强制包含列表( FOCIL )的设计。FOCIL 通过EIP-7805成为以太坊中实现抗审查(CR)的主要方案,它允许多个包含者传播待包含在下一个区块中的交易的包含列表。然而,当区块已满时,提议者仍然有权审查交易,即使他们愿意支付高于实际包含交易的价格。此外,很大一部分可审查的交易 必须私下传播以避免 MEV,因此不能依赖 FOCIL 进行 CR。

人们提出了多种限制区块内容控制权的区块内协议(IL)设计方案。无条件区块内协议(UIL)要求所有符合常规包含标准的已列出交易都必须包含在区块中。EIP -8046引入了统一价格拍卖包含列表(UPIL),确保在区块已满的情况下,提议者无法再忽略区块内协议。交易按其愿意支付的费用进行排序,出价最高的交易将被包含,每笔交易支付相同的统一区块内基础费用,该费用将被销毁。这提供了强大的代码审查能力(CR),有利于对时间敏感的交易和多维费用市场。然而,UIL 和 UPIL 并不能阻止多版本增强(MEV),因为交易仍然需要公开传播。

为了防止 MEV 攻击,交易必须在提交之前保持隐藏状态。针对加密内存池,人们提出了多种设计方案,例如可能利用提议者承诺的阈值加密、类似密封交易中的提交-揭示方案,或二者的混合方案。密封交易在 ePBS 下可以利用ABB 。类似密封交易的基于分叉选择强制执行的提交-揭示方案,可以进一步促进各种协议外加密方案——一种广义密封交易。最近,一篇研究论文EIP也提出了一个朝此方向发展但采用同时隙解密的设计方案。另一种策略是依赖智能账户加密内存池,该策略也已作为EIP提出。

哈耶克式的去中心化区块构建论点是,更广泛的参与者群体将共同拥有构建一个优质区块所需的知识。值得注意的是,只有通过屏蔽单个参与者对区块的贡献(使其免受MEV的影响)并确保有效交易被纳入区块,我们才能真正使他们能够以无需信任的方式交流这些知识。

包含列表通常会引入数据冗余:事务信息先在内存池中传播,然后通过包含列表 (IL) 传播,最后在执行有效载荷中再次传播。通过将包含列表的传播视为“预填充”步骤,有效载荷可以有效地分布在整个时隙期间,而不是在末尾突发传播。这样就避免了在单个时隙窗口内重复传输相同的字节(一次在包含列表传播中,一次在有效载荷信封中)。减小ExecutionPayloadEnvelope载荷信封的大小可以最大限度地减少传播延迟,从而允许更短的时隙时间、更大的包含列表或更大的数据块。该设计与有效载荷分块 ( 1 , 2 ) 兼容,后者只需在 DPP 下对已经经过一定程度压缩的有效载荷进行操作即可。

尽管DPP提高了网络效率,但它并不能解决多个包含器(IL)传播相同交易的低效问题。因此,理想的解决方案是协议内解决方案,以减少重叠。本文为此提出了交错包含列表(附录A),该列表还有助于实现无需信任的预确认。为了限制执行前需要协调的独立解密密钥的数量,可以在提交前将密封交易(ST)捆绑在一起。本文提出了LUCID,它实现了通用密封交易(扩展自文献[1 , 2 ]),同时升级了包含器,使其能够屏蔽交易免受MEV的影响,并拥有平等的区块空间权限,从而弥合了包含器和提议器之间的差距。

3. 加密设计

本文首先使用 UPIL 机制描述加密设计,并在 3.10 节中介绍 UIL 机制所需的更改。在通用设计下,也可以使用 Vanilla FOCIL(条件 IL)。需要强调的是,如 6.1 节进一步讨论的那样,3-4 节中概述的几个特性(例如 DPP、UPIL 和捆绑)对于基本的 LUCID 加密内存池并非至关重要。

3.1 密封交易

密封交易 (ST) 由已签名的 ST 票据和密文encrypted_tx组成。ST 包含以下字段:

  • from此处签署ST车票并支付费用,
  • 常规字段noncegas_limitmax_fee_per_gasmax_priority_fee_per_gasmax_ranking_fee_per_gas
  • 负责解密的实体的decryptor_address
  • decryptor_fee将在执行解密后的明文交易时支付,前提是from已获得资金。
  • reveal_commitment ,其中reveal_commitment = hash_tree_root(RevealCommitmentPreimage(ticket.from, ticket.nonce, plaintext_tx, ToB_fee_per_gas))将揭示的明文有效负载绑定到特定的付费票据,
  • ciphertext_hash ,其中ciphertext_hash = keccak256(encrypted_tx)将密文字节绑定在一起,
  • encrypted_tx ,解密后得到RevealedTransaction(plaintext_tx, ToB_fee_per_gas)

为了推广通用解决方案,基本思路是协议仅规定客户端如何解析和打开encrypted_tx ,而解密者则自行(在协议之外)定义他们使用的密钥托管/混合加密结构。具体来说, encrypted_tx是一个信封:

encrypted_tx = header_len:u16 || header || ct_demct_dem = nonce || aead_ciphertext

协议header对协议本身是不透明的,其中可能包含任何解密器特定的元数据,用于恢复 DEM 密钥(例如,混合公钥加密 ( HPKE )/KEM 封装、阈值解密器密钥下的阈值密文等)。解密器会发布协议外的指令,描述发送方如何填充header以及如何针对给定的票据导出 DEM 密钥k_dem 。在解密时,解密器仅发布每个票据的 DEM 密钥材料 ( k_dem ),以便任何人都可以解密ct_dem并根据reveal_commitment验证解密结果。

解密器应确保释放的k_dem与已付费票据上下文相关(例如,通过使用域分隔的(chain_id, ticket.from, ticket.nonce)作为 KDF 输入(如果使用 HPKE,则使用 HPKE info )和/或 AEAD 关联数据来导出)。这使得泄露的密钥与票据相关,因此即使跨票据复制了header字节,释放一个票据的解密材料也不会帮助解密附加到其他票据的密文(从头部恢复的任何长期秘密都绝不能泄露)。附录 C 给出了此类构造的一个示例(感谢 Benedikt Wagner)。对于无需信任的自解密,发送方可以简化操作(例如,设置header_len = 0并直接为每个票据选择一个新的 DEM 密钥)。

class RevealedTransaction ( Container ):plaintext_tx: Transaction # Type 2 transaction ToB_fee_per_gas: uint64 class RevealCommitmentPreimage ( Container ):ticket_from: ExecutionAddressticket_nonce: uint64plaintext_tx: TransactionToB_fee_per_gas: uint64 class STTicket ( Container ): from : ExecutionAddressnonce: uint64gas_limit: uint64max_fee_per_gas: uint64max_priority_fee_per_gas: uint64max_ranking_fee_per_gas: uint64decryptor_address: ExecutionAddressdecryptor_fee: uint64reveal_commitment: Bytes32ciphertext_hash: Bytes32signature: Bytes65 # Signature by `from` over the ticket fields class SealedTransaction ( Container ):ticket: STTicketencrypted_tx: ByteList[MAX_ENCRYPTED_TX_BYTES]

gas_limit必须足以支付encrypted_tx字节大小的 calldata 成本,受MAX_TRANSACTION_GAS_LIMIT的限制,并且将全额收费—— RevealedTransaction后观察到实际 gas 使用量时,不会退款。RevealedTransaction 中的解密plaintext_tx是一个 EIP-1559(类型 2)交易, max_priority_fee_per_gas = 0max_fee_per_gas = 0 (因为解密交易已由 ST 票据预付),并且gas_limit = ticket.gas_limit

ST票据的随机数(nonce)复用以太坊的普通账户随机数,并且无论密文是否最终被揭示都会被消耗,因为ST票据无论执行是否成功都会被收费。ST发送者对ST票据进行签名。签名是基于一个域分隔的摘要计算的,该摘要包含chain_id (以及fork/version)和票据字段(不包括signature )的哈希树根。

encrypted_tx中的明文有效载荷由明文发送方作为plaintext_tx的一部分单独签名。节点通过验证票据签名并检查ciphertext_hash是否与encrypted_tx的哈希值匹配来验证 ST。

3.2 密封交易捆

密封交易在ABB中进行承诺。如果加密内存池变得流行,大量的独立承诺和解密密钥可能会给网络带来压力,尤其是在以太坊扩展的情况下。因此,有必要限制ABB中对密封交易的承诺数量,同时还要保证高吞吐量。所以,可以将密封交易捆绑在一起并共同承诺。

同一交易包中的所有交易必须具有相同的decryptor_address ,并且该交易包必须由控制该decryptor_address的实体签名。交易包可以携带完整的ST,也可以仅包含带有签名的哈希值。这样,完整的ST交易包就需要由包含者自行重建。考虑到这些字节必须在PTC截止时间前可用,要求包含者携带完整的ST字节似乎是合理的。如果在信标块中观察到引用该交易包的包含者不可用,则必须通过P2P传播完整的交易包。

包含非捆绑加密内存池交易的功能仍然有诸多益处,原因有三:

  1. 任何ST只要包含在IL中即可执行,从而为公共内存池提供抗垃圾邮件保护。
  2. 诸如阈值解密之类的设计无需预先捆绑交易的序列器即可运行,
  3. 用户无需传播他们想要以非信任方式解密的单个 ST 的捆绑包。

3.3 ST承诺

在 ABB 中,密封交易以“ST 承诺”的形式进行承诺,可以单独承诺,也可以作为来自公共加密内存池的捆绑包的一部分承诺(或者可能通过协议外方式提供,并可能利用类似于 MEV Boost 的设计)。包含列表为 ST 承诺提供了一条重要的包含路径——构建者必须遵守他们提出的承诺。每个 ST 承诺都指定了四个字段:

class STCommitment ( Container ):bundle: bool # False if ST, True if ST-bundle commitment_root: Bytes32 # ticket_root if ST, bundle_root if bundle decrypt: Bitfield # indices to release keys to decrypt the tx gas_obligation: uint64 # sum of gas_limit over entries with decrypt=1

ST 承诺通过commitment_root来识别,commitment_root 可以是已签名票据的 SSZ 哈希树根ticket_root = hash_tree_root(STTicket)也可以是已签名捆绑包的 SSZ 哈希树根bundle_root ,后者涵盖捆绑包中的所有ticket_root条目。第 6.3 节讨论了decrypt=1ticket_root条目的可能scheduled_root 。请注意,密文字节通过ciphertext_hash = keccak256(encrypted_tx)绑定到票据,该哈希值包含在已签名票据中。

3.4 配额和 ToB 天然气限制

每个包含列表 (IL) 都有一定数量的 ST 承诺,初始值可以设置得比较低;例如,每个 IL 最多可以提交MAX_COMMITS_PER_IL = 4 ST 承诺。也可以允许构建者自行提交 ST 承诺,例如也允许其提交MAX_COMMITS_PER_IL个 ST 承诺。但是,为了简化设计,最简单的方法可能是直接给构建者分配一个独立的 IL。每个 IL 都有一个max_bytes_per_inclusion_list分配值,就像 FOCIL 一样。该值会随着 gas 限制的变化而变化,这样当区块的gas_limit增加时,包含者相对于提议者不会处于劣势。它可以计算为max_bytes_per_inclusion_list = gas_limit/(IL_COMMITTEE_SIZE * GAS_PER_AGG_IL_BYTES) 。设置GAS_PER_AGG_IL_BYTES = 2**9当使用IL_COMMITTEE_SIZE = 16 (如 FOCIL 中那样)时,在 gas 限制为 60M 的情况下,IL 字节大小为7.15 KiB承诺仍然计入max_bytes_per_inclusion_list中。

每个区块都有一个用于解密交易的ToB_gas_limit ,其值设定为前一个区块总gas_limit的某个比例,暂定为1/4 * gas_limit 。此外,还有一个ToB_marginal_ranking_fee_per_gas ,其计算方法为:当前区块的marginal_ranking_fee_per_gas (如 EIP-8046 中所述)与从下一个区块的ToB_gas_limit分配中排除的最高排名 ST 的ranking_fee_per_gas中的最大值。

3.5 可审计的建筑商投标(ABB)

构建者为获得构建有效载荷的权利而进行可审计的构建者竞价(ABB)。ABB 通过包含ToB_marginal_ranking_fee_per_gas 、ST 承诺以及关于前一个区块 ST 承诺的密钥遵守情况的位域来扩展ExecutionPayloadBid

class ILCommitments ( Container ):IL_root: Bytes32commits: List [STCommitment, MAX_COMMITS_PER_IL] class ILKeyAdherence ( Container ):key_adherence: List [Boolean, MAX_COMMITS_PER_IL] class ABB ( Container ):... # existing fields of the ExecutionPayloadBid ToB_marginal_ranking_fee_per_gas: uint64IL_data: List [ILCommitments, IL_COMMITTEE_SIZE]key_adherence: List [ILKeyAdherence, IL_COMMITTEE_SIZE] # one bitfield per previous IL in a list of bitfields

构建器使用(ticket.from, ticket.nonce)对 ST 承诺中的 ST 进行去重。去重后的集合中只能有一个 ST 具有相同的(ticket.from, ticket.nonce) ,该 ST 应包含在有效载荷中,其decrypt位设置为1所有其他具有相同(ticket.from, ticket.nonce) ST 的decrypt位必须设置为0此外,对于ticket.from生成无效 ticket- nonce序列的 ST,或在票据计费开始时不可计费的 ST(参见第 3.9 节),也会以相同的方式移除。应用确定性规则来确定在去重过程中要保留哪个 ST,该规则选择捆绑包中 ST 数量最多的实例,如果数量相同,则使用 IL 的committee_index进行打破。

如果存在多个指向特定 ST 捆绑包的 IL 承诺,则重复的承诺会将decrypt设置为规范的零编码0 (单比特 0)以节省空间,并且仅保留committee_index最高的 IL 的 ST 捆绑包。为避免可塑性,当decrypt没有设置位时,必须将其编码为精确的0 (单比特 0),并解释为全零掩码,而与捆绑包长度无关;其他全零编码无效。

对于捆绑包内重复的ST,它们共享同一个decryptor_address ,因此去重严格来说是解密器的一个记账操作。此外,构建者不能随意设置decrypt位。时隙n + 1验证者、构建者(以及所有其他节点)将审查decrypt位的设置是否严格遵循确定性规则(例如去重),且不会遗漏IL暴露出的有效ST。如果有效载荷未通过审核,则协议将进入无效有效载荷下的恢复过程,如第4.5节所述。

如果去重后的 ST 的ranking_fee_per_gas超过ToB_marginal_ranking_fee_per_gas ,则通过设置decrypt = 1将其包含在内,如果排名相同则使用ticket_root进行判定。确定要包含哪些 ST 后,每个 ST 承诺的gas_obligation被设置为该承诺中所有ToB_marginal_ranking_fee_per_gas decrypt = 1gas_limit条目的总和。ToB_marginal_ranking_fee_per_gas 还可以用于压缩decrypt位域,使其仅覆盖ranking_fee_per_gas足够的交易的允许范围。

ABB 中的commitment_root允许解密器在及时观测到信标块后识别自身并释放解密密钥,甚至在有效载荷释放之前即可进行。每个IL_root都包含在 ABB 中,用于解决歧义,这将在讨论 DPP 的 4.3 节中进一步阐述。

有两种方法可以避免构建者每次投标都传播完整的 ABB。构建者可以为每次新投标指定相对于其先前投标的增量,并包含一个用于引用的哈希值。可以预期,ST 承诺会在投标截止日期前很早就确定,这意味着后续投标的增量只需涵盖因迟到的 PT 而导致的投标值和有效载荷的变化。另一种方法是采用拉取机制,构建者的投标较为轻量级,提案者在发布前从中标构建者处拉取 ABB。

3.6 证明

检验员将ABB与他们观察到的IL进行比较。他们核实以下内容:

  • 所有gas_obligation条目的总和在ToB_gas_limit范围内,
  • ABB 中正确规定了所有及时观察到的 IL,没有含糊不清之处,并给出了已公布的ToB_marginal_ranking_fee_per_gas

ABB 中包含但未经验证者审核的列表将不予审核。节点在 ABB 中观察到这些列表后会提出请求,PTC 最终将投票决定其是否及时生效。

3.7 关键版本

解密器会观察信标块n n传播的 ABB 中的ToB_marginal_ranking_fee_per_gas及其规定的gas_obligation 。它会验证ToB_marginal_ranking_fee_per_gasdecrypt位域是否确实为其自身的 ST 承诺生成了指定的gas_obligation ,并且所有gas_obligation条目的总和是否在ToB_gas_limit范围内。这是释放解密密钥的必要条件。具体来说,如果有效载荷随后被证明无效或不及时,解密器的 ST 承诺始终在ToB_gas_limit范围内。这意味着它们仍然可以包含在下一个有效载荷的 ToB 中,如第 4.5 节进一步讨论的那样。

如果负责列出 ST(或捆绑包)的 IL 不可用,解密器此时(如果之前未执行)将广播ticket_root / bundle_root与 ABB 中的commitment_root匹配的完整 ST 字节(或捆绑包主体),以便节点可以在 PTC 截止时间前验证已发布的密钥。当解密器(或任何人)提供已提交 ST 的完整SealedTransaction字节时,节点会检查hash_tree_root(st.ticket) == commitment_rootkeccak256(st.encrypted_tx) == st.ticket.ciphertext_hash 。当解密器确信信标块将成为规范块(例如,在观察到其证明之后)时,它将发布其密钥。

在密钥发布时,解密器会按照第 3.1 节所述发布对称密钥材料。密钥以消息的形式发布,该消息由decryptor_address签名,并通过committee_indexcommit_index标识关联的 ST 提交,此外还包括槽位号以及承载关联 ABB 的信标块的beacon_block_root 。对于密钥包,密钥会被封装在一个长度与设置为1 decrypt位数量相同的列表中,其顺序与已提交的密钥包中的顺序相同。

密钥消息通过 P2P 泛洪传播。节点会转发任何格式良好的密钥消息,该消息指向 ABB 中由(beacon_block_root, slot)标识的承诺,并由 ST 承诺中指定的decryptor_address签名。如果密钥能够解密RevealedTransaction(plaintext_tx, ToB_fee_per_gas)中已提交的密文,且满足hash_tree_root(RevealCommitmentPreimage(ticket.from, ticket.nonce, plaintext_tx, ToB_fee_per_gas)) == ticket.reveal_commitment ,则该密钥有效。此外,解密后的plaintext_tx还满足所需的固定字段( max_priority_fee_per_gas = 0max_fee_per_gas = 0gas_limit = ticket.gas_limit )。解密后的明文发送方和 nonce 无需与 ST 发送方的fromnonce匹配。

指向同一beacon_block_rootcommittee_indexcommit_index密钥,如果字节不完全相同,则构成歧义。歧义密钥的处理方式与 FOCIL 中的 IL 歧义类似:节点会传播其观察到的针对同一目标的前两个不同的签名密钥消息,以表明存在歧义;构建者可以忽略解密者歧义的 ST。如果在验证截止日期前验证者观察到歧义证据,则验证者接受这种忽略。

3.8 PTC 投票

PTC 对与有效载荷广播和 blob 数据相关的 DA 进行投票。为了符合有效载荷的分布式传播(第 4 节),PTC 投票还涉及重建已提交的ExecutionPayload所需的所有数据的可用性:引用的明文事务字节( tx_reference )、引用的 ST 提交以及这些提交引用的底层 ST/捆绑包字节。

因此,构建者有责任确保其在 ABB 中注册的 IL 在 PTC 投票前到达,但如果 IL 不可用,解密者也可以独立传播相应的 ST 字节。关于此主题的更多考虑将在 4.3 节中讨论。借助存储的 IL 重建有效载荷后,PTC 成员会验证有效载荷的根是否正确。他们还会通过投票确认 ABB 已正确指定,这可以从有效载荷中看出。

每个 PTC 成员还可以选择性地广播一个签名位域,该位域指示哪些已安排在下一时隙解密的 ST 承诺在密钥截止时间前已收到有效的密钥消息。该位域使用非零decrypt掩码,按规范顺序(committee_index, commit_index)对调度 ABB 的 ST 承诺进行索引(即,按committee_index递增顺序扫描IL_data ,并按commit_index递增顺序扫描commits[] )。使用 PTC 投票的原因将在 6.3 节中讨论。

构建者和第 n + 1槽位的验证者根据 PTC 投票结果做出关于及时性的决策。为了合并视图,验证者可以在第 n+1 个槽位开始之前冻结他们对 PTC 投票的视图。然后,当某个键的得票率达到例如 45% 到 55% 之间时,构建者可以强制执行其关于及时性的视图(低于 45%,验证者强制执行不及时;高于 55%,验证者强制执行及时,前提是他们在投票截止日期前已经观察到该键)。构建者还可以选择传播一个包含其观察到的投票结果的独立结构,用于合并视图。

3.9 支付和纳入

执行有效载荷的共识表示扩展了st_tickets列表和decrypted_transactions列表(两者均在第 4.2 节中描述)。这些列表用于对 ST 进行计费。

收取 ST 车票费用

st_tickets中的每个 ST 票据都会从ticket.from中扣除ticket.gas_limit * (base_fee_per_gas + ToB_marginal_ranking_fee_per_gas) + ticket.decryptor_fee ,其中ToB_marginal_ranking_fee_per_gas取自调度该票据的 ST 承诺的 ABB(即定义待处理集合的 ABB)。根据实际gas_used ,区块n+1不会退款;如果 ST 未解密,则仅退还decryptor_fee 。如果st_tickets中的任何票据无法完全收费,则该区块无效。

节点通过将ToB_marginal_ranking_fee_per_gas (参见 3.4 节)与 ToB 中排除的最高有效排名 ST 的ranking_fee_per_gas进行比较,来验证 ToB_marginal_ranking_fee_per_gas 设置是否正确。由于 ST 的收费基于其公开可见的gas_limit而非实际使用的 gas,因此承诺时的资金可用性检查是静态的,不依赖于其他交易的执行。这避免了 UPIL 排名机制中因循环依赖问题而导致的保守余额检查。

包括和对解密的ST进行收费

节点观察密钥的发布,并在本地解密ST交易。区块n + 1构建者收集所有能找到的密钥,并生成一个包含其所遵循的有效密钥位域的ABB。验证者要求构建者遵循所有及时有效的密钥,其中及时性通过视图合并或PTC投票确定,如前所述。无法使用已发布密钥解密的ST将被忽略。

节点会根据生成该交易的特定 ST 票据(通过完整的 ST 和相应的密钥)验证每个解密的 ToB 交易。只有当hash_tree_root(RevealCommitmentPreimage(ticket.from, ticket.nonce, plaintext_tx, ToB_fee_per_gas)) == ticket.reveal_commitment且解密的plaintext_tx满足所需的固定字段( max_priority_fee_per_gas = 0max_fee_per_gas = 0 ,且gas_limit = ticket.gas_limit )时,揭示才有效。

处理decrypted_transactions的第一步是退还所有未解密 ST 的ticket.decryptor_fee 。发送方通过ticket_index中缺少索引来识别(参见 4.2 节)。已decrypted_transactionsdecryptor_fee将记入关联的ticket.decryptor_address 。协议最后从ticket.from中扣除并销毁 ToB 费用ticket.gas_limit * ToB_fee_per_gas 。如果ticket.from不足以支付此费用,则该交易不予处理。

如果用户提交的多个 ST 的解密plaintext_tx具有相同的from并且 nonce 是连续的,则应确保ToB_fee_per_gas与 nonce 兼容,因为解密的交易主要按ToB_fee_per_gas排序,而执行仍然遵循每个发送者的 nonce 顺序。

3.10 无条件 IL 版本

对于无条件 IL 版本,我们进行了一些修改,详情如下。其理念是实现“无条件 FOCIL”,遵循 FOCIL 的诸多设计原则,但允许每个包含者的列表都是无条件的。除了可以像 LUCID 那样实现加密内存池之外,它在像 EIP-7999 那样的多维费用市场中也很有帮助。关于无条件 FOCIL 的更多细节和分析,除本文概述的内容外,将在后续文章中另行介绍。

UIL 溢出

ToB_marginal_ranking_fee_per_gas已从 ABB 中移除。每个 IL 至少可以消耗ST_gas_min_per_IL的 ToB gas,该数值计算公式为ST_gas_min_per_IL = ToB_gas_limit // IL_COMMITTEE_SIZE实际可以消耗的 ToB gas 量取决于其他 IL max_bytes_per_inclusion_list消耗量。max_bytes_per_inclusion_list 可以设置成允许 IL 填充调用数据,使其不超过ST_gas_min_per_IL或更低。ST 承诺的顺序,以及 ST 在捆绑包中的顺序,定义了 IL 指定的优先级顺序。构建器会不断增加 IL 可以消耗的最大 gas 量,直到所有gas_obligation条目的总和超过ToB_gas_limit ,然后降低该最大值以移除最后添加的交易。因此, gas_obligation条目的(未去重的)总和必须在ToB_gas_limit范围内,就像以前一样。

验证者会检查每个及时观察到的 ST 承诺是否都正确指定了gas_obligation ,其依据是所有gas_obligation条目中的最大值和已发布的decrypt位。每个解密者也会验证其自身承诺的这一点。对于decrypt = 1的交易,他们会释放密钥,使得 ST gas 限制的总和等于gas_obligation

无溢出

在无条件IL版本(无溢出)下,每个IL的上限为ST_gas_limit_per_IL = ToB_gas_limit // IL_COMMITTEE_SIZE以ToB gas为单位)。由于此上限是每个IL固定的,因此可以从ABB中省略gas_obligation字段。考虑到包含者仍然可能产生歧义,因此在ABB中保留commitment_root似乎是合理的。

UIL 与 UPIL 一起

另一种可行的设计是让 IL 无条件地包含ST_gas_limit_per_IL = ToB_gas_limit // IL_COMMITTEE_SIZE ,并允许根据 UPIL 包含额外的交易。然后,超出限制由max_bytes_per_inclusion_list限制。

4. 分布式有效载荷传播

有效载荷依赖于对预先传播的交易数据和先前 ST 承诺的引用,而不是在广播的有效载荷中重复交易字节。共识表示扩展了st_ticketsdecrypted_transactions (第 4.2 节),但常规transactions列表仍然像当前执行有效载荷一样,是完整的交易字节列表。通过 P2P 发送的网络表示有所不同,仅用作临时优化。

4.1 网络表示

引入了一种轻量级有效载荷广播。除了携带非包含列表来源的交易的完整交易字节外,分布式执行有效载荷信封DistributedExecutionPayloadEnvelope还包含一个指向节点预期已拥有(或能够从规范包含列表获取)的交易的指针列表。每个ILTransactionPointer还指定了包含列表交易在区块最终transactions列表(共识表示)中的位置。

class ILTransactionPointer ( Container ):committee_index: uint8 # 0..IL_COMMITTEE_SIZE-1 tx_index: uint16 # index into the canonical IL body for this committee_index position: uint32 # index in the final full transactions list

有效载荷的网络表示不涉及ST。构建者生成的ABB足以确定性地重构ST票据和解密后的ST。具体而言,调度ABB中的ST承诺(其decrypt位由构建者指定)标识了有效载荷包含的ST票据及其顺序。同样, key_adherence位标识了应包含的解密后的ST,其顺序由ToB费用决定。有关恢复的更多细节将在4.5节中讨论。

因此,具体来说, DistributedExecutionPayloadEnvelope镜像了ExecutionPayload标头字段(重新计算block_hash所需的一切),但依赖于指针( ILTransactionPointer )来获取来自 IL 的交易,并依赖于 ABB 来重建 ST 票据和解密的 ST。

4.2 共识表示

执行有效载荷的共识表示扩展了两个附加列表: st_ticketsdecrypted_transactions

st_tickets

st_tickets是一个已签名 ST 票据列表,这些票据在区块处理开始时计费,对应于一组待处理的(即尚未计费的)ST 承诺。构建者必须将每个设置了decrypt=1的 ST 票据包含在其 ABB 的 ST 承诺中。在恢复机制下(第 4.5 节),构建者只需包含在相关祖先 ABB 中经过确定性过滤(去重、nonce 可行性、计费性)后剩余的、与decrypt = 1 1 的待处理 ST 承诺对应的 ST 票据即可。

st_tickets列表具有规范顺序:首先按committee_index递增扫描调度 ABB 的IL_data ,然后按commit_index递增扫描commits[] ,最后(对于捆绑包)按tx_index递增扫描条目,并将确定性过滤后剩余的每个条目的 ST 票据包含在内。

decrypted_transactions

` decrypted_transactions是一个列表,其中包含当前区块中已解密的 ToB 交易。每个条目包含(ticket_index, plaintext_tx, ToB_fee_per_gas) ,其中ticket_index是指向调度当前正在解密的交易的区块(通常是前一个区块)的ticket_index st_tickets的索引。`ticket_index` 在处理区块时作为轻量级指针包含在内,如果同一个ticket_indexdecrypted_transactions中出现多次,则该区块无效。当两组st_tickets (参见 4.5 节)指向同一个decrypted_transactions列表时, ticket_index编号方式为:后出现的st_tickets的索引从len(st_tickets)开始。

仅当hash_tree_root(RevealCommitmentPreimage(t.from, t.nonce, plaintext_tx, ToB_fee_per_gas)) == t.reveal_commitment for t = st_tickets[ticket_index]时,该条目才有效。ToB 的排序必须按照ToB_fee_per_gas递减的顺序进行,如果 ToB_fee_per_gas 仍然为零,则按ticket_index顺序打破平局,并跳过因 nonce 顺序问题而无法执行的条目。

共识表示的性质

常规transactions列表仍然是完整交易字节的列表,与当前的执行有效载荷格式相同。信标区块包含一个SignedExecutionPayloadBid ,用于提交完整的有效载荷,特别是通过其block_hash ,如 EIP-7732 中所述。基于指针的有效载荷格式仅用作临时网络优化:节点在本地重建完整的ExecutionPayload ,计算/验证生成的block_hash与已提交的头部是否匹配,然后执行层客户端像往常一样执行并存储完整的交易数据。同步操作基于完整的区块;指针永远不会成为共识对象的一部分。

4.3 IL 在 ABB 中的根本承诺,以防止含糊其辞

包含器可能会在区块构建前后传播多个 IL。构建器在提交有效载荷之前可能只会观察到其中一个 IL,并决定包含来自该 IL 的交易。这存在一个风险,即网络上的节点观察到的 IL 与包含器不同,从而导致构建器引用的 IL 出现歧义。因此,构建器通过在 ABB 中包含每个包含器的 32 字节 SSZ IL_root来定义每个包含器的唯一“规范”IL。具体来说,如果分布式有效载荷通过ILTransactionPointer(committee_index=i, ...)引用了委员会成员i的任何交易,则包含在信标区块中的 ABB 必须包含一个非空的iIL_root

如果构建器未从包含器中观察到 IL,则该条目将留空。构建器可以自由地在其代码块中包含它不会引用的已观察到 IL 的根目录,以便在揭示有效载荷内容之前对其进行混淆,但也可以不这样做。

节点被指示始终转发规范的包含请求(即使存在歧义)(同时转发一条额外的包含请求以指示歧义)。如果节点已经转发了来自同一包含者的两个包含请求,并且得知第三个包含请求是规范的,则在收到该包含请求时也会转发它。如果构建者观察到歧义,则会在发布竞价后重新播种其规范的包含请求。仍然可以对包含者因歧义而进行惩罚,并且鉴于包含请求的动态属性(DA)的重要性增加,在动态支付计划(DPP)下进行惩罚似乎更为合理。

4.4 有效载荷重建

复杂性都封装在 CL 客户端中。工作流程如下:

  1. IL 接收: CL 客户端通过 P2P 接收 IL,并将其存储在以IL_root为键的本地缓存中。
  2. 有效载荷接收:它接收SignedDistributedExecutionPayloadEnvelope ,验证构建者签名,并检查其(slot, beacon_block_root, builder_index, block_hash)是否与信标块中提交的SignedExecutionPayloadBid匹配。
  3. 分辨率和重建:
    • 客户端通过以下方式解析所有ILTransactionPointer条目:在信标区块的 ABB 中查找committee_index对应的规范IL_root ,从其缓存中获取该 IL(如果缓存中不存在则请求获取),并读取tx_index处的完整交易。它通过将每个 IL 交易插入到最终列表中的唯一position ,将这些交易与信封的完整transactions合并。
    • 客户端根据调度 ABB(通常是当前时隙的 ABB;在恢复模式下,是未计费的祖先 ABB)确定性地构造st_tickets 。它按规范顺序扫描IL_datacommits[] ->(bundle tx_index ),应用确定性过滤规则(去重、nonce 可行性、计费性),获取相应的SealedTransaction字节,并为每个剩余条目提取 ST 票据。
    • 客户端根据当前区块待解密的 ST 承诺确定性地构建并排序decrypted_transactions :在正常操作中,这些承诺是父区块的已安排 ST 承诺;在恢复模式下,这可能包括来自最近完整祖先区块和第一个空区块的待解密承诺(参见 4.5 节)。对于每个具有有效已发布密钥消息且 ABB 遵循该消息的承诺,客户端进行解密以获得RevealedTransaction(plaintext_tx, ToB_fee_per_gas) ,识别相应的已收费票据t ,并验证: hash_tree_root(RevealCommitmentPreimage(t.from, t.nonce, plaintext_tx, ToB_fee_per_gas)) == t.reveal_commitment 。然后,客户端创建一个decrypted_transactions条目,其中包含tst_tickets中的ticket_index 。最后,它按ToB_fee_per_gas递减的顺序排序,按ticket_index打破平局,并按该顺序应用每笔交易的支付能力检查(删除任何未通过检查的条目)。
  4. 验证:客户端计算结果block_hash并将其与信标区块中的SignedExecutionPayloadBid进行验证。
  5. 执行:客户端将完全成型的ExecutionPayload传递给引擎 API( engine_newPayload )。
  6. PTC 投票:节点持续获取缺失的 IL/ST 字节/密钥,并在新数据到达时重试重建。PTC 成员只有在T_4时刻完全重建有效载荷并验证了block_hash后,才会投票“及时”;否则,投票“不及时”。

4.5 被拒绝有效载荷下的恢复

如果信标区块的ABB为其ST承诺指定了正确的gas_obligation条目,所有gas_obligation条目的总和在ToB_gas_limit范围内,并且发送者的ST承诺和解密密钥可用,则发送者有权将其解密后的交易包含在下一个区块中。但是,在解密密钥发布后,有效载荷n可能会被拒绝,这并非发送者或解密者的过错。在这种情况下,下一个有效载荷必须包含已安排在有效载荷n的解密ST 以及在时隙n中已发布密钥且已安排在n+1ST

具体来说,一个数据块的解密序列是指满足以下条件的序列:

  • 具备ST字节和密钥,
  • 列于正确指定的ABB中,其中该ABB
    • 不是当前插槽的ABB,
    • 尚未将其解密的 ST 承诺纳入链上。

因此,当一个区块为空(没有有效载荷)时,下一个有效载荷必须包含该空区块本应包含的已解密存储转移(ST),以及该空区块在ABB中提交的(现已解密的)ST。恢复有效载荷不能提交新的ST(如Potuz在此处建议的那样),而是必须使用key_adherence位来指示空区块的ST提交当前是否可用(字节+密钥)。这些位也标记了ST票据,在恢复过程中,这些票据必须与已解密的ST一起放入同一个有效载荷中。如果该区块未能包含解密的ST以致链无法恢复,则该区块也必须被投票判定为空,并且恢复的责任将再次落到下一个有效载荷上。

在基准规范中,解密的ST最多分配到1/4的gas限制。这确保了当某个有效载荷丢失时,下一个有效载荷可以包含两组解密的ST,最多消耗该区块1/2的gas限制。

5. 揭示 LUCID 中的可选性

在密封交易承诺-披露机制下,一个潜在的问题是披露选择权。一些密封交易将被用于“回溯”,例如,CEX价格的变化。

来源
免责声明:以上内容仅为作者观点,不代表Followin的任何立场,不构成与Followin相关的任何投资建议。
喜欢
52
收藏
12
评论