硬剛馬斯克,為何不能簡單地“將區塊大小增加10倍?”

買賣虛擬貨幣

撰文:Vitalik Buterin

編輯:南風

特別感謝 Felix Lange, Martin Swende, Marius van der Wijden 和 Mark Tyneway 的反饋和審查。

你能把區塊鏈的可擴充套件性推進到什麼程度?你真的能像埃隆·馬斯克所希望的那樣,“將出塊時間加快 10 倍,將區塊大小增加 10 倍,從而將費用降低 100 倍”,而不導致極度的中心化,且不損害區塊鏈的基本屬性嗎?如果不能,區塊鏈的可擴充套件效能達到何種程度?如果你改變共識演算法呢?更重要的是,如果你更改技術以引入 ZK-SNARKs 或分片 (sharding) 等特性,那會如何呢?理論上來說,一條實施分片的區塊鏈可以持續新增更多的分片 (shards),那麼是否可以增加非常多的分片呢?

事實證明,有一些重要且相當微妙的技術因素限制了區塊鏈的擴容,無論是否實施了分片。在很多情況下,我們都會有相應的可擴充套件性解決方案,但即使存在解決方案也會有侷限性。本文將介紹這些問題。

只是增加引數,所有問題都解決了。但代價是什麼?

讓普通人能夠執行節點,這對於區塊鏈的去中心化至關重要

凌晨2點35分,你接到了來自世界另一端的搭檔的緊急電話,這個搭檔幫助管理你們的礦池 (也可能是一個質押池)。你的搭檔告訴你,大約14分鐘前,你們的礦池和其他幾個礦池從區塊鏈上分裂出來了,而這條鏈仍然擁有 79% 的網路共識節點。根據你的節點,這條擁有大多數節點的區塊鏈的區塊是無效的。且發生了餘額錯誤:金鑰區塊似乎錯誤地將 450 萬枚額外的幣分配給了一個未知的地址。

一小時後,你與另外兩個和你一樣被打了個措手不及的小礦池,還有一些區塊瀏覽器和交易所,在 Telegram 上聊天。最後你看到某人在聊天中貼上出了一條推文連結,這條推文的開頭寫道:“新的鏈上可持續協議發展基金正式釋出。”

到了早上,在 Twitter 上的爭論,以及在某個不審查討論的社羣論壇上,到處都在討論。但到那時,這 450 萬枚幣中的很大一部分已經在鏈上轉換為其他資產,併發生了數十億美元的 DeFi 交易。這 79% 的共識節點、所有的主要區塊瀏覽器和輕錢包端點都在跟隨這條新鏈了。也許新的開發基金將資助一些開發專案,或者也許這些資金將全部被領先的礦池、交易所以及他們的親信侵吞。但無論結果如何,該基金在所有意圖和目的上都是既成事實,普通使用者沒有辦法反擊。

好戲即將上演。也許它可以由 MolochDAO 或其他機構資助。

這可能發生在你的區塊鏈上嗎?你的區塊鏈社羣的精英,包括礦池、區塊瀏覽器和託管節點,可能是非常協調一致的;很可能他們都在同一個 Telegram 群和微信群。如果他們真的想要組織一次突然的協議規則更改以助長他們自己的利益,那麼他們可能可以做到。以太坊區塊鏈曾在 10 小時內完全解決了一次共識失敗問題;如果你的區塊鏈只有一個客戶端實現,並且你僅需將程式碼更改部署到幾十個節點,那麼協調一次對客戶端程式碼的更改可以更快地完成。要讓這種協調的社會攻擊無效,唯一可靠的方法是透過一個去中心化的選民陣營來進行被動防禦,也即使用者。

想象一下,如果使用者在執行驗證區塊鏈的節點 (無論是直接執行節點還是透過更高階的間接技術),且節點自動拒絕接受那些違反了協議規則的區塊,即使超過 90% 的礦工或者質押者 (stakers) 支援這些區塊,那麼故事將如何發展呢?如果每個使用者都執行一個驗證節點,那麼這場攻擊將很快就會失敗:一些礦池和交易所會以分叉的方式退出,使他們在這一過程中看起來非常愚蠢。但是,即使有一些使用者執行驗證節點,攻擊也不會使攻擊者獲得徹底的勝利;相反,這會導致混亂,不同的使用者會看到不同的區塊鏈檢視。至少,隨之而來的市場恐慌和可能持續的鏈分裂將大大減少攻擊者的利潤。駕馭這樣一場持久的衝突的想法本身就能阻止大多數襲擊。

看看 Hasu 對此的看法。

如果你的社羣由 37 個節點執行者和 80000 個負責檢查簽名和區塊頭的被動監聽器,那麼攻擊者會獲勝;但如果你的社羣中每個人都執行一個節點,那麼攻擊者就會失敗。我們不知道群體對協同攻擊產生免疫的確切閾值是多少,但有一件事是絕對清楚的:節點越多越好,越少越糟糕,且我們肯定需要不止幾十個或幾百個節點。

那麼,我們可以要求全節點執行多少工作量的限制是什麼?

為了最大化能夠執行節點的使用者數量,我們將重點關注常規消費級硬體。透過要求 (使用者) 購買一些容易獲得的專門硬體 (例如透過亞馬遜購買) ,可以實現一些網路容量的增加,但是實際上這並沒有給擴充套件性帶來太多增加。

全節點 (full node) 處理大量交易的能力存在三個關鍵的限制:

算力:可以安全地佔用多少比例的 CPU 能力來執行一個節點?

頻寬:根據當前網際網路連線的實際情況,一個區塊可以包含多少位元組?

儲存:我們可以要求使用者的磁碟有多少 GB 用來儲存?另外,讀取速度必須有多快?(也即,HDD 是否足夠?還是我們需要 SSD?)

對於區塊鏈透過使用“簡單的”技術能夠擴容到什麼程度,許多錯誤的結論都源於對上述這些數字的估計過於樂觀。我們可以逐一分析這三個因素:

計算能力

錯誤的回答:100% 的 CPU 能力可被用於區塊驗證;

正確的回答:~5-10% 的 CPU 能力可被用於進行區塊驗證。

之所以限制如此之低,有四個關鍵原因:

我們需要一個安全邊際來應對 DoS 攻擊的可能性 (攻擊者利用程式碼中的弱點來設計交易,使其比常規交易需要更長的處理時間);

節點能夠在離線之後同步區塊鏈。如果我離線網路一分鐘,我應該能夠在幾秒鐘內再次同步;

執行一個節點不應該太快耗盡你的電池電量,因為這會使你的其他應用程式的執行非常緩慢;

節點還需要完成其他非區塊生產的任務,主要圍繞驗證和響應 P2P 網路上傳入的交易和請求。

請注意,直到最近,大多數關於“為什麼只使用5-10%?”的解釋都集中在一個不同的問題上:因為 PoW 的出塊是隨機的,需要很長時間來驗證區塊,從而增加了同時建立多個區塊的風險。有很多方法可以解決這個問題 (比如 Bircoin NG,或者使用 PoS),但是這些解決方式不能解決其他四個問題,因此不能像許多人最初認為的那樣在可擴充套件性方面獲得很大的好處。

並行化 (parallelism ) 也不是萬能的。通常,即使是看似單執行緒區塊鏈的客戶端也已經被並行化了:簽名可能由一個執行緒進行驗證,而執行由其他執行緒完成,並且有一個單獨的執行緒在後臺處理交易池邏輯。所有執行緒的使用率越接近 100%,執行節點的能耗就越高,抵禦 DoS 的安全邊際也越低。

頻寬

錯誤的回答:如果我們每 2-3 秒就處理 10 MB 的區塊,那麼大多數使用者的網路速度都超過10 MB/秒,因此他們當然可以處理這樣的區塊。

正確的回答:也許我們可以每 12 秒處理 1-5 MB 的區塊,儘管這已經很困難了。

如今,我們經常聽到關於網際網路連線能提供多少頻寬的廣告資料:100 Mbps 甚至 1 Gbps 都很常見。然而,廣告中的頻寬和預期的實際頻寬之間有很大的差異,原因如下:

1)“Mbps”指的是“百萬位元每秒”;位元 (bit) 是位元組的 1/8,因此你需要將廣告中的位元數除以 8 來得到位元組數。

2) 就像所有的公司一樣,網際網路供應商經常撒謊。

3) 總是有多個應用程式使用同一個網際網路連線,所以一個節點無法獨佔整個頻寬。

4) P2P 網路不可避免地引入了其自身的開銷:節點通常最終會多次下載並重新上傳同一個區塊 (更不用說交易在被打包進入某個區塊之前會透過交易池 (mempool) 被廣播)。

Starkware 在 2019 年做了一個實驗,他們首次釋出了 500 kB的區塊,因為當時在交易資料 Gas 成本的降低首次使這種可能性成為可能,但實際上一些節點無法處理這種大小的區塊。此後,處理較大區塊的能力已經得到了改善,並將繼續得到改善。但無論我們做什麼,我們還遠不能簡單地以MB/秒為單位獲取平均頻寬,讓自己相信我們可以接受1秒的延遲,並且能夠擁有那麼大的區塊。

儲存

錯誤的回答:10 TB

正確的回答:512 GB

正如你可能猜到的那樣,這裡的主要爭論與其他地方一樣:理論和實踐之間的差異。理論上,你可以在亞馬遜上買到 8TB 的固態硬碟 (你確實需要 SSD 或 NVME;HDD 儲存區塊鏈狀態太慢)。但實際上,用來寫這篇博文的膝上型電腦有 512 GB,如果你讓人們去買他們自己的硬體,他們中的許多人會懶得去購買 (或者他們買不起 800 美元的 8TB SSD),而是使用某個中心化的提供商。即使你可以把區塊鏈放入某個儲存空間,高水平的活動也可以輕鬆地快速燒錄到磁碟上,迫使你不斷地購買新的磁碟。

區塊鏈協議研究人員對每個人擁有多少磁碟空間發起的投票。樣本量小,我知道,但仍然可以說明問題…

此外,儲存大小 (storage size) 決定了新節點能夠聯機並開始參與區塊鏈網路所需的時間。現有節點必須儲存的任何資料都是新節點必須下載的資料。這個初始同步時間 (和頻寬) 也是使用者能夠執行節點的主要障礙。在寫這篇部落格的時候,同步一個新的 geth 節點花了我大約 15 個小時。如果以太坊的使用量超過 10 倍 (即意味著資料量增加10倍),那麼同步一個新的 geth 節點將需要至少一週的時間,而且更有可能導致你的網際網路連線受到限制。在攻擊期間,這一點更加重要,因為對攻擊的成功響應可能會涉及到許多使用者在之前沒有執行節點的情況下執行新節點。

互動效應

此外,這三種成本 (計算能力、頻寬 & 儲存) 之間存在互動效應 (interaction effects)。由於資料庫在內部使用樹結構 (tree structures) 來儲存和檢索資料,因此從資料庫中獲取資料的成本隨著資料庫大小的對數而增加。實際上,由於頂層 (或頂部的幾層) 可以快取到 RAM 中,因此磁碟訪問成本與資料庫大小成正比,是快取在RAM中的資料大小的好幾倍。

不要從字面上理解這個圖表;不同的資料庫以不同的方式工作,記憶體中的部分通常只是一個單一 (但很大) 的層 (參見 leveldb 中使用的 LSM 樹)。但基本原理是一樣的。

舉個例子,如果快取是 4 GB,我們假設資料庫的每一層都比前一層大4倍,那麼以太坊當前的~64GB 狀態將需要~2次訪問。但是如果狀態大小增加 4倍 到 ~256 GB,那麼這將增加到~3次訪問。因此,增加 4 倍的 Gas 上限實際上意味著增加 ~6 倍的區塊驗證時間。其影響可能更大:硬碟滿的時候比幾乎空的時候需要更長的時間來讀寫。

那麼,這對以太坊意味著什麼?

今天在以太坊區塊鏈中,執行一個節點對許多使用者來說已經是一個挑戰,雖然至少在常規硬體上仍然是可能執行 (我在寫這篇文章時剛剛在我的膝上型電腦上同步了一個節點!) 因此,我們接近遇到瓶頸。以太坊核心開發人員最關心的問題是儲存大小 (storage size)。因此,目前勇敢地努力解決計算和資料的瓶頸,甚至改變共識演算法,都不太可能使得 Gas 上限的大幅提高被接受。即使解決了以太坊最大的未解決的 DoS 弱點,也只會使 Gas 上限增加了20%。

儲存大小問題的唯一解決方案是無狀態性 (statelessness) 和狀態保質期 (state expiry)。無狀態性允許一類節點在無需維護永久性儲存的情況下驗證區塊鏈;狀態保質期會從狀態中移除那些近期沒有被訪問的狀態物件,迫使使用者手動提供證明來更新它。這兩種方法已經被研究了很長一段時間,關於無狀態性的概念驗證實現已經開始。這兩種改進結合起來可以極大地緩解這些問題,併為顯著提高 Gas 上限開闢了空間。但即使在無狀態性和狀態保質期被實施之後,Gas 上限可能也只能安全地增加 3 倍,直到其他限制開始占主導地位。

分片之後會發生什麼?

分片從根本上解決了上述限制,因為它將區塊鏈上包含的資料與單個節點需要處理和儲存的資料解耦。節點不是透過自己下載和執行區塊來驗證區塊,而是使用先進的數學和密碼技術來間接驗證區塊。

因此,實施分片的區塊鏈可以安全地擁有非常高的交易吞吐量,而非分片區塊鏈不能。這確實需要大量的密碼學智慧來建立替代當前這種 (單個節點) 執行全部驗證的方式,併成功地拒絕無效區塊,但這是可以做到的:理論已經很完善,基於Eth2規範草案的概念證明已經在研究中。

以太坊正計劃使用二次分片 (quadratic sharding),由於節點必須能夠同時處理單個分片和信標鏈,而信標鏈必須為每個分片執行一定量的管理工作,因此總體的可擴充套件性受到了限制。如果分片太大,節點就無法再處理單個分片,如果分片數量太多,節點就不能再處理信標鏈。這兩個限制因素帶來了可擴充套件性的上限。

可以想象,透過三次分片 (cubic sharding),甚至指數分片 (exponential sharding),我們可以更進一步。在這樣的設計中,資料可用性抽樣肯定會變得複雜得多,但這是可以做到的。但以太坊只走了二次分片路線。原因是,我們從 shards-of-transactions (交易分片) 到 shards-of-shards-of-transactions (交易分片的分片) 獲得的額外可擴充套件性提升,是無法在不使其他風險高得不可接受的情況下實現的。

那麼這些風險是什麼呢?

1)最少節點數

可以想象,只要有一個使用者 (節點) 願意參與其中,一條非分片的區塊鏈就可以執行。但實施分片的區塊鏈不是這樣的:沒有任何單個節點可以處理整條鏈,所以你需要足夠的節點,讓它們至少可以一起處理這條鏈。如果每個節點可以處理 50 TPS,而整條鏈可以處理 10000 TPS,那麼這條鏈至少需要 200 個節點才能存活。如果這條鏈在任何時候少於 200 個節點,那麼要麼節點無法跟上這條鏈,要麼節點無法檢測到無效區塊,或者可能發生許多其他糟糕的事情,這取決於節點軟體的設定方式。

在實踐中,由於需要冗餘 (包括資料可用性抽樣),安全的最少節點計數要比單純的“區塊鏈的TPS除以單個節點的TPS”高出好幾倍;就上面的例子而言,不妨說需要 1000 個節點。

如果分片區塊鏈的容量增加了10倍,那麼最少節點數也增加10倍。現在,你可能會問:為什麼我們不從一點點容量開始,只在我們看到大量節點時才增加容量,然後在節點數量下降時減少容量?

這有幾個問題:

區塊鏈本身不能可靠地檢測它有多少唯一節點,因此這需要某種治理來檢測和設定分片計數。而對容量限制的治理很容易成為分裂和衝突的根源。

如果許多節點同時突然意外退出該怎麼辦?

增加啟動分叉時所需的最少節點數量會使防禦惡意接管變得更加困難。

幾乎可以肯定,如果需要的最少節點計數小於 1,000 幾乎是沒問題的。另一方面,如果需要至少 100 萬的節點數肯定是不行的。即使需要的最小的節點計數是1萬,也開始變得有風險了。因此,似乎很難證明一個實施分片的區塊鏈擁有超過幾百個分片的合理性。

2)歷史可檢索性

使用者真正看重區塊鏈的一個重要屬性是永久性 (permanence)。當公司破產或失去了維護生態系統的興趣,儲存在某個伺服器上的數字資產可能會在10年後停止存在。而另一方面,以太坊上的 NFT 是永久性的。

是的,到了2371年,人們還會下載並檢查你的加密貓。

但一旦區塊鏈的容量太高,就很難儲存所有這些資料,直到某個時刻,區塊鏈歷史記錄的某個部分最終不再被任何人儲存。

量化這種風險很容易。以區塊鏈的資料容量MB/秒為單位,乘以~30就得到每年以 TB 為單位儲存的資料量。目前的分片計劃的資料容量約為 1.3 MB/秒,因此大約為 40 TB/年。如果資料容量增加10倍,這就變成 400 TB/年。如果我們希望資料不僅可以訪問,而且可以方便地訪問,我們還需要後設資料 (例如解壓 rollup 交易),那麼每年就是 4 PB,10年後 40 PB。相比較而言,目前網際網路檔案 (Internet Archive) 使用 50 PB。這是一個合理的分片區塊鏈的安全資料量上限。

因此,看起來在這兩個維度上,以太坊分片設計實際上已經大致以相當接近合理的最大安全值為目標。常量可以增加一點,但不能增加太多。

總結

有兩種方法可以嘗試擴充套件區塊鏈:基本的技術改進 & 簡單地增加引數。一開始,增加引數聽起來非常吸引人:如果你在餐巾紙上計算一番,很容易說服自己一臺消費型膝上型電腦每秒可以處理數千筆交易,不需要 ZK-SNARKs 或 rollups 或分片。不幸的是,有許多微妙的原因導致這種方法從根本上是有缺陷的。

執行區塊鏈節點的計算機不能使用 100% 的 CPU 能力來驗證區塊鏈;它們需要很大的安全邊際來抵禦意外的 DoS 攻擊,需要空閒容量來處理交易池中的交易等任務,並且你不希望在計算機上執行一個節點導致該計算機同時無法用於執行任何其他應用程式。頻寬也有類似的開銷:一個 10MB/秒的網際網路連線並不意味著你每秒可以擁有一個 10MB 的區塊!也許每12秒才能有1-5 MB 的區塊。儲存也是如此:增加執行節點的硬體需求並將節點執行限制於專業的參與者並不是一種解決方案。要想讓區塊鏈實現去中心化,讓普通使用者能夠執行節點並擁有一個使執行節點成為常見活動的文化是至關重要的。

另一方面,基礎技術的改進是可行的。目前,以太坊的主要瓶頸是儲存大小 (storage size),無狀態性 (statelessness) 和狀態保質期 (state expiry) 可以解決這個問題,並允許其容量增加到大約 3 倍,但不會更多,因為我們希望執行節點比現在更容易。對區塊鏈實施分片可以進一步擴充套件,因為一個實施分片的區塊鏈中的任何單個節點都不需要處理每筆交易。但即使這樣,容量也是有限制的:隨著容量的增加,最少安全節點數量也會增加,而歸檔整條的成本 (以及如果沒人願意去對鏈進行歸檔,資料存在丟失的風險) 也會增加。但我們不必太擔心:這些限制足夠高,我們可能安全地使用區塊鏈每秒處理超過 100 萬筆交易。但在不犧牲去中心化的前提下做到這一點需要付出努力,而正是去中心化讓區塊鏈變得如此有價值。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;