newsence
負載分塊:優化以太坊區塊傳播與執行效率

負載分塊:優化以太坊區塊傳播與執行效率

Ethereum Magicians·12 天前

本文探討了以太坊的多種負載分塊策略,旨在透過並行化區塊傳播與執行來降低延遲並實現第一層擴容。我們比較了語義化與非語義化分塊模型,並分析了它們與 ePBS 及 BAL 等即將推出的 EIP 提案之間的權衡與互動。

動機

針對有效載荷分塊(Payload Chunking),目前有多種相似但不同的方法正在被考慮。本文的目的是解釋其中的差異、描述權衡,並分析它們如何與其他 EIP 相互作用。

問題

我們可以用下圖來模擬以太坊上的區塊傳播與執行:

有效載荷分塊的核心思想是將區塊拆分成較小的分塊(chunks),並在網路上分別傳播。在最簡單的設計中,每個節點必須在執行區塊之前下載並合併所有分塊。在本文的其餘部分,我們將此模型稱為「簡單分塊」(Simple Chunking):

如果我們也能在分塊到達時立即執行它們,我們就可以將區塊下載與執行並行化,這將引導我們進入此模型:

分塊可能以任何順序到達。圖中為簡化起見按自然順序排列。

效益

我們確定了這帶來的兩項改進。

並行傳播

能夠在每個分塊到達時立即傳播,使整個區塊的傳播速度更快。分塊越小且網路規模越大(到達所有節點所需的跳數越多),分塊的效果就越顯著(見下文分析)。

簡單分塊模型即是如此。已有數個提案深入探討了這種設計,例如:Blobs 中的區塊 (EIP-8142),或使用 RLNC (連結)。

並行下載與執行

獨立執行分塊減少了從接收區塊數據的第一位元到驗證區塊之間所花費的總時間。

值得強調的是,在最佳情況下,這能帶來 2 倍的加速(即當下載時間 = 執行時間時)。在其他情況下,加速效果較小,因為下載或執行單項操作就佔用了總時間的 50% 以上。

由於僅提供第一項效益(並行傳播)的設計已經存在,本文將主要關注同時允許兩者的設計。

協議變更

假設納入 ePBSBAL 提案(預計在 Glamsterdam 升級),我們可以做出一些假設並考慮一些具體的有效載荷分塊實現。

首先,我們觀察到交易和 BAL 佔了網路上傳播的大部分數據。有效載荷分塊最簡單的設計是將它們從 ExecutionPayloadEnvelope 中移除(參見 ePBS EIP)。ExecutionPayloadEnvelope 將改為包含對分塊的承諾(commitment),而分塊則分開傳播。每個分塊僅包含部分交易 / BAL 數據。

這引發了一些設計問題。

將區塊訪問列表分塊化

BAL 的平均大小比交易小,但在最壞情況下可能更大(例如:少量交易讀取或寫入許多存儲插槽)。將 BAL 分塊化似乎是一個合乎邏輯的方法,但我們必須考慮一些事項。

BAL 是讓我們即使在分塊亂序到達時也能獨立執行分塊的關鍵。如果我們想保留該特性,必須將其拆分為「分塊訪問列表」(Chunk Access Lists,簡稱 CALs)。我們必須以下列方式之一設計 CAL:

依賴型 CALs

我們可以讓執行當前分塊時需要先前分塊的 CAL。這意味著,為了執行分塊 i,我們需要 chunk_i(分塊 i 的交易)以及所有的 CAL_0, CAL_1, …, CAL_i。

這會導致某些欄位在 CAL 之間重複(與 BAL 相比):

  • 在多個分塊中被修改的地址和存儲插槽
  • 在早期分塊中被讀取並在後期分塊中被修改的存儲插槽

因為即使沒有 chunk_i,CAL_i 也是有用的(狀態預取、執行後續分塊),所以這些對象應該分開傳播。

獨立型 CALs

另一種方法是使 CAL 獨立,即每個 CAL_i 都包含執行 chunk_i 所需的所有數據。

這進一步增加了數據重複。與前一種方法相比,我們還需要包含:

  • 在早期分塊中被訪問過的所有存儲插槽
  • 如果它們被修改過,我們也必須包含最新的修改

通過這種設計,我們可以將 CAL 和分塊交易一起發送,降低複雜性。但它與非語義分塊(見下文)不相容。

使 CAL 依賴是更務實的做法,因為在最壞情況下數據重複顯著較小。缺點是執行任何後期分塊都需要早期的 CAL(即需要 CAL_0 才能執行任何分塊,如果它延遲收到會導致延遲)。

語義分塊 vs 非語義分塊

在決定如何對交易進行分塊時,自然會出現兩種方法。

非語義分塊

我們認為非語義分塊是指將所有交易編碼成一個字節數組,然後將其拆分為均等大小的過程。這確保了每個分塊在網路中的傳播時間相似。

然而,如果我們希望能夠在分塊到達時立即執行,我們必須傳播一些關於編碼的額外信息(例如:每筆交易從哪個分塊以及哪個索引開始)。這使設計變得複雜(某些交易會跨越多個分塊,BAL 分塊的選擇較少),且隨著我們調高 Gas 限制並降低內置交易 Gas 成本 (EIP-2780),額外數據量可能不可忽視。

大多數「簡單分塊」設計都是非語義分塊的一種形式,但不具備獨立執行分塊的效益。例如,Block-in-Blobs (又名 BiB) 將 BAL 和交易編碼成單一字節數組,然後拆分為預定義大小並轉換為 Blobs。BiB 的缺點是,由於在切換到 zkEVM 之前我們無法啟用 DAS(數據可用性採樣),每個節點都必須下載所有分塊/Blobs。在目前使用與常規 Blobs 相同編碼的設計中,我們使需要傳播的數據量翻倍,卻沒有帶來太多好處。建構者(Builders)還必須在關鍵的時隙(slot)時間內計算 KZG 承諾和證明。

語義分塊

非語義分塊的缺點之一是我們無法保證各分塊之間的執行工作量是相似的(例如:一個分塊可能包含所有執行繁重的交易)。

為了在分塊之間建立更均勻的執行複雜度分佈,我們可以拆分交易並以下列方式創建「微型區塊」(mini-blocks):

  • 每個分塊至少有一筆交易
  • 交易不跨分塊拆分
  • 分塊中使用的 Gas 最多為 16.8 Mgas(根據 EIP-7825 挑選,可調整)
  • 我們還可以確保平均分塊不會太小(例如:不允許連續兩個分塊加起來小於 16.8 Mgas)

由於交易大小會影響使用的 Gas,我們也限制並平衡了分塊的字節大小,使傳播也趨於均勻分佈。

與非語義分塊相比,將交易更自然地劃分為分塊使分塊執行更簡單。這些分塊可以被視為微型區塊,擁有自己的分塊標頭(包含分塊特定欄位,例如 chunk_gas_usedpre_chunk_tx_count…),但沒有區塊那樣的複雜性(無需計算狀態根、發送證明等)。

有關此設計的詳細規範,請參閱 EIP-8101。概念驗證實現請參考此處

其他生態系統的相關方法

其他生態系統也引入了類似的改進。

Solana 將數據拆分為「碎片」(shreds),並使用 Turbine 協議來加快傳播速度。雖然數據拆分與非語義分塊類似,但 Turbine 在網路層進行了創新,以進一步提高傳播速度。

Base 和其他幾個 OP Stack 網路使用 Flashblocks。Base 不是每 2 秒傳播一次區塊,而是每 200 毫秒產生並傳播一次子區塊。這些子區塊隨後被組合成單個區塊。這種方法類似於語義分塊,但它允許建構者在最終確定區塊之前創建子區塊。這種類型的「流式語義分塊」(Streaming Semantic Chunking)在目前的 ePBS 設計下無法在以太坊主網上實現。ePBS 的設計必須更改為「時隙拍賣」(Slot Auction)模型,而該模型具有詳盡記錄的權衡

擴展 L1

有效載荷分塊的主要好處是它允許我們擴展 L1。更短的傳播和執行時間讓我們能夠增加區塊大小(即 GasLimit)、減少時隙時間,或兩者結合。

一旦我們有了 zkEVM 和 BiB,這些改進的相關性就會降低,因此我們必須分析潛在的擴展因子,並考慮是否值得去做(zkEVM 的確切時間表在此討論中扮演重要角色,但本文將不予討論)。

為了安全地擴展 L1,我們必須考慮最壞情況及其帶來的效益。讓我們分析每項改進。

並行下載與執行

如前所述,獨立的分塊執行允許我們最多擴展 2 倍。這是最佳情況的估計,與現實相去甚遠。

如果我們深入觀察並考慮最壞情況,非語義分塊在這方面幾乎無法提供任何保證的改進。最壞的情況是,大部分執行都發生在一個分塊中,而客戶端恰好最後才收到該分塊。在這種情況下,開頭的圖表看起來會像這樣:

乍看之下,語義分塊應該能解決這個問題(因為它限制了每個分塊使用的 Gas),但其有效性取決於參數。BAL 已經允許交易並行執行。因此,如果一個區塊充滿了使用最大 Gas (16.8M) 且執行繁重的交易,我們實際上並沒有擴展太多。

在上面的圖表中,我們有一個區塊,其中只有 4 筆交易就用完了整個區塊的 GasLimit。如果我們將帶有 BAL 的簡單分塊(交易並行執行)與語義分塊進行比較,我們發現語義分塊沒有提供任何加速。隨著 GasLimit 的增加會有一些好處(因為我們無法並行化所有交易),但不會是重大的改進。

顯而易見,在最壞情況下,擴展因子小於 2。也很難估計具體數值,因為它取決於許多參數(GasLimit、用於並行執行的核心數量等)。

隨著 zkEVM 的到來,分塊執行在未來的價值會進一步降低。

並行傳播

無論採用哪種方法,並行傳播都能保證擴展。最佳情況是分塊大小相同,這正是非語義分塊(包括許多簡單分塊設計)預設提供的。語義分塊對此不提供任何保證,但由於我們對每個分塊使用的 Gas 有限制,我們也間接地限制了分塊大小。

在不分塊的情況下,如果兩個節點之間發送整個區塊需要 t 秒,那麼在 h 跳後接收區塊的節點將在 T_h = th 時間完成接收。如果區塊被分成 N 個分塊,它將改為在 T'_h = (h-1)t/N + t = t(h-1+N)/N 時間完成接收。在這種情況下,擴展因子將是 T_h/T'_h = hN/(h-1+N)。

如果我們假設需要 h=6 跳才能到達大多數節點(根據當前網路規模估計),且區塊被分成 N=10 個分塊,我們得到的擴展因子為 4。

在大多數設計中,我們無法直接控制分塊數量 N。隨著區塊大小增長(即 GasLimit 增長),我們自然會擁有越來越多的分塊。更多的分塊意味著更好的擴展性,但這種關係並非線性的。我們還不應忘記,每個分塊也會攜帶一些額外數據(包含證明、簽名)並需要額外的處理時間(驗證)。如果存在太多極小的分塊,這種開銷可能會產生影響。

如果我們使用非語義或簡單分塊,分塊大小是一個非常靈活的參數,我們可以根據基準測試和其他參數(GasLimit、calldata 定價等)來設定。我們還可以考慮與 BiB 和其他提案的相容性。

結論

在考慮哪種方法值得加入協議時,我們必須考慮潛在效益、複雜性以及與其他計劃改進的相互作用。

優點缺點
簡單分塊簡單、高效的並行傳播、與未來 EIP 相容無並行下載與執行
非語義分塊高效的並行傳播、與未來 EIP 相容實現並行執行的設計複雜,且無保證的擴展性
語義分塊中等複雜度、高效的並行執行並行執行擴展因子難以計算(可能很小)、在 zkEVM 後無用

所有探索過的設計都提供了並行傳播,且效果相似。如上所述,單個分塊執行並不能提供巨大或有保證的擴展,卻增加了複雜性。如果我們移除這項要求,我們也不必將 BAL 拆分為 CAL,這進一步簡化了設計。協議也能與未來的改進(如 BiB 和 zkEVM)保持更好的一致性。

這得出的結論是:如果我們要進行任何形式的有效載荷分塊,採用「簡單分塊」是最有意義的。一種方法是簡單地對每個分塊的哈希進行承諾。我們可以將分塊大小設定為與 BiB 相容,並在稍後決定啟用 DAS 時切換到 BiB。我們也可以決定直接採用 BiB。確切的設計有待進一步分析,且超出了本文的討論範圍。

        1 則貼文 - 1 位參與者

        [閱讀完整主題](https://ethereum-magicians.org/t/payload-chunking/28067)
https://ethereum-magicians.org/t/payload-chunking/28067