斑點流
由@QED 、 @fradamt 、 @Julian撰寫,特別感謝@soispoke 、 @aelowsson和@casparschwa的寶貴意見。
我們提出blob 流式傳輸:將 blob 數據的連續採樣預傳播作為協議內一級機制,與現有的關鍵路徑 blob 通道並列。預傳播目前已通過 blob 池實現,但由於缺乏數據可用性採樣且保證較弱,因此無法安全地擴展吞吐量。Blob 流式傳輸引入了一種票據機制來限制預傳播的速率,從而允許在不擴展關鍵路徑的情況下可靠地將採樣擴展到整個時隙——因此緩解了自由選項問題。除了擴展性之外,該機制還實現了 blob 交易的完全抗審查性。
介紹
定義:JIT 和 AOT 數據塊
如果一個數據塊在需要其可用性的時隙的關鍵路徑上傳播,我們就稱該數據塊為JIT (即時)數據塊;否則,我們就稱該數據塊為AOT (提前)數據塊。
以太坊的數據可用性機制最初是圍繞即時數據塊(JIT blob)設計的,並在共識層(CL)的關鍵路徑上進行傳播。該機制已通過PeerDAS進行了升級,以支持數據可用性採樣。然而,執行層(EL)的數據池實際上通過提供預傳播途徑,實現了實時數據塊(AOT blob)的實現。
儘管 JIT blob 原則上能夠實現 AOT blob 無法提供的功能——例如,為了與 L1 層實現同步組合,需要同時創建數據塊和 blob——但實際上,目前所有 blob 的使用都是 AOT 的。因此,blobpool 使得工作能夠脫離關鍵路徑,從而分散帶寬使用。然而,這種預傳播缺乏可靠的保證,也沒有數據可用性採樣,因此其帶來的擴展性優勢有限。
圖 1.時隙時間線可視化 JIT/AOT 定義。AOT 數據塊(橙色)在關鍵路徑之前傳播;JIT 數據塊(黃色)在需要其可用性的時隙的關鍵路徑內傳播。無論傳播何時以及如何發生,驗證人員都會驗證所有數據塊的可用性。
本文提出了一種名為Blob 流式傳輸的機制:將 AOT Blob 作為一級通道,採用基於票證的機制——用戶可以提前購買 Blob 的傳播權——與按現貨價格計費的 JIT 通道並存,後者可以被視為當前的私有 Blob。流式傳輸通道採用疊加式設計:AOT Blob 在關鍵路徑之前進行預傳播,而 JIT Blob 在關鍵路徑內進行傳播。至關重要的是,基於票證的速率限制機制能夠有效控制傳播負載,從而確保預傳播的可靠性——一致的節點視圖和清晰的 DoS 防護能力。此外,由於傳播權與可用性判定相分離(與 Blob 池不同),因此可以安全地在其上疊加數據可用性採樣,將採樣窗口擴展到整個時隙,從而實現 Blob 吞吐量的擴展。因此,所提出的機制可以被視為 Blob 池採樣機制(例如垂直分片、水平分片)的替代方案,能夠在實現相同吞吐量擴展的同時,提供以下優勢:
- 對用戶而言:強大的抗審查保證、提前獲取 blob 空間的可能性、放寬 blob 交易的內存池限制。
- 協議:明確的負載界限和更小的關鍵路徑傳播窗口,從而緩解自由期權問題。
圖 2.時隙的雙通道視圖。AOT 數據塊在關鍵路徑之前預先傳播,並隨時間推移而擴散;JIT 數據塊與有效載荷一起在關鍵路徑內傳播。驗證器會驗證所有數據塊的可用性。
基於票證的設計可以同時支持 JIT 和 AOT blob。但是,我們選擇保留現有的 JIT 路徑,其中容量按現貨價格定價,而不是通過票證分配,以適應不涉及提前容量規劃的用例,例如(純粹的) 基於 blob 的彙總,以及最終 L1 本身對 blob 的使用( blobs 中的塊, 原生彙總)。
在深入探討機制的具體細節之前,讓我們通過分析 AOT 和 JIT 數據塊的供需情況,來闡述引入 AOT 通道的必要性。
協議視角(供應方)
系統提供的 AOT 數據塊吞吐量明顯高於純 JIT 吞吐量,因為 JIT 數據塊必須在受以下因素限制的狹窄時間窗口內傳播:
- 下一個提案方和建設方需要在採取行動前確定可用性。
- 自由選擇權問題,隨著我們延長這個窗口期,這個問題會變得越來越嚴重。
這會在傳播窗口期間造成帶寬激增,而在該時隙的其餘時間裡帶寬則基本處於閒置狀態。通過AOT數據塊的預傳播,傳播會擴展到更大的時間窗口(見圖2),從而平滑帶寬消耗並避免瓶頸。有效的預傳播可以實現帶寬在容量範圍內的穩定使用,進而提高吞吐量。
圖 3. JIT 數據塊與 AOT 數據塊在不同時隙內的帶寬變化示意圖。JIT 數據塊需要在較短的時間段內消耗帶寬,導致帶寬消耗波動較大;而 AOT 數據塊的傳播時間較長,帶寬消耗較為平滑。
用戶視角(需求方)
JIT blob 的主要應用場景是與 L1 實現同步組合,這需要 基於序列的驗證以及實時證明。相比之下,外部序列化的 rollup 以及帶有預確認的基於序列的 rollup (例如Taiko )可以使用 AOT blob。
也可能存在一種基於混合的彙總設計,它結合了預確認和同步可組合性,其主要方式是在 L1 時隙的大部分時間裡使用預確認,但在 L1 區塊生成期間切換到基於模式,從而實現該期間的同步交互。這種彙總可能混合使用 JIT 和 AOT 數據塊,其中在 L1 區塊生成期間需要使用 JIT 數據塊,以實現與 L1 的同步交互。
至關重要的是,JIT blob 對於 L1 也變得非常重要,因為我們正迅速邁向未來,屆時 zkEVM + DAS 將通過把有效載荷放入 blob 中來擴展 L1 本身,本質上是將 EL 變成有效性彙總。
即使考慮到這些用例,也很難準確預測未來 JIT 與 AOT 數據塊的需求將如何變化。我們知道同步可組合性是有益的,但究竟有多大益處?我們知道它成本很高,但究竟有多高?我們知道 L1 需要 JIT 數據塊,但它會佔用總數據塊吞吐量的多少比例?
我們認為,無需精確預測這兩種數據塊類型未來的需求,即可確定是否值得在協議中引入更多用於處理 AOT 數據塊的機制。只要對 AOT 數據塊存在顯著需求(這似乎很有可能,因為並非所有彙總都希望完全基於數據塊,即使是超大規模的 L1 層也不太可能消耗掉所有數據塊吞吐量),所有數據塊用戶都能從將 AOT 數據塊吞吐量轉移到其專屬通道中受益。如上所述,AOT 數據塊可以利用當前未使用的關鍵路徑之外的帶寬。允許它們使用這些資源可以釋放關鍵路徑,供 JIT 數據塊使用。這意味著引入 AOT 數據塊不僅有利於使用它們的用戶,也有利於 JIT 數據塊的用戶,因為他們可以獲得更多受限的關鍵路徑資源。
設計
現在我們從現有的 blobpool 開始,逐步構建完整的雙車道架構,來描述該設計。
回顧:blobpool 門票
目前,預傳播是通過EL blobpool進行的,但協議內部沒有任何機制來分配傳播帶寬。隨著blob吞吐量的增長,blobpool必然會分片——它沒有全局方法來限制流入,因此只能在節點層面進行局部控制。此外,blobpool無法從數據可用性採樣中獲益,而且引入採樣也極具挑戰性:blobpool的安全模型依賴於僅傳播有效且可包含的事務,而採樣節點無法獨立完全驗證blob的可用性,因此在採樣時很難確保這一點。
圖 4.當前 blob 池中的預傳播。請注意,blob 事務必須與完整的 blob 數據同步傳播,因為後者的可用性是前者有效性的前提條件。
關於 blob 票務機制已有大量文獻(參見此處、此處、此處),這些機制旨在拍賣 blob 傳播的權利。最近,有人提出了blobpool 票務機制,作為朝著這個方向邁出的一步,它增強了 blobpool,以確保 blob 在 blobpool 中預先傳播時能夠抵禦拒絕服務攻擊,並且即使與 blobpool 採樣機制一起實現,也能保持這種保證(參見垂直分片內存池和EIP-8070:稀疏 Blobpool )。
為了在 Blob 池中提交和傳播 Blob,提交者需要持有有效的票據,該票據可通過與指定的票據合約交互獲得(例如,通過實施第一價格拍賣)。這將確保通過 Blob 池傳播的 Blob 數量受到限制,並公平地分配有限的空間。由於 Blob 池的准入現在由預付費票據控制,而不是通過有效性檢查,因此也可以安全地引入抽樣機制——節點不再需要驗證 Blob 的完全可用性來決定是否傳播交易。
圖 5.使用 blobpool 票證擴充 blobpool。
Blob 票
Blob 票證進一步擴展了票證概念,將預傳播移至變更列表 (CL),並將其更深入地集成到數據可用性管道中。這與 Blob 池票證主要有兩點不同:
- 對於 AOT blob,用戶只需一張票券即可將 blob 添加到鏈上。特別地,AOT blob 交易在被添加到鏈上時無需支付 blob 基本費用,只需支付常規 gas 費用。因此,票券被稱為blob票券而非blobpool票券——您購買的實際上是 blob 空間,而不僅僅是 blobpool 空間。從協議的角度來看,這是因為傳播過程才是真正消耗稀缺帶寬資源的地方。(JIT blob 將在後面討論,並且仍然採用現貨價格。)
- 傳播過程轉移到 CL ,重用其已開發的用於 DA 採樣的基礎設施,否則需要在 EL 上重複開發。此外,DA 採樣是共識機制的根本組成部分,因為 DA 是將區塊導入 fork-choice 的前提條件。目前,我們通過
getBlobs引擎 API 調用將 EL 預傳播和 CL 可用性強制執行整合在一起。
工單工作流程如下:
- 購買門票:通過向門票合約發送交易,用戶可以獲得在未來某個時間傳播 blob 的權利。
- 傳播:
- Blob :用戶使用票據(在指定時間)通過 CL 採樣基礎架構推送 blob 數據。
- Blob tx :同樣使用票據,blob tx(不帶 blob 數據)會進入常規內存池。
- 包含性和可用性強制執行:當包含 blob 事務時,證明者會強制執行關聯的 blob(由
blob_tx.versioned_hashes標識)的可用性,就像今天一樣。
圖 6.用戶使用 blob 票據的工作流程。用戶獲取票據,在 CL 上傳播 blob,並將 blob 事務提交到 EL 內存池。一旦 blob 事務被包含在數據塊中,其功能與現在完全相同,數據塊的有效性取決於相關 blob 的可用性,從而為用戶提供嚴格的可用性保證。
每張票都賦予傳播權:
- CL 上的一個斑點(傳播方向右側)
- 在EL上可以進行多筆blob交易。例如,最多可以進行16筆交易,這與Geth blobpool當前允許的最大blob交易數(
maxTxsPerAccount)以及Geth mempool中常規交易的默認最大保證mempool槽位數(AccountSlots)相匹配。但需要注意的是,這裡的限制是針對每張票券的,而不是針對每個賬戶的。
這兩項權限是獨立的——CL 和 EL 各自獨立跟蹤票據的使用情況。這意味著票據持有者可以並行地在 CL 上傳播其 blob 數據,並在 EL 上傳播其 blob 交易,而無需各層之間進行協調。允許使用同一張票據在 EL 內存池中傳播多筆 blob 交易,使得用戶無需購買新票據即可重新提交交易,例如,當基礎費用變更導致交易失效時。
用戶須知:將 blob 交易的傳播與票據(而非其有效性)掛鉤,可以讓內存池擺脫目前對其施加的嚴格規則。具體來說,同一個地址可以並行排隊多個 blob 交易,因為一個交易導致其他交易失效的情況並不重要——再次強調,傳播權限取決於票據,而非有效性!這對 blob 提交者來說是一個切實的痛點,如果不加以解決,隨著各個 L2 交換機吞吐量的增加,這個問題只會愈演愈烈,因為每個交易的 blob 數量上限會導致每個 L2 交換機的交易速率增加。
混合設計:AOT + JIT
根據我們目前討論的內容,AOT 和 JIT 在結構上原則上可以相同:我們可以設計一個系統,使所有容量(包括關鍵路徑容量)都通過票券出售。在這種系統中,JIT 和 AOT 的區別僅僅在於傳播時間。
這種僅使用票券的設計對於能夠提前規劃吞吐量併購買票券的參與者(例如外部排序彙總的運營商)的 blob 需求來說非常有效。然而,一旦需求包含沒有規範票券管理器的開放式用戶流,這種設計就會失效:用戶不能被期望提前獲取票券,而默認將構建者設置為中間票券會造成庫存、資金和中心化方面的壓力。在需求高峰期,即使網絡仍然具備關鍵路徑傳播能力,票券庫存也可能成為瓶頸。這不僅適用於最終使用 blob( blob 中的 blob )的 L1 本身,也適用於基於 blob 的彙總。
因此,本文最終提出的架構明確採用了混合架構,引入了基於票證的AOT blob以及按現貨價格計費的JIT通道。最終用戶可以通過交易直接支付關鍵路徑blob資源(JIT blob,通過blob基礎費用),而計劃流程(AOT blob)可以使用票證(並從中受益)。在有效負載中,這種分離通過引入兩個版本化哈希列表來明確體現:
-
jit_versioned_hashes:用於構建者即時提交的 blob。它們與有效負載一起傳播(採樣),並立即支付其資源費用(通過設置為等於\text{bf}^{AOT} bf A O T的 JIT blob 基本費用 - 有關更多詳細信息,請參閱票據合同部分),就像今天的 blob lane 一樣。 -
aot_versioned_hashes:已預先隨票證傳播的 blob,現在被聲明為可用。購買票證時已支付 blob 資源費用,無需立即付款。
這兩個列表都將有效載荷的有效性取決於可用性:所有與jit_versioned_hashes和aot_versioned_hashes對應的 blob 都必須可用,有效載荷才能成為規範有效載荷。區別僅在於傳播資源的付費和使用方式。
總而言之,網絡傳播資源被明確地分為兩類:關鍵路徑和非關鍵路徑。不同的市場分別管理這兩類資源的分配:預先進行的鏈上門票拍賣用於傳播前的容量分配,而關鍵路徑傳播則採用即時現貨市場,在該市場中,構建者擁有最終的分配權。
JIT 機制與當前的 blob 通道本質上相同:關鍵路徑傳播、構建者驅動的包含,以及在包含時通過 blob 基本費用進行即時支付。但需要注意的是,由於 JIT blob 沒有 blob 池預傳播,用戶必須直接將他們的 blob 發送給構建者。因此, JIT blob 對應於當前的私有 blob。AOT機制是新增的,它提供了一條具有不同特性的額外路徑:提前購票、預傳播(因此容量更高),以及我們將看到的抗審查性 (CR) 保證。對於任何可以預傳播的 blob,此路徑都將成為默認路徑。
JIT 與 AOT 產能對比
混合設計中出現的一個根本問題是資源分配:我們應該將多少網絡容量用於傳播 Blob 數據,多少用於 AOT Blob?我們提出了一種設計方案,其中容量約束由三個參數控制,這些參數的設置方式與目前 Blob Gas 目標和限制的設置方式非常相似:
- B_1 B 1 ( JIT max ):每個時隙的 JIT 代碼塊最大數量。這是一個上限,取決於我們願意完成關鍵路徑的時間長短——以及我們相應地可以容忍的自由選擇窗口的大小。
- B_2 B 2 ( blob (JIT + AOT) max ): 每個時隙的最大 blob 總數,是 JIT + AOT 的聚合限制。該值由網絡在一個時隙內的總傳播吞吐量決定。
- R \leq B_1 R ≤ B 1 (保留的 JIT 容量):JIT 容量的一部分,受到保護,免受 AOT 使用。
這些參數對給定的時隙n導出以下規則:
- AOT 門票銷售:最多可售出B_2 - R B 2 − R個未來時段的門票。由於R R已預留給 JIT,因此最多隻能提前安排B_2 - R B 2 − R個區塊。
- JIT 容量:如果已為時隙n調度了a \leq B_2 - R a ≤ B 2 − R AOT blobs,則最多\min(B_1,\, B_2 - a) min ( B 1 , B 2 − a )可以包含 JIT 塊。這保證了至少R R JIT 容量,並允許 JIT 在 AOT 需求較低時擴展到B_1 B 1 。
B_2純粹是一個技術約束,反映了網絡在一個時隙內的總傳播預算。B_1則需要更大的靈活性:它受時隙結構的限制,但可以設置得更低以限制空閒選項窗口。然而, B_1對 JIT與AOT並沒有預設要求——所有超出R R 的容量都是共享的,因此較高的B_1值只是允許 JIT 在 AOT 需求較低時進一步擴展到共享池中。
最有趣的設計選擇是R R。未預留容量B_2 - R B 2 − R是一個共享池,可供 AOT(通過票券)和 JIT(如果 AOT 需求有餘量)使用。將R R設置得太低可能會導致 JIT 需求無法得到滿足,尤其是在 L1 本身依賴於 JIT 數據塊的情況下,這個問題更為突出。將R R設置得太高會將原本可以作為票券出售的容量轉移到僅限 JIT 使用的路徑中;預留容量永遠不會完全丟失——原則上任何 AOT 活動都可以使用 JIT 數據塊——但用戶將被迫直接通過構建者進行操作,並失去協議的抗審查保證。
基準定價
作為基準,現有的二進制大容量費用更新機制可以照常應用。在規定的限制條件下, \min(B_1,\, B_2 - a) + B_2 - R min ( B 1 , B 2 − a ) + B 2 − R個斑點可以在槽位中出售, \min(B_1,\, B_2 - a) min ( B 1 , B_2 − a )作為當前時隙的 JIT blobs , B_2 - R作為未來時隙的票證。因此,如果時隙中調度的 AOT blobs 數量較少,則最多可以售出B_1 + B_2 - R ( B_1 + B_2 − R )個blobSchedule.target可以位於B_2\times2/3 ( B_2 × 2 / 3) , blob_gas_used由時隙中售出的 JIT blobs 和 AOT 票證總數乘以GAS_PER_BLOB計算得出。實際上,我們還會向blobSchedule添加新變量B_1 (B_1 ) 、 B_2 (B_2 )和R ( R) ,這些變量施加了整體機制所需的更細粒度的容量約束。
提高吞吐量的票務合同和定價機制
如前所述,購買車票時,需要向專用車票合約發送交易信息。該合約有兩個主要功能:輸出新車票以及更新已使用或過期的舊車票。車票合約根據上述容量限制輸出 AOT 車票。車票價格根據 AOT 基本費用\text{bf}^{AOT} bf A O T設定,該基本費用由目標 AOT blob 容量通過 EIP-1559 類型的控制器機制設定。如前所述,JIT 的基本費用等於\text{bf}^{AOT} bf A O T。
具體而言,這意味著如果售出的票數超過或少於目標票數,則從時隙i到時隙i+ 1的bf ^{AOT}會增加或減少。其中,目標票數是 AOT 區塊容量的函數,即B_2 - R , AOT_target = B_2 - R。基本費用的更新規則可以與EIP -1559 中使用的規則完全相同:
$$\text{bf}^{AOT} {i+1} = \text{bf}^{AOT} {i} \times \Big(1 + \frac{1}{8} \times \frac{\text{AOT} {i} - \text{AOT} {\text{target}}}{\text{AOT}_{\text{target}}}\Big)$$
其中\text{AOT}_{i} AOT i是在i i號售票處售出的票數。
每筆票務交易需要指定四個變量: base_fee 、 auction_bid 、 number of tickets (合約可從中扣除auction_bid_per_ticket = auction_bid / number of tickets 、 base_fee_per_ticket = base_fee / number of tickets )以及sender_adress指定接收票務的地址)。票務交易要獲得票務,必須滿足條件base_fee_per_ticket ≥ bf^{AOT} ≥ bf A O T。交易按auction_bid_per_ticket降序排列,並分配票務,最多分配2×(B_2 - R) 2 × ( B 2 − R ) 。
如果出現超額需求(即,如果用戶在給定時段內嘗試購買的票數總數超過2 × ( B₂ - R )的限制),則成功獲取票券的交易的base_fee和auction_bid將被銷燬,而未能獲取票券的交易的相應值將被退回給發送方地址。回想一下,AOT blob 的吞吐量容量為B₂ - R。因此,所有票券(由於我們將限制設置為容量的兩倍,因此數量不超過B₂ - R )對應於有序交易列表底部的交易,在下一個時段內都將有效。例如,假設B₂ - R = 5 ,且時段N中競標者的順序如下:Alice: 3張票,Bob: 4張票,Charlie: 3張票。那麼,Alice 將在時段N+1收到3張票,Bob 將在時段N + 1收到2張票。對於N+1 N + 1和2 2 號槽位N+2 N + 2 ,查理將收到3 3 張N+2 N + 2 號槽位的票。在需求不超過2\times(B_2 - R) 2 × ( B 2 − R )的情況下,每次交易都會銷燬\text{bf}^{AOT}\times bf A O T × number of tickets對應的值。
最後,需要注意的是,沒有理由只出售下一個時段的門票。我們也可以考慮出售在時段N中有效的門票,這些門票適用於時段N+ k 。能夠提前獲取門票對 L2 系統來說意義重大,因為 L2 系統可以利用這一點,在預先了解特定數據塊價格的情況下,更準確地為自己的交易定價。至於具體細節——例如 k應該多大?用戶是否應該能夠從一系列選項中指定他們想要的時段門票?——等等,目前仍是一個開放性問題。
抵制審查
AOT通道的一項關鍵承諾是確保blob交易的抗審查性。票證允許我們識別一組受限的blob,其可用性可由委員會確定,從而確保它們能夠被納入協議——每張票證都可以被視為授予單個blob的納入列表提議者角色。然而,僅靠blob票證的基礎系統並不能完全實現這一目標。接下來,我們將指出這一差距,展示如何通過DA合約在鏈上記錄可用性來解決這個問題,並在此基礎上構建端到端的納入保證。
blob票據的侷限性
Blob 票據是一項意義重大的改進,但在抗審查方面仍存在缺陷。FOCIL 是一種抗審查機制,它允許委員會保證某些交易(例如從內存池中提取的交易)被納入鏈表。然而,Blob 交易的有效性取決於其可用性。由於可用性沒有記錄,因此無法強制執行 Blob 交易的納入。根本原因在於可用性只能在 Blob 交易被納入鏈表的那一刻確定:即使 Blob 已經傳播開來,並且所有人都對其進行了採樣,也沒有記錄表明哪些 Blob 可用,而驗證可用性的唯一方法是將 Blob 交易納入鏈表。
錄音權限:DA合同
一種簡潔的解決方法是獨立於 blob 事務包含情況來記錄可用性。我們引入兩項更改:
- 有效載荷可以包含獨立於 blob 交易的版本化哈希值。構建器可以包含一個 blob 版本化哈希值列表,用於聲明其可用性,即使同一區塊中沒有相應的 blob 交易。
- 可用性記錄在 DA 合約中。在每個區塊開始時,系統調用會將有效載荷中的版本化哈希值記錄到 DA 合約中。這樣就創建了一個記錄,顯示哪些 blob 可用,節點(作為 mempool 和 FOCIL 參與的一部分)以及 EVM 內部都可以查詢該記錄。
強制可用性機制與現在完全相同:認證者只會對數據塊可用的區塊進行投票。如果構建者為不可用數據添加了版本化哈希值,則該區塊將無法獲得認證。唯一的區別在於,版本化哈希值現在可以直接來自有效負載,而不僅僅是來自數據塊交易。
此外,我們調整了鏈上 blob 交易的行為以使其與合約兼容。Blob 交易的有效性仍然取決於相應 blob 的可用性,但為了確保這一點,我們現在會在驗證blob_tx時檢查 DA 合約中blob_tx.versioned_hashes的可用性。特別地,如果blob_tx.versioned_hashes已在之前的區塊中記錄為可用,則我們不再要求將其包含在payload.versioned_hashes中。可用性只需確認一次。
注意:由於 DA 合約可在 EVM 內查詢,常規交易也可以檢查 blob 的可用性,例如,合約可以根據特定 blob 是否可用來調整其邏輯。Blob 交易可以繼續作為主要接口,但 DA 合約為與可用性進行更靈活的交互打開了大門。
圖 7.可用性記錄與強制執行,以及 blob 交易有效性。構建器包含一個版本化哈希列表,該列表指向可用的 blob,其可用性通過證明來強制執行。版本化哈希記錄在一個專用的 DA 合約中,blob 交易驗證會檢查該合約中的可用性。
此外,我們調整了內存池中 blob 交易的處理方式,以便內存池能夠利用合約中的可用性信息。現在,如果滿足特定條件,blob 交易就可以在內存池中傳播。
任何一個:
1.可用性已記錄:所引用 Blob 的可用性已記錄在 DA 合約中,或者
2.發送方持有未使用的票據:發送方擁有尚未在 EL 上使用的有效票據(節點在本地可以看到)。
換句話說,只有當 blob 交易在可用性記錄之前傳播時(例如與 blob 本身並行傳播),才需要票證。可用性記錄後,blob 交易可以像普通交易一樣,按照正常的內存池規則進行傳播。這也解決了基礎票證系統的一個實際限制:如果沒有 DA 合約,一張票證只能提交有限的 blob 交易,並且內存池必須將 blob 交易的傳播限制在票證持有者範圍內。可用性記錄後,這些限制就消失了——例如,重新提交不再需要特殊處理。
圖 8.基於 DA 合約的 blob 和 blob tx 傳播全貌。一張票據授予兩項獨立的傳播權限:CL 上的一個 blob 和 EL 上的幾個 blob tx。在 DA 合約中記錄可用性後,blob tx 無需票據即可自由傳播,從而實現無限次重新提交。
blob txs 的完整包容性故事
由於可用性記錄獨立於 blob 交易,我們現在可以通過首先確保 blob 的包含(可用性確定)來為 blob 交易提供抗審查性。我們通過基於 blob 票據的機制來實現這一點,並將類似 FOCIL 的 fork 選擇強制執行機制應用於 blob:
- 有效載荷及時性委員會 (PTC) 的每個成員都會觀察哪些數據塊已在區塊生成前的截止時間前傳播。他們會對這些數據塊進行抽樣,並形成本地可用性視圖。
- 成員們會發送他們觀察到的可用版本化哈希列表。
- 多數投票決定提案人必須在有效載荷中包含哪些版本化的哈希值(從而記錄在 DA 合約中)。
- 提案人可以添加額外的二進制數據塊,但不能排除 PTC 要求的數據塊。
- 驗證者強制執行此規則:他們只對包含 PTC 要求的版本化哈希值的區塊進行投票,除非驗證者在本地看不到這些 blob 可用(安全始終優先)。
請注意,現在提案者在 blob 包含方面受到雙向約束:他們必須包含 PTC 要求的內容(活性),而不能包含不可用的內容(安全性)。
至關重要的是,一旦記錄了 blob 的可用性,引用該 blob 的 blob 交易就等同於常規交易,因為其附加的有效性條件保證得到滿足:
- 如前所述,根據正常的內存池規則,它可以在沒有票據的情況下傳播。
- 它可以通過常規的FOCIL接口包含進來。
此外,票據交易本身也是常規交易,共享相同的內存池和FOCIL基礎設施。因此,我們獲得了針對blob交易的端到端抗審查機制。
圖 9. blob 交易的端到端包含保證。PTC 強制包含傳播的 blob(作為 DA 合約中記錄的版本化哈希),而 FOCIL 為購票和 blob 交易提供包含保證。
請注意,這種端到端的抗審查機制適用於使用 AOT blob 的 blob 交易。即使 AOT blob 在給定區塊的 PTC 截止時間之後傳播,只要它仍然可用,仍然可以從下一個區塊開始獲得包含保證——這與常規的 FOCIL 行為類似,即在 IL(包含列表)截止時間之前不在內存池中的交易不能被強制包含在當前區塊中,但可以包含在下一個區塊中。
另一方面,JIT blob 的定義是,只有當它被包含在區塊中時才會傳播——沒有預先包含的傳播路徑,因此無法提前確定其可用性並保證其被包含。當 JIT blob 被允許傳播時,它實際上已經被包含在區塊中了。我們可以將 JIT 容量理解為將一部分工單(“關鍵路徑”部分)分配給提案者,提案者再將這些工單轉售給構建者:構建者完全可以自行決定是否包含這些 blob(但會收取優先費用作為激勵)。對於真正需要 JIT blob 的用例——例如為了實現同步組合而進行的區塊和 blob 的共同創建——除了讓構建者執行此操作之外別無他法,因此缺乏包含保證是其固有特性。對於並非嚴格需要共同創建的用例,未能作為 JIT 包含的 blob 可以始終作為 AOT 重新提交,從而獲得上述完整的抗審查保證。
最後,我們將全面介紹該設計,並將其與當今的系統進行對比。
圖 10.當前模式(上)與 Blob 流式傳輸模式(下)。當前模式下,blob 數據、可用性判定和執行在一個模塊中耦合。而採用 Blob 流式傳輸模式後,AOT blob 通過票據預先傳播,並根據 DA 合約進行驗證;JIT blob 則像當前模式一樣在關鍵路徑上傳播。DA 合約通過系統調用記錄可用性,之後 blob 事務會根據該記錄進行驗證並正常執行。
附錄
DA系統合同
設計考慮因素
- 寫入模式:在每個塊的開頭,系統調用會記錄該塊中要斷言可用性的 blob 的版本化哈希值。
- 讀取模式:合約通過版本化哈希查詢來檢查數據塊是否可用。這應該既簡單又高效。
- 存儲管理:必須定期刪除條目以限制存儲空間的增長。如果每個存儲槽存儲 128 個數據塊,則無限制的存儲空間每年將增長約 10 GB。
- 當前區塊訪問:與可用性記錄在同一區塊中的交易必須能夠在沒有外部證明的情況下檢查可用性,因為它們無法為剛剛記錄的數據生成證明。
合同設計
該合約通過環形緩衝區維護一個最近窗口(約 128 個區塊),從而實現 O(1) 的無證明查詢。這涵蓋了當前區塊訪問和典型的彙總用例。
此外,用戶還可以通過存儲在每個區塊頭中的versioned_hashes_root來驗證合約是否包含在內。這既能最大限度地減少合約存儲空間,又能長時間地進行可用性查詢,足以確保用戶在 blob 可用性確定後仍能將交易上鍊。
請注意,當versioned_hashes包含在當前有效負載中時,驗證 DA 合約作為 blob 交易驗證的一部分,其開銷非常低,因為這是一次熱讀——版本化哈希在區塊開始時已寫入 DA 合約。因此,當前可用性確定與執行同時進行的模式基本不受影響。
# Constants BLOCK_WINDOW = 128 MAX_BLOBS_PER_BLOCK = 128 RECENT_RING_SIZE = BLOCK_WINDOW * MAX_BLOBS_PER_BLOCK # Storage recent_vhs_buffer: list [ Optional [ bytes ]] = [ None ] * RECENT_RING_SIZErecent_availability: dict [ bytes , int ] = {} # vh => 1 if in recent window recent_write_cursor: int = 0 def record_availability ( versioned_hashes: list [ bytes ] ): """Called via system call at block start.""" global recent_write_cursor for vh in versioned_hashes: # Clear old entry at current position old_vh = recent_vhs_buffer[recent_write_cursor] if old_vh is not None : del recent_availability[old_vh] # Record new entry recent_vhs_buffer[recent_write_cursor] = vhrecent_availability[vh] = 1 recent_write_cursor = (recent_write_cursor + 1 ) % RECENT_RING_SIZE def is_available ( versioned_hash: bytes ) -> bool : """Check availability in recent window (no proof needed).""" return recent_availability.get(versioned_hash) == 1













