Rollup 的大補帖:Proto-Danksharding(二)

NIC Lin
Taipei Ethereum Meetup
14 min readSep 3, 2022

本文將延續前篇 Proto-Danksharding 的介紹,但有別於前篇介紹其對 Rollup 的影響及整合方式,此篇將主要介紹其對手續費市場、節點實作、未來技術路線圖的影響。

Danksharding

Sharding 是以太坊技術藍圖中的一塊重要拼圖,而 Danksharding 是最新一個 Sharding 的設計提案,比之前的設計都來的更簡潔。更多關於 Danksharding 的介紹可以參考:

Rollup 的主要成本之一為上傳資料的成本,而在 Sharding 推出後,Rollup 勢必得改用 Sharding 的交易資料格式(也稱作 Blob)來上傳資料,因為會比目前用 calldata 的方式便宜很多。

而這也代表未來 Rollup 仍免不了要做一次系統更新:將資料上傳方式從 calldata 改成 Blob。那我們短期可以做的就是:(1) 降低 calldata 成本,也就是上一篇提到的 EIP-4488,及 (2) 讓 Rollup 提早切換至新資料格式(Blob),這樣未來就不必再做一次系統更新,而這就是 EIP-4844 Proto-Danksharding 在做的。

所以其實可以把 Proto-Danksharding 理解成一個提前為 Sharding 做準備,又能同時在中短期內大幅降低 Rollup 成本,一石二鳥的解方。

Eth 2.0 CL/EL 的調整

在實作 Sharding 的過程中,以太坊包含 Consensus Layer (以下簡稱 CL)及 Execution Layer (以下簡稱 EL) 的客戶端都會需要進行升級。而身為在為 Sharding 提前做準備的 Proto-Danksharding 除了引進新的 Shard Blob Transaction 格式外,還順便更新了 CL 及 EL 的架構及實作。

在 EL 這一端,包含 Blob 的 Fee Market(Blob 有獨立的手續費市場,後面會介紹)、新的 Opcode 及 Precompile 合約、P2P 網路的新資料格式及 EL/CL 之間的溝通驗證機制等等,基本上 Sharding 會需要的 EL 改動都已涵蓋在 4844 當中。

在 CL 這一端,包含保存及傳遞 Blob 的資料(Blob 資料只在 CL 間傳遞,不經過 EL)、引進資料可用性的接口等等,大部分 Sharding 會需要的 CL 改動都已涵蓋在 4844 當中。

Blob Sidecar 及相容 DAS 的接口

Blob 資料是在 Consensus Layer 間傳遞,但它不是被編碼成區塊的其中一部分,而是另外以稱為「Sidecar」的形式傳送,也就是區塊資料和 Blob 資料會是走兩個不同的資料通道。

為什麼要這樣做?為什麼不把 Blob 資料編碼成區塊的一部分一起傳送就好?這是為了能向前兼容 Sharding 的設計所做的調整。未來 Sharding 中 Blob 資料會比現在還大上很多倍,且節點將不會下載完整的 Blob 資料,而是透過 Data Availability Sampling 的方式一起來確保資料是可用的。所以 Blob 資料不會被編碼成區塊的一部分,否則節點就要把全部 Blob 資料都下載下來。另外節點會新增檢查資料可用性的接口(is_data_available),用來確認資料是否可用。

這個 EIP 引進了 Sidecar 這個設計,提早讓節點適應新的模式並能做一些效能的監測。在 Danksharding/DAS 來臨之前,節點都還是會下載完整的 Blob 資料,所以 is_data_available 接口會依是否有完整 Blob 資料來回傳 True/False,未來在 DAS 中則是會透過 Sampling 及在 P2P 網路溝通的結果來回傳 True/False。

剩下的 Sharding 會需要但還沒實作的部分包含(幾乎都是最上面的 Danksharding 介紹文章提到的技術):

  • 2 Dimension KZG commitments
  • Data Availability Sampling (DAS) 的實作
  • Proposer-Builder Separation (PBS)
  • Proof of Custody 機制

多維度手續費市場

這個 EIP 引進一個新的資源計算維度,讓原本的 EIP-1559 變成一個多維度的 EIP-1559。在這個多維度的 1559 中,原本的 Max Gas Per Block 及 Target Gas Per Block 還是存在,並繼續用來當作 EVM 各種運算所消耗的 Gas 上限參數;同時另外新增了一組給 Blob 資料大小的 Max 及 Target 值。目前設計中,Target 為每個區塊 3 個 Blob,Max 為 6 個。

一樣是指數成長的 BASE_FEE

如果 Blob 數量超過 Target Blob 數量,則 Blob Gas 的 Base Fee 和目前的 EIP-1559 市場一樣會以指數成長!

註:Blob 的收費單位也叫 Gas,並沒有新增一個計價單位,只是它和原本手續費市場的 Gas 是分開、獨立計算的,是不同維度的。

不一樣的數據參考來源

原本手續費市場裡所參考的是「上一個區塊的 Gas 消耗量」:如果上一個區塊的 Gas 消耗超過 Target,那就提高 Base Fee;而在 Blob 的手續費市場中,數據參考來源是「過去到現在累積的 Blob Gas 消耗量」:如果過去到現在累積的 Blob Gas 消耗超過 Target,那就提高 Base Fee。差別主要也就是考量的是短時間週期的影響還是長時間週期的影響。

Blob Gas 統計方式

每個區塊的標頭檔都會紀錄並更新過去到現在累積的超過 Target 的 Blob Gas 消耗量:excess_blob_gas。如果過去累積的 Blob Gas 消耗量都低於 Target 值或平均都低於 Target 值,那 excess_blob_gas 就會是 0

以下是每個區塊計算 excess_blob_gas 的公式:

  • parent 是前一個區塊的標頭檔
  • parent.excess_blob_gas 代表的是歷史累積的超過 Target 的 Blob Gas 消耗量
  • parent.blob_gas_used 代表的是前一個區塊的 Blob Gas 消耗量
  • TARGET_BLOB_GAS_PER_BLOCK 是 Target 值,如果 Target 是三個 Blob,那 TARGET_BLOB_GAS_PER_BLOCK 就是 4096*32*3 = 393216
def calc_excess_blob_gas(parent: Header) -> int:
if parent.excess_blob_gas + parent.blob_gas_used < TARGET_BLOB_GAS_PER_BLOCK:
return 0
else:
return parent.excess_blob_gas + parent.blob_gas_used - TARGET_BLOB_GAS_PER_BLOCK

如果前一個區塊的消耗(parent.blob_gas_used)沒超過 Target 值,那就能幫忙消化掉歷史累積的超額消耗,但如果前一個區塊消耗也超過 Target 值,那就會將這個超額的值繼續累積下去(return parent.excess_blob_gas + parent.blob_gas_used - TARGET_BLOB_GAS_PER_BLOCK)。

Base Fee 計算方式

算出了累積的超額 Blob Gas 消耗後,就可以算出 Base Fee 該怎麼調整。Blob Gas 的 Base Fee 的計算公式是:blob_base_fee = MIN_BLOB_BASE_FEE * e**(excess_blob_gas / BLOB_BASE_FEE_UPDATE_FRACTION)

  • MIN_BLOB_BASE_FEE 是 1(wei),Base Fee 的下限
  • BLOB_BASE_FEE_UPDATE_FRACTION3338477

註:BLOB_BASE_FEE_UPDATE_FRACTION 選擇為 3338477 的目的是為了達到 e**(TARGET_BLOB_GAS_PER_BLOCK / BLOB_BASE_FEE_UPDATE_FRACTION) ≈ 1.125 的效果,和原本的 1559 手續費市場(超過 Target 就以 1.125 倍成長)很相似。

如果 excess_blob_gas 不為 0,那 Base Fee 就會指數上升:

  • 如果累積超過 Target 10 個 Blob,那 Base Fee 就會是 e**(10*4096*32 / 3338477) = e**(1310720 / 3338477) = e**0.3926 = 1.48 (wei)
  • 如果累積超過 Target 50 個 Blob,那 Base Fee 就會是 e**(50*4096*32 / 3338477) = e**(6553600 / 3338477) = e**1.963 = 7(wei)
  • 如果累積超過 Target 100 個 Blob,那 Base Fee 就會是 e**(100*4096*32 / 3338477) = 50(wei)
  • 如果累積超過 Target 500 個 Blob,那 Base Fee 就會是 e**(500*4096*32 / 3338477) = 335290595(wei)= 0.33 (Gwei)

當累積超過約 530 個 Blob 時,Base Fee 才會超過 1 Gwei,1 Gwei 也是原本 1559 市場的最低 Base Fee,也是大家比較熟悉的數值和單位。

  • 如果累積超過 Target 10 個 Blob,一個 Blob 的手續費為 131072(gas)* 1(wei)= 131072 wei = 1.31072 * 10**(-13) ETH
  • 如果累積超過 Target 100 個 Blob,一個 Blob 的手續費為 131072(gas)* 50(wei)= 6553600 wei = 6.65536 * 10**(-12) ETH
  • 如果累積超過 Target 500 個 Blob,一個 Blob 的手續費為 131072(gas)* 0.33(Gwei)= 43253.76 Gwei = 0.00004325376 ETH
  • 如果累積超過 Target 600 個 Blob,一個 Blob 的手續費為 131072(gas)* 17(Gwei)= 2228224 Gwei = 0.002228224 ETH
  • 如果累積超過 Target 700 個 Blob,一個 Blob 的手續費為 131072(gas)* 862(Gwei)= 0.112984064 ETH

Blob 累積超過數量在 600 到 700 之間開始快速上升,到貴得離譜的階段。可以觀察目前的 Sepolia 測試網上統計的 Blob 用量、Blob Gas Price :https://sepolia.blobscan.com/stats/block

此時測試網維持在超過約 600 左右個 Blob,所以 Base Fee 為 20 Gwei 左右
比較資料放在 Blob(藍色部分)與資料放在 Calldata(棕色部分)所消耗的 Gas 用量差異

Block Builder 該如何挑選交易?

兩種交易,兩種不同限制

Block Builder 是否會需要跑複雜的演算法來計算最優的一般交易及 Blob 交易的組合?原本單維度的手續費市場 Block Builder 只需要按照手續費高低來收入交易,但在多維度手續費市場裡 Block Builder 要面對兩種變數、兩種限制來找出手續費最高的組合,也就是背包問題(Knapsack Problem)。

Vitalik 目前推測是不用的,有幾個原因:

  • EIP-1559 的設計確保在大部分的時候是不會碰到上限的,因此大部分的時間 Block Builder 都可以直接選擇收入他們能接受的所有交易(但不代表每筆交易都會收入,Block Builder 還是會考量收入一筆交易是否划算)
  • 這份分析也顯示,盡可能收入交易的策略與使用最佳解算法(背包問題算法)的策略,在收益上差距並不大(收益為純手續費收入,不包含 MEV)
  • MEV 會是最大的收入來源,而不是單純交易本身手續費的收入。而 MEV 都會是由更專業的角色去計算,他們本身就具備足夠的知識和經驗去算出最優組合。另外 Proposer-Builder Separation 也能透過分工來避免 Block Proposer 因為這些 MEV 收入與競爭導致變得中心化 — Proposer 賺的是 Block Builder 的競標費用而不是 MEV。

兼容問題與挑戰

Web3 API 存取不到 Blob

Blob 會在 CL 之間的 P2P 網路傳遞,也就是 EL 節點基本上不會存取到 Blob,也因此開發者是沒辦法透過 web3 API 來拿到 Blob 資料的。

Mempool 的 DoS 風險

因為 Blob 資料量不小,所以如果攻擊者廣播很多 Blob 交易到 p2p 網路中,就有可能會有 DoS 風險。因此節點會改成採用「宣告 Blob 交易(Announcement)」及「索取 Blob 交易」的方式,而不是直接讓 Blob 交易主動推送到網路中每一個節點,如此節點就可以透過先查看 Announcement 再決定要索取哪一筆 Blob 交易。

資料大小對磁碟大小需求的影響

EIP-4488 及 Proto-Danksharding 都會造成一個效果是:長期下來平均每一個 slot(即每 12 秒)會有 1MB 大小的傳輸需求,一年下來就是 2.5 TB 的大小,遠比目前 Ethereum 每年新增的資料大小還大上許多。

如果 EIP-4488 被採用了,那 EIP-4444:清除節點歷史數據的手段就必須被納入,來避免硬碟空間需求暴增。

如果 Proto-Danksharding 被採用了,CL 節點可以透過定期清除舊的 Blob 資料方式來避免硬碟需求暴增(不管 EIP-4444 有沒有被納入)。

這兩種方式都能將硬碟需求降至一年數百 GB。不過 Sharding 遲早會來,屆時資料大小將會再大上許多,像是 EIP-4444 這樣的手段還是無可避免。

資料大小對頻寬的影響

以目前 Target 是 3 個 Blob 來計算,每個區塊資料量的頻寬需求會增加 0.375 MB。

--

--