作者 | Piper Merriam 翻譯&校對 | 閔敏 & 阿劍
最近舉行的第 90 期核心開發者會議幾乎全程都在討論一個問題。我強烈建議大家親自聽一下這場會議。
在這場會議上,Alexey 提出了客戶端開發者負荷過重的問題。雖然我認為這場討論是一個重要的開始,但是我們太急於尋求解決方案了,充分理解這個問題才是當務之急。重要的是,我們需要花點時間來分析問題。在問題內涵的分析上,「五問法(Five Whys)」 是最簡單有效的方法之一。
事不宜遲,先來看看第一問是什麼。
第一問:為什麼 Geth 開發團隊的壓力如此之大,甚至到了超負荷的地步?
通過 etherscan,我們可以看到各個客戶端的裝機量所佔份額的統計數據如下所示:
- Geth: 75%
- Parity & OpenEthereum: 20%
- Nethermind: 1%
剩下 4% 由一些市場份額不到 1% 的客戶端組成,因此忽略不計。重要的是,有超過 51% 的算力都集中在 Geth 客戶端上。假設在即將到來的柏林硬分叉中,Geth 在實現其中一個 EIP(以太坊改進提案)時出現了 bug 。即使這個客戶端的其它實現都沒出 bug ,只要有區塊碰上了這個 bug ,就會導致以太坊網路分叉。按理來說,這個區塊是無效的,其他客戶端也會將其視為無效塊。但是,有超過 51% 的挖礦節點都運行的 Geth 客戶端,因此整個網路都會被帶到錯誤的分叉鏈上去。這就要求 Geth 客戶端和開發團隊絕對不能犯錯。因此,第一問的答案是:
因為以太坊網路的客戶端缺乏足夠的多樣性。
值得一提的是,客戶端多樣化不會突然將客戶端開發變成一項輕鬆的工作。但客戶端多樣性本身依然是一個值得探索的領域,有助於我們找到提高客戶端開發的效益,同時減輕開發團隊負擔的方法。不可否認的一點是,只在 Geth 團隊上下功夫不太可能解決這個問題。
第二問:為什麼以太坊網路缺乏客戶端多樣性?
以太坊主網上線時,我們有多個客戶端。其中最主要的兩個是 Geth 和 CPPEthereum 。之後又出現了 Parity ,CPPEthereum 被淘汰。從那時起,除了 Parity 之外,沒有一個客戶端能獲得較大的市場份額。去年,Nethermind 異軍突起,成為了一顆冉冉上升的新星,但是目前只佔據了 1% 的市場份額。最近,由於 Parity 遭遇了一些波折,前途一片黯淡,Parity 的市場份額大幅下降。
我們認為,在理想情況下,以太坊網路需要有 3 個及以上的客戶端、每個客戶端佔有的客戶端份額都不至於太高、沒有任何一個客戶端能佔據遠遠超過 51% 市場份額。雖然在理想情況下應該實現客戶端多元化,但是我們已經習慣了客戶端霸權的局面。那麼,我們為什麼需要多個客戶端?從我個人的經驗角度來看,構建以太坊客戶端難比登天。
Geth 之所以能在以太坊網路上穩定運行,是因為它引入了很多複雜的優化。Geth 團隊花費了數年時間才達到了如此高的複雜度,目前仍在繼續優化中。有人可能會立即建議我們想辦法為落後的客戶端提供支持和幫助。我很警惕這種 「人月神話」 式的解決方案 —— 在軟體開發過程中,讓更多工程師來解決一個難題很少會成功,而且我不指望這種方案會取得成功。相反,我認為應該將關注點放在複雜性上。
註:人月神話,mythical man-month,指出以大量人員和較短的時間,並不能縮短軟體的開發進度。一窩蜂的作業方式無助於軟體生產,且會製造麻煩,產生出更差的軟體。向進度落後的項目追加人力,只會使進度更加落後。
第三問:為什麼構建以太坊客戶端會這麼難?
現在,我們正越來越接近問題的根源。事實證明,大部分困難都來自於組網協議(networking protocol),即以太坊客戶端軟體用於相互連接並分享區塊鏈信息的那一組工具。以太坊的組網規則(定義在 devp2p 代碼庫中),最終影響甚至決定了以太坊客戶端的設計和要求。一些組網工具指定了未經優化的架構,甚至要求以太坊客戶端運行不必要的功能。客戶端開發者需要在這些限制下工作。
第四問:為什麼網路互聯協議提高了客戶端實現的難度?
我相信,這個問題的答案基本上可以分為兩個部分。
- 狀態管理
- 整體網路互聯要求
就狀態管理而言,以太坊客戶端必須能夠同步網路上的完整狀態,並維護該狀態的本地副本。這兩點都很難做到。對客戶端以及讀取並處理狀態要求的伺服器來說,同步狀態需要提出數百萬個請求,並且會導致磁碟 I/O 飽和。新同步的狀態需要經過維護和刪減,以便資料庫能足夠快地執行新區塊。從工程上來說,這是一項嚴峻挑戰!GetNodeData
是我們用來同步狀態的唯一網路互聯工具,針對特定的狀態資料庫格式(俗稱 「the native layout」)進行了優化。由 Turbo Geth 推廣的 「扁平式」 資料庫布局在狀態維護方面具有極大的性能優勢,但是使用這種布局會加大 GetNodeData
請求的處理難度。一旦我們將注意力轉向網路技術,尤其是 DevP2P ETH
協議,我們會發現還有其他因素提高了客戶端的複雜性。要想加入這個網路,客戶端需要具備以下能力:
- 處理訪問最近區塊所生成的狀態的
GetNodeData
請求; - 處理訪問鏈上數據歷史記錄的請求,包括區塊頭、區塊體和收據。
從根本上來說,對於許多客戶端操作而言,處理這些請求所需的基礎數據不是必需的,但是現在卻強制它們支持這些功能。這就需要所有客戶端在除了滿足自己本身的需求之外,還要另外構建大量功能。例如,主要作為交易發送網關的客戶端並不需要歷史鏈上數據,可能只需要一個很小的狀態子集。但是,就當前的以太坊版本而言,客戶端依然需要保存完整的副本。
第五問:為什麼……
看來我只問了四個 「為什麼」 就找到了根本原因。以太坊協議還沒有完全成熟。在設計以太坊協議時,我們並沒有意識到現如今發現的大多數問題,或者因為當時狀態規模較小、發展歷史較短,這些問題還不成問題。
解決方案
過去一整年,我都在關注這個問題。令我震驚的是,以太坊上許多問題的根源其實都可以追溯到網路層。或許最明顯的例子是,磁碟 I/O 歷來都是客戶端的一個瓶頸。這個瓶頸之所以存在,是因為客戶端傾向於使用樹結構(Trie)的樸素表示來執行其狀態資料庫。狀態資料庫的構建方式由 GetNodeData
網路元件決定。
為了解決這個問題,我們需要對以太坊共識層以及網路層的各個部分進行檢修。目前,檢修工作已經啟動。大量工作已經在 Alexey 和我共同領導了 8 個月的 「無狀態以太坊」 名義下開展。我們所做的一些工作至少減輕了 Geth 團隊的負擔,因為他們用上自己開發了經年之久的 SNAP 同步協議。還有一部分工作需要深入理解這個問題並想到可行方案的才俊來承擔。目前,這樣一個龐大的 DevP2P ETH
協議尚未完全解構。
我們對於如何將這個網路拆分成三個獨立的專用網路有了基礎了解,但是目前還沒有人直接著手這塊。另外,還有像 re-genesis 之類的想法,提供了完全迴避這些問題的機制。這是一種激進的方法,如果能成功的話,或將為我們帶來很大的優勢。首先,我們應該清楚的是,以太坊網路還有許多艱巨的任務需要完成,只有少數人能夠勝任這些任務。
雖然每天都有越來越多的開發者參與進來,但是他們需要投入時間和精力來學習必備技能。客戶端開發者在專註於解決日常用戶看不到的底層問題時,還要抽出時間來開發新的 EVM 功能。如果我們希望以太坊網路能夠取得長遠的成功,我認為整個社區都要就解決這些問題展開合作,給予其根本原因足夠的關注和討論。最重要的是,我們要攜手打造出有效的技術解決方案。
冷萃財經原創,作者:Awing,轉載請註明出處:https://www.lccjd.top/2020/07/21/%e4%bb%a5%e5%a4%aa%e5%9d%8a%e5%ae%a2%e6%88%b7%e7%ab%af%e5%a4%9a%e6%a0%b7%e6%80%a7%e9%97%ae%e9%a2%98%e4%bb%8e%e4%bd%95%e8%80%8c%e6%9d%a5%ef%bc%9f/?variant=zh-tw
文章評論