ETH1.x:如何通向無狀態以太坊

當我開始著手撰寫一篇文章,意圖詳細介紹以太坊1.x研究的“路線圖”,以及如何通向無狀態以太坊,卻意識到嚴格來說,這完全不能被定義為傳統意義上的路線圖。 雖然1.x團隊有著共同的目標,但卻是一個兼收幷蓄的集體,開發者和研究者獨立地進行著錯綜複雜的工作。因此,也不存在“官方”路線圖一說,但這並不意味著混亂無序。團隊工作遵循一種默認的“次序”,例如某些工作必須要優先進行,某些解決方案是互斥的,還有一些工作可能有所裨益但卻不是必要的。

如果不用“路線圖”來描述通向無狀態以太坊的過程,那麼是否有更好的比喻呢?要找到一個合適的比喻確實不容易,但我覺得無狀態以太坊就像是科技樹(tech tree)[1] 中的“全屬性”。

有些讀者可能會立即明白這個類比,那麼接下來的幾段可以跳過。有些讀者可能不是遊戲愛好者,我會稍作解釋:科技樹(tech tree)是遊戲中的一種常見機制,玩家能夠解鎖和升級新的符咒、技術或技能,通常以鬆散的層次或樹狀結構展現分類。

ETH1.x:如何通向无状态以太坊

通常來說,可以通過“耗費”某種XP(經驗點)來獲取樹中的元素(屬性),進而解鎖更多高級元素。有時需要獲取兩個不相關的基本元素才能解鎖第三個更高級的元素,有時解鎖一個基本技能會為下次升級開放更多新的選擇。對於玩家來說,遊戲的樂趣有一半是來自於在科技樹中選擇了與自身角色能力、目標和偏好相匹配的正確路徑。

以下是我自制的粗略科技樹圖。針對排列方式、每個升級及其與整體的關聯性,我會稍作闡釋。科技樹中最終的“全屬性”升級就是“無狀態以太坊”。也即是指,一個功能齊備的以太坊主網將支持全狀態、部分狀態和零狀態節點,將高效可靠地傳遞見證(witnesses)和狀態信息,並且從原則上來說,對於後續的擴展性也要準備就緒,直到eth2的橋接建設完成且能夠登陸eth1鏈。

ETH1.x:如何通向无状态以太坊

注意:就像之前提到的,這不是“官方”的工作路線。這是我所整理和組織的1.x團隊必須解決的關鍵難題、里程碑和決策,目標是最終實現無狀態以太坊。歡迎提供反饋,隨著研究的推進,該計劃也會隨之更新和修訂。

閱讀順序是從左至右,左側的紫色信息是“基本”要素,必須首先進行開發和確定,才能繼續推進右側的要素。綠色部分表明這些元素在某種意義上算是“增益”項目,儘管在過渡過程中不是必需,並且在研究方面還不夠具體,但還是有可取之處。較大的粉色形狀代表無狀態以太坊的重要里程碑。要完全過渡到無狀態以太坊,必須“解鎖”圖中所有四個主要里程碑。

見證範式

在無狀態以太坊的語境下,關於見證(witness)的討論有很多。因此,我提出的第一個主要里程碑是最終的見證範式。這意味著一定要確定狀態樹和相關見證的結構。可以將規範創建或參考實現視作eth 1.x研究“升級”的地方;圍繞狀態的新形式展開工作將有助於釐清和集中完成其他亟待解決的問題。
ETH1.x:如何通向无状态以太坊

二叉樹

將以太坊的狀態切換為二叉樹結構非常關鍵,這可以使得見證足夠小,在進行網絡通訊時避免帶寬/延遲問題。

上次的研究者會議中[2] ,轉換為二叉樹結構將需要保證以下兩種互斥策略之一:

漸進式。如同忒修斯之船[3] ,當前的十六叉狀態樹將在很長一段時間內逐段進行轉換。通過這種方式,任何涉及狀態部分的事務或EVM執行都會自動將狀態更改編碼為新的二進制形式。這意味著採用“混合”樹結構,休眠的狀態部分依然保留當前的十六進制形式。該過程實際上永遠不會完成,並且對於客戶端開發者來說實施難度很大,但是在很大程度上將使用戶和更高層的開發人員免受第0層幕後發生的更改的影響。

乾淨利落。也許這種策略更切合狀態數變更的重要性,該策略將通過規劃多次硬分叉為過渡過程制定清晰的時間線,計算狀態的二進制樹新表現形式,一旦新的狀態計算完成就持續以二進制形式表示。儘管從實現的角度來看沒那麼複雜,但是需要協調所有節點運行者,並且幾乎可以肯定會給網絡帶來一些(有限的)中斷,這可能會影響過渡期間開發者和用戶的體驗。另一方面,對於更長遠的eth2過渡計劃來說,該過程具有一定的參考價值。

不管選擇哪種過渡策略,二進制樹都會是見證的基礎結構,即構成狀態樹的哈希的順序和層次。如果不進行優化,通過粗略計算(2020年1月),十六進制樹結構中見證的大小將從約800—3400 kB減小到約300—1400 kB。

代碼分塊 (merkleization)

見證的一個主要組成部分就是代碼。如果不進行代碼分塊,包含合約調用的事務將需要該合約的完整字節碼,以驗證其codeHash。代碼大小取決於合約,可能會是非常龐大的。代碼的‘merkleization’是一種拆分合約字節碼的方法,只需要生成代碼的一部分即可生成並驗證交易的見證,這是一種大大減小見證平均大小的技術。
拆分合約代碼有兩種方法,目前還不清楚兩者是否互斥。

“靜態”分塊。將合約代碼拆分為固定大小(約32個字節)。為了使分塊後的代碼正確運行,這種方法還需要在每個代碼塊中包含一些額外的元數據。

“動態”分塊。根據代碼本身的內容將合約代碼拆分成多塊,並按照其中包含的特定指令(JUMPDEST)進行分割。

乍一看,“靜態”分塊方式似乎更可取,以避免抽象洩漏,即防止拆分後的代碼內容影響較低級別的代碼塊,這種情況在“動態”分塊方式中也可能出現。話雖如此,這兩種方式還尚待完全測試,因此都只是作為考慮選項。

零知識(ZK)見證壓縮

大約70%的見證都是哈希。也許可以使用ZK-STARK證明技術來壓縮和驗證那些中間哈希。目前有許多關於零知識相關的研究,但是它到底如何起作用,或者甚至會否起作用都還無法得到明確的答案。因此,從某種意義上講,這在主要的技術開發路線中屬於支線,或者說是不必要的升級。

EVM語義

我們之前簡單談到了避免“抽象洩漏”,由於它與EVM語義這一里程碑最為相關,因此在這裡我將展開闡釋一下為何這個概念如此重要。EVM是大型以太坊協議的抽象組成部分。從理論上講,EVM內部運作的細節對於整個大型系統的運作來說應該是不會產生任何影響的,並且反之亦然,系統發生的變動也不應該對抽象的EVM內部產生任何影響。

然而實際上,協議的某些方面的確會直接影響EVM的內部運作。Gas成本就是一個明顯的表現。智能合約(EVM抽象內)已通過GAS操作碼暴露了各種堆棧操作(EVM抽象外)的gas成本。Gas調度的變動可能會直接影響某些合約的性能,但它取決於具體情況以及合約如何利用其可以訪問的信息。

由於存在“洩漏”,因此必須謹慎變動gas調度和EVM執行,避免對智能合約產生意料之外的影響。這使我們必須面對和解決的現實問題,要設計零抽象洩漏的系統非常困難,並且1.x的研究者沒有從頭重新設計的時間和精力,他們需要在當前的以太坊協議範圍內進行工作,目前的虛擬狀態機抽象中只存在極少的洩漏現象。

回到我們的主題:見證的介紹將需要更改gas調度。

見證需要在網絡上生成和傳播,並且該活動需要囊括在EVM操作中。EVM語義里程碑的相關主題都與這些成本和激勵措施是什麼有關,又要如何對其進行估算,以及如何在對其他較高layers影響最小的情況下實現。

ETH1.x:如何通向无状态以太坊

見證索引/Gas計算

本節可能有許多細枝末節,幾句話可能無法解釋清楚,在之後我會更詳細地進行說明。目前,只需要知道每筆交易都只對區塊見證的一小部分負責。生成區塊的見證需要進行一些計算,計算由該區塊的礦工執行,因此就會產生相關的gas成本,由交易的發起方支付。

由於多個交易可能涉及到狀態的同一部分,因此尚不清楚如何最好地估算在廣播交易時生成見證的gas成本。如果交易方支付了見證生成的全部費用,我們可以想象這種情況:交易重疊時,區塊見證的同一部分可能會被多次支付。需要注意的是,這顯然不是一件壞事,只是需要更好地理解這種情況如何為gas激勵帶來真正的改變。

無論相關的gas成本是多少,見證本身都將需要成為以太坊協議的一部分,並且可能需要併入每個區塊成為標準組成部分,就像在每個區塊頭中加入witnessHash這一條信息。

UNGAS/無版本以太坊

這一類別主要是與無狀態以太坊正交的升級,與EVM中的gas成本有關,並且可以彌補我提到的抽象洩漏。UNGAS指“無法觀測的gas”(unobservable gas),這是一項修改,明確禁止合約使用GAS操作碼,以防止智能合約開發者對gas成本進行任何預測。UNGAS是

以太坊核心文件[4] 中的建議之一,以彌補部分洩漏,使將來對gas調度的更改更易於實施,尤其是與見證和無狀態以太坊有關的更改。

狀態可用性

無狀態的以太坊不會完全消除狀態,而是使狀態成為可選項,從而在跟蹤和計算的狀態量方面賦予客戶端一定程度的自由。因此,必須在某個地方提供完整狀態,如此一來節點就可以從完整狀態中下載部分狀態。

從某種意義上來說,現有的範例(例如快速同步)已經提供了此功能。但是零狀態節點和部分狀態節點的加入使新節點的速度問題變得更加複雜。目前,由於所有節點都保留了當前狀態的副本,因此新節點可以從其連接的任何正常節點處下載狀態。但是,如果某些節點是零狀態節點或部分狀態節點,該假設就不再成立。

達成狀態可用性里程碑的前提條件與這些因素相關:節點如何相互告知對方擁有哪些狀態;如何在持續變化的點對點網絡中可靠地傳遞這些狀態。

ETH1.x:如何通向无状态以太坊

網絡傳播規則

下圖展示了無狀態以太坊中可能存在的網絡拓撲假設。在該網絡中,節點將需要具備這樣一種能力:根據其想要保留的狀態的部分(如果有的話)來對自己進行定位。ETH1.x:如何通向无状态以太坊

諸如EIP 2465[5] 之類的改進屬於網絡傳播規則的一般類別:網絡協議中的新消息類型,可表明節點擁有哪些信息,並定義如何將該信息傳遞給其他節點,而這些節點可能處於較差或有限的網絡中。

數據傳遞模型/DHT路由

如果上述消息類型之類的改進被接受並實現,節點將能夠輕鬆判斷其他節點保留了哪些狀態部分。如果所有連接的節點都不具有該節點所需的狀態怎麼辦?

數據傳遞是一個開放性問題,有許多潛在的解決方案。一個“主流”的解決方案就是通過雲服務器的HTTP請求提供部分或全部狀態。一個更有野心的解決方案是採用相關點對點數據傳遞方案中的功能,允許對部分狀態的請求由連接的節點代理,並通過分佈式

哈希表[6]查找正確的歸屬地。

這兩個極端方案在本質上並非不兼容,所以魚與熊掌為何不能兼得?

狀態切片(tiling)排布

改善狀態分佈的一種方法是將完整狀態分解為多個可管理的部分(切片),將其存儲在網絡緩存中,這些緩存可以為網絡中的節點提供狀態,從而減輕了全節點的負擔。即使是相對較大的狀態切片,區塊之間的部分狀態切片可能會保持不變。

Geth團隊對此進行了一些實驗,實驗表明狀態切片有助於改進狀態截圖的可用性。

鏈修剪(pruning)

目前已經有許多關鏈修剪的文章[7],此處就不再贅述。但還是要明確一點,只有通過狀態切片和/或DHT路由方案這類解決方案,使新的全節點隨時可以使用歷史狀態截圖的情況下,全節點才能安全地修剪歷史數據,例如交易收據、日誌和歷史區塊。

網絡協議規範

最後,無狀態以太坊的完整版圖將成為關注焦點。見證範式、EVM語義和狀態可用性這三個里程碑共同構成了網絡協議規範的完整描述:定義明確的升級應編碼到每個客戶端實現中,並在接下來的硬分叉中進行部署,以使網絡進入無狀態範例。

本文已經包含了很多背景知識,但圖中還有一些細微之處需要解釋:

♦️ 正式的無狀態規範

總言之,我們並不必對完整的無狀態協議進行正式定義。直接將參考實現編碼,並用作所有客戶端重新實現的基礎,這也是合理的。但是,為見證和無狀態客戶端創建“正式”規範有著不可置否的好處。這實際上可以作為以太坊黃皮書的擴展或附錄,因為規範將精確詳細地描述以太坊無狀態客戶端實現的預期行為。

♦️ 優化Beam Sync、Red Queen’s Sync及其他狀態同步方式

同步方式不是網絡協議的關鍵部分,但卻是影響有效節點如何執行協議的細節。Beam Sync和Red Queen’s Sync有助於創建來自見證的狀態的本地副本。在決定並實施網絡協議的最終版本時,我們需要改進同步方式,以使其適應網絡協議。

目前,這還是科技樹中的“增益”項目,因其可以獨立於其他主題進行開發,並且其實現細節取決於更基礎的因素,例如見證範式。值得注意的是,由於這些協議外的主題無關於“核心”更改,因此有助於實施和測試科技樹左側的根本改進項。

結語

看到這裡,我們把科技樹從左到右都梳理了一遍。我希望“科技樹”中的主題,里程碑以及總體思路有助於釐清“無狀態以太坊”的研究範圍。

我希望能根據實際進展來更新科技樹的結構。

正如之前所說,這不是“官方”或“最終”的工作範圍,只是目前最為準確的草圖。如果您有任何改進意見,請與我聯繫。

如果您有疑問,希望提出新主題或加入無狀態以太坊的研究工作,請在ethresear.ch上進行自我介紹,或在Twitter上聯繫@gichiba或@JHancock。

文內鏈接:

[1] https://en.wikipedia.org/wiki/Technology_tree

[2] https://blog.ethereum.org/2020/01/17/eth1x-files-digest-no-2/

[3] https://en.wikipedia.org/wiki/Ship_of_Theseus[4] https://corepaper.org/ethereum/#proposals

[5] https://github.com/ethereum/EIPs/issues/2465

[6] https://en.wikipedia.org/wiki/Distributed_hash_table

[7] https://gist.github.com/karalabe/60be7bef184c8ec286fc7ee2b35b0b5b


分享到:


相關文章: