作者:John Otander,以太坊核心開發人員;翻譯:金色財經xiaozou
這篇文章的靈感來自於以太坊常使人Vitalik在最近的 Reddit AMA 中的回答。
Vitalik指出,適度提高Gas Limit是合理的,Gas Limit已經近三年沒有增加,這是該協議歷史上最長的時間,。 Vitalik也做了一些簡單的計算表示將以太坊Gas Limit提高到4000萬。
本文講述了為何說提高以太坊Gas Limit比較困難?提高以太坊Gas Limit帶來的風險,以及相關解決方案。
1、Gas Limit(Gas限制)
Gas limit決定了一個區塊內的工作完成量,因此決定了每個區塊可以執行多少交易。提高gas limit將使以太坊能夠處理更高的交易吞吐量或更複雜的交易。一直以來,具體的gas limit設置受礦工/質押者影響,並且多年來限額一直在增加。下圖來自etherscan.io,顯示了gas歷史用量(非常接近gas limit,所有限額增加都被市場消化掉了)。
2、風險
現在提高gas limit涉及幾個風險。
(1)漏塊率
我在之前的文章中提到,叔塊率(uncle rate)是評估gas limit增加時討論最多的一個指標。現在,在以太坊合併之後,再也沒有叔塊了。我們要知道節點是否能很好地處理了目前的gas limit,唯一的方法就是看漏率。但這個指標是有瑕疵的,因為它只顯示目前供應不足的節點。它並沒有提供給我們一個很好的指標來顯示gas limit的增加,而且它只顯示了平均情況,而不是在攻擊中可能發生的最壞情況。
(2)狀態大小
區塊18418786(2023年10月24日)的帳戶快照為10.33GB,儲存快照為76.59GB,因此整體狀態大致為87GB。區塊17419840(2023年6月6日)的狀態略小於80GB。這意味著狀態在4個月內大約成長了7GB,也就是說每月成長約2GB。
如果我們使用87+(2*12*#年)來推斷,一年後的狀態將是111GB,五年後將是207 GB。這裡的問題不在於大小。每個人都可以儲存這麼多的數據,但是存取和修改這些數據會變得越來越慢。
這還只是快照,是一般狀態。 Geth還需要以不同的形式儲存此狀態,以便驗證狀態根。區塊18418786的另一種狀態儲存形式(trie節點)大約需要180GB。
因此,目前僅用於狀態儲存的總空間大小約為267GB。如果我們提高gas limit,狀態大小會成長得更快。
狀態成長的問題在於,與過去不同,我們沒有明確的途徑來移除狀態。沒有我們可以迅速實施的具體的狀態期限建議來讓我們擺脫不斷增長的狀態。
(3)歷史規模
在我2021年的一篇文章中曾提到,一個完整的geth節點大約是350GB(新修剪的)。大約三年過後,一個完整的geth節點(在pbss上)超過900GB。下圖顯示了交易的總累積量。從中很容易看出,交易量在三年內增加了一倍多,從大約9.8億筆增加到超22億筆。
隨著L2的崛起,歷史規模已經成為一個更大的問題,因為它們現在(在4844上線之前)儲存資料的方式是calldata。區塊18418786的區塊體超過427GB,區塊17419840(同樣是4個月前)的區塊體為339GB,這意味著4個月內成長28GB,也就是說大約每月成長9GB。我們可以用427+(9*12*#年)來推論這個成長,一年後為535GB,五年後為967GB(再次假設為線性成長)。
希望在EIP-4844上線後,這種成長會放緩,屆時L2將停止使用CALLDATA來取得資料可用性,並轉為使用幾週後到期的blob。
EIP-4444將解決歷史成長問題,因為全節點不再需要儲存所有歷史。實作EIP-4444需要一個可靠的網路來檢索歷史,然後我們才能讓全節點停止歷史資料服務。
(4)同步時間
Gas limit在許多方面都可以影響同步時間:
· 完全同步變得很慢,一個geth節點需要一周以上的時間才能完全同步鏈,其他客戶端已經優化了更好的完全同步模式。
· 同步歷史資料比較慢。因為我們需要下載更多的數據,所以同步歷史資料部分就會比較慢。
· 快照同步狀態比較慢,因為我們需要下載的狀態更多了。
· 快照恢復較慢。由於pivot point(樞軸點)在快照同步期間移動,因此我們在磁碟上有許多需要修復的不完整狀態。如果pivot移動更頻繁,並且每個區塊有更多的更改,那麼該修復階段就會變慢。
· 由於節點需要透過更多的變更才能形成區塊頭,因此與鏈同步的速度會更慢。
(5)客戶端多樣性
建立一個新的EL客戶端本身就是一項艱鉅的任務。增加gas limit還有一個額外的缺點,那就是會使建立客戶端並優化以供主網使用變得更加困難。 Geth已經開發了10多年,並進行了大量優化。可能存在相反的觀點,認為新客戶端可以藉鏡現有客戶端,不再犯同樣的錯誤。
然而,我們已經看到了兩個客戶端(用python編寫的Execution Specs和使用javascript編寫的EthereumJ)的主網困境。這也意味著現在使用某些語言編寫的客戶端行不通了。受限於語言開銷和程式碼庫的成熟度,增加gas limit將讓一些客戶端掉隊。
我們在KZG中也看到了這一點,為了獲得所需的效能,大多數客戶端依賴呼叫C-KZG(一個用C語言編寫的程式碼庫),而不是使用用他們所選的語言編寫的函式庫。
(6)最差情況
在考慮gas limit時,我們不能只看一般情況。我們總是要考慮最差的情況。當然,當鏈處於平均負載情況下,節點可能會運作得很好,但是如果突然連續5個區塊的磁碟I/O增加一倍會發生什麼?
運行時間並不是我們需要考慮的唯一指標,如果攻擊者可以佔用其他資源,如磁碟I/O、CPU時間或內存,他們可能會迫使較低配置的機器離線。特別是在以太坊合併後,在同一台機器上運行兩個客戶端,攻擊其中一個客戶端可能也會讓另一個客戶端狀態不穩定。在以太坊合併測試的早期,我們目睹過幾次這樣的情況:一個客戶端的記憶體洩漏會導致整個系統崩潰。
另一個需要考慮的最壞情況是證明大小(proof size)。隨著gas limit的增加,兩個區塊之間可能發生的潛在狀態變化也會增加。這對前面討論的快照同步是有影響的,但它也會影響執行層輕客戶端的證明大小。現在這還不是什麼大事,merkle-patricia tree(梅克爾-帕特里夏樹)的證明太大了,無法透過網路發送。但是,如果我們想要實現在同一台機器上運行多個輕客戶端的交叉驗證思想,那麼證明大小就會非常重要。
3、解決方案
我們就這麼完了嗎?我們會一直維持30MGas的上限嗎?不是的!
在我2021年的一篇文章中,我為當時我們面臨的困境提出了解決方案。對於我們在2021年面臨的完全同步問題,geth實現了快照同步和快照。對於修剪和資料庫佈局的問題,geth實作了PBSS。 Txpool在處理高交易負載方面變得更加可靠,大部分MEV搶跑交易都轉移給了建造者。許多交易也轉移到了L2,這反過來又增加了主網交易的平均規模。
唯一沒有實現的解決方案是regenesis。多年來,人們的觀點發生了一些變化,大多數人似乎都傾向於EIP-4444歷史期限作為歷史數據成長的短期解決方案。對於EIP-4444的發布,我們需要一個強大的歷史資料服務節點網絡,這樣歷史就不會遺失,即使它不再被所有全節點儲存(順便說一句,大多數比特幣節點根本不儲存歷史資料) 。
我們至今仍然沒有找到一個體面的、現實的狀態期限方式。
正如你在上海昇級之前看到的攻擊,有一些已知攻擊阻止了我們提高gaslimit。 (據我所知)所有漏洞都已解決了。
在撰寫本文時,EIP-4844正在測試網路上發布。此EIP將提高節點的儲存和I/O需求。在我看來,在嘗試任何類型的gas limit增加之前,等等看這項變更對主網的影響是最安全的做法。一旦L2轉向Blob交易,我們就應該增加calldata成本(因為在我看來,與資料需要儲存的其他東西相比,calldata的價格被低估了)。這也可以作為L2使用blobspace的強制函數。
總之,我想提醒大家在考慮提高gas limit時要小心行事,因為它會影響節點的許多方面,有些影響會相對明顯。在相關討論中,考慮gas limit變化的長期和短期影響是非常重要的。