區塊鏈公鏈如何才能快起來 (一)

從 2008 年 11 月中本聰(Satoshi Nakamoto)發表論文「Bitcoin: A Peer-to-Peer Electronic Cash System」算起,比特幣即將迎來第一個十週年。這十年中,比特幣與其背後的區塊鏈技術蓬勃發展,以去中心化技術之名,大有變革整個在線數字世界的氣勢和雄心。

不過,雄心歸雄心,正蓬勃發展的區塊鏈技術,尤其是公鏈領域,有一個瓶頸卻一直有待突破:以當今數字世界的規模和體量,任何一個在線系統,如果沒有一個大容量、高吞吐的基礎設施,就無法承載哪怕僅僅一個互聯網級別的應用。

很可惜,中本聰的論文中完全沒有考慮到這個問題,也許是走出這第一步實屬不易,他也沒想太多之後的事情,也許是這樣的一個高性能的設計,在徹底去中心化的系統中難度太大。總之,近 10 年過去了,爲了提高區塊鏈系統的性能,前赴後繼出現了大把項目,但到今天爲止,並沒有出現能夠承載互聯網級別應用的解決方案。

這是一個世界性的難題,全世界最聰明的學者、開發者都在嘗試解決這個問題。我曾在微軟工作多年,擔任微軟研究院主管研究員,很長一段時間專注於分佈式系統方面的研究;離開微軟之後,我又在創新工場擔任負責區塊鏈和人工智能投資方向的執行董事。多年在分佈式系統方面的研究心得,以及在區塊鏈投資領域評估多個公鏈項目的經驗,讓我深深明白,在徹底去中心化的系統中實現高性能設計,是一項難度極高、極具挑戰的工作。

我看到行業內存在大量對於區塊鏈公鏈性能瓶頸及解決方法的討論,有些充滿洞見,令人受益匪淺,但也有不少謬誤,更有很多爲了自身項目宣傳而編造的似是而非的見解,頗有把討論引入歧途的風險。在和多位該行業頂尖的學者、開發人員、投資人多次深入交流之後,他們都鼓勵我把自己的看法分享出來。再三思索之後,我決定把自己對該話題的一些拙見記錄下來,這樣既可以讓自己的一些思考能夠沉澱,同時,也希望能和對該話題感興趣的更多同仁進行一些探討。

1 不要只關注性能瓶頸,而忽略了容量瓶頸

先說一下我的一個結論:在當前以類金融爲主流應用場景的情形下,區塊鏈系統最首要的性能瓶頸是區塊數據的廣播延遲造成的,本質上受限於互聯網的帶寬和通訊延遲,這一點直接制約了吞吐量 (TPS)。只要是「Chain of Blocks」的系統,無論具體採用了什麼共識算法,無論是工作量證明(POW)、權益證明(POS)、拜占庭容錯(BFT),還是委託權益證明(DPOS),在出下一個區塊之前,都需要保證前一個區塊在全網有一定的同步率,從而約束了每個區塊不能太大,出塊頻率也不能太高,然後,這個問題無解。

請注意,這裏說的區塊鏈系統特指「Chain of Blocks」的系統,其特徵是要保證系統能最終收斂到一條單一的鏈表結構,並只有這條鏈上面的區塊纔是被確認的,反例是「Graph of Blocks」系統,例如所採用的 DAG 結構 IOTA。

假設物理網絡的帶寬和延遲可以被忽略,例如基於數據中心高速鏈路的 EOS,系統第二個瓶頸是受限的賬簿容量,本質上受限於單臺全節點的內存容量,這一點直接制約了鏈上可以承載多少個用戶(地址)以及多少個 DApp。無論具體採用了什麼共識算法,只要交易驗證 / 執行過程隨時可能涉及到任何一個用戶,那麼單臺全節點就必須隨時保持全網每一個用戶、每一個 DApp 相關的狀態在內存裏面,以供交易驗證實時訪問。當前所有主流的「Chain of Blocks」的系統,包括比特幣區塊鏈、以太坊、EOS 等,都有這個問題,並且同樣的,這個問題也是無解的。多級緩存的數據庫技術 (例如 RocksDB) 可以稍微改善一下這個限制,使得只有活躍用戶受到內存限制,而總用戶基數受限於硬盤的容量。但是這並不從根本上解決問題。

「容量」這個問題的關注度遠遠少於吞吐量,原因很簡單:因爲吞吐量這個短板還沒解決,所以容量問題被掩蓋住了。請記住,一旦吞吐量實現了大幅提升,容量問題馬上就會出現:在一個高吞吐的系統上,如果用戶量上不去,很可能高性能根本跑不滿。

一個典型的例子是 EOS。當 EOS 以喪失去中心化特性爲代價而解決了吞吐量問題之後,容量的問題馬上就凸顯出來了。然後,EOS 把賬簿容量瓶頸這個問題包裝成了一個稀缺資源,並將其代幣化,成了 EOS RAM 虛擬幣。當然除了內存,單臺全節點 CPU 也會成爲容量的瓶頸,所以也被代幣化,成了 EOS CPU 虛擬幣。不過,在類金融應用場景中,通常計算複雜度非常低,所以,內存會是主要瓶頸。

另外,我的另外一個觀點是:共識算法其實幫不了解決性能和容量的瓶頸,試圖從標新立異的共識算法出發,提升「Chain of Blocks」系統性能的努力,基本上不會讓系統性能有實質上的大幅提升。總之,解決上面所提及的兩個瓶頸問題,需要的是分佈式系統設計上的巧思妙想,這和共識算法相關,也和密碼學相關,但是本質的出發點不是共識算法和密碼學。

2 性能瓶頸 : 一個出塊節點在做什麼

首先出塊節點也是全節點,接受全網的已確認區塊以及未確認交易,並構造成鏈,不斷維護賬簿的最新狀態,然後抓緊機會試圖在鏈尾追加新的區塊。無論採用哪種共識算法,都會歷經以下幾個步驟 :

- 第一個步驟,根據賬簿的最新狀態,在未確認交易集合中選出若干驗證合法的交易,然後構造一個新的區塊;

- 第二個步驟,爲這個新的區塊,參與出塊的權力的競爭或者候選,在這個階段,大概率會因爲賬簿狀態更新了 (其他節點成功出塊了) 而中斷,回到第一步;

- 第三個步驟,獲得出塊的權力之後,向全網廣播這個新的區塊,更新賬簿狀態,回到第一步。

不同的共識算法,其核心差異在於如何完成其中的第二個步驟的出塊權的競爭或者候選。但是無論哪種共識算法,都有一個不可調和的性能矛盾,本質上由區塊數據的廣播延遲導致。這個矛盾使得如果每次出塊比較大 (可以包含更多的交易),就必須有比較長的出塊間隔,以保障該區塊在下一次出塊之前,在全網被充分傳播。

如果傳播不充分,在 PoW 和 PoS 系統中,將表現爲較高的分叉率(出了無效的塊),而在 BFT 系統中則表現爲較高的失敗率(區塊拿不到 2/3 的同意票)。

2.1 Proof-of-Work 和 Proof-of-Stake

PoW 通過設定一個 Hash Target,要求 Hash 值必須小於一個特定的值(例如,將 256 位的 Hash 值當成一個大整數看待)。而 Hash 值必須根據新區塊數據拼合一個 Nonce 數據計算而得。找到滿足 Hash Target 對應 Nonce 的任何一個節點,便獲得了出塊的權力。由於只能通過隨機窮舉的方式找 Nonce,所以這個競爭就轉換成了計算 Hash 的算力的競爭。PoS (如 Peercoin)是 PoW 的一個變種,引入了消耗 Coin Age 來增大 Hash Target 的機制,使得出塊權力的競爭可以部分地被數字貨幣持有的時間和數量所代替。

可以看到,PoW 機制最大的好處是用一個簡潔的算法,實現了完全非許可(premissionless)的出塊權隨機指定,競爭節點之間完全不需要協同和通訊,可以輕鬆支持任意數量的出塊節點共同競爭,具有極佳的去中心特性。也正是由於這一點,這個算法導致了區塊廣播延遲和出塊間隔之間的矛盾。當出塊間隔較短時,一個新的區塊尚未充分全網廣播之前,就有另一個礦工在同樣的高度出了另一個新的區塊,即發生了所謂的分叉 (Fork)。這種情況下,最終其中一個區塊會被拋棄掉 (ophaned)。發生這種情況的概率不能太高,否則會顯著降低原爲 51% 的算力攻擊基準 (Selfish Mining),極端情況甚至會導致分叉始終無法到達穩定收斂。

區塊廣播延遲主要由區塊大小和全網各個節點間的帶寬決定。當前的互聯網環境,大致需要 10 秒可以廣播到 90% 以上的節點。所以在比特幣網絡中,10 分鐘左右的出塊間隔使得區塊分叉的概率極其低。2018 年整個上半年,僅出現兩次分叉。而在以太坊網絡中,15 秒左右的出塊間隔使得區塊分叉的概率始終保持在 10% 左右,即使其區塊遠小於比特幣的區塊。要注意一點,PoW 的出塊間隔是統計意義上的,實際情況是出塊間隔時大時小,而統計期望是 10 分鐘。這個並不是全網算力波動造成的,而是因爲搜索 Nonce 的過程是個隨機刺探過程 (撞大運),所以很多礦池都給出了自身的運氣值曲線,(笑 ...)。

對於比特幣網絡來說,10 分鐘的出塊間隔其實在現今的互聯網環境中是有很大保留的,要知道,畢竟這是在 10 年前提出的方案,這使得擴大區塊大小就可以實現簡單的擴容方案,但是由於區塊廣播延遲這一根本矛盾的存在,這種提升只在一定程度上有效。

另外,值得提一下 GHOST 協議。該協議給出了一個新的準則來判定分叉的時候,哪個叉是被接受的。其將中本聰最初提出的最長鏈原則, 改成了包含算力最多的子樹。兩個準則在分叉概率很低的時候是完全等價的,但是當概率比較高的時候 (比如 ETH 的 10% 分叉率),GHOST 協議可以規避 Selfish Mining,提高安全性。但是無論採用 GHOST 協議與否,對公鏈的性能無實質幫助。

PoW 帶來算力競爭,即所謂的挖礦,確實消耗了大量能源。不過這也爲 PoW 系統發行的每一個幣奠定了一個基礎成本,使之價值有個底線。需要指出的是,PoW 的算力和區塊鏈系統的性能沒有任何聯繫,任何加速 hash 算法的軟件或者硬件都不會提高區塊鏈系統單位時間的吞吐量。這就是爲什麼比特幣區塊鏈的全網 hash 算力提高了萬億倍,但是其吞吐量一直是 7 TPS 左右。

另外,任何宣稱節省挖礦能源的公開技術,都是不可能在實際上減少能源消耗的。因爲投入挖礦的能源總量在一個個礦場建立的時候已經確定,當有更高能效的挖礦技術或者設備出現時,算力競爭將導致所有礦工都應用新的技術,最終哄擡了全網的挖礦難度罷了。所以實際的總能源消耗,在宏觀上,只和幣價、電價以及數字貨幣的投資信心相關,和挖礦效率無關。

2.2 拜占庭容錯 (BFT)

拜占庭容錯類共識算法採用隨機算法確定每一次出塊的節點,根據賬簿上的數字貨幣地址,而不是 IP 地址。所有參與出塊候選的節點無須競爭。新的區塊將被委員會 (一組驗證者) 所有成員驗證並簽名 (投票),然後廣播全網,繼而開始下一個出塊的流程。

與 PoW 不同的是,BFT 出塊候選是一個協作的過程,期間至少涉及 O(n^2) 的通訊複雜度,而 PoW 在出塊競爭過程中無須任何通訊代價。基於 BFT 的協作過程將不會導致分叉,也不需要消耗稀缺資源 (算力或者 Coin Age),但是由於這個協作的過程涉及到相當多的數據通訊,所以這個過程無法在全網候選,驗證並簽名的過程無法在全網展開。這就是爲什麼 BFT 類算法一定會涉及到一個委員會的構建過程,並且驗證簽名只在一個小範圍裏面發生,剩下的人相信他們就好了。最近出現的很多基於 BFT 的公鏈項目,比如 Algorand,在如何安全公平的選出這個委員會方面做了很多工作,雖然這些工作對系統性能的提升沒有直接關係。

BFT 類算法的投票通常是有權重的,以規避女巫攻擊 (Sybil Attack)。而這個權重多與參與者的權益相關,和 PoS 的精神類似,進而現在很多人將 BFT 的這類投票算法稱爲了 PoS 算法。而事實上,BFT 類共識算法和一開始提出的 PoS 算法 (例如 Peercoin) 是本質不同的機制。

上面我們提到,不同的 BFT 類算法其具體選定出塊節點以及委員會成員的過程和系統的性能關係不大。和 PoW/PoS 類似,其吞吐性能同樣決定於每次出塊的大小,以及出塊的週期。在 BFT 系統中,如果想要允許每次出塊比較大,就需要出塊的週期也比較大,從而大概率保證新出的塊及其委員會的簽名數據在委員會內部完全傳播。如果這個傳播不充分,將可能導致委員會成員無法達成 2/3 以上的投票,進而使得委員會內部驗證並簽名過程超時,最終在本出塊的週期內出塊失敗。

理論上說,委員會的規模遠小於全網,BFT 類算法中的廣播延遲會比同等規模的 PoW/PoS 網絡小。事實上也確實如此,但是基於 Gossip 協議的廣播延遲和網絡規模的對數成正比而不是線性,所以廣播延遲並沒有小很多。加之 BFT 類算法依賴一些額外的週期性全局同步等安全措施,使得實際效果中,BFT 類算法並沒有比 PoW/PoS 系統有太多性能優勢。

2.3 小結

PoW/PoS 系統每個出塊週期需要充分傳播一個區塊 (例如 1MB), BFT 類系統每個出塊週期也需要充分傳播一個區塊,加上 所有委員會成員的簽名 (例如 128 個成員節點,至少每人 84*128B,總共 1.3MB 的樣子)。但是 PoW/PoS 系統的廣播範圍是全網 (例如幾萬個節點),而 BFT 系統的範圍限於委員會成員,這一點使得後者充分傳播的時間較短一些。

不過,基於 Gossip 協議實現充分傳播的時間,和傳播的數據量呈線性關係,和傳播的節點數量呈對數關係,所以 BFT 在傳播時延上也沒有太大的優勢。結果就是,無論哪種算法,都有不可調和的區塊大小和出塊間隔之間的矛盾,從而無法大幅提升性能。

3. 容量瓶頸 : 一個不出塊全節點在做什麼

單鏈的「Chain of Blocks」的系統中,大致有三種角色的節點 : 出塊的全節點,不出塊的全節點和輕量節點。全節點無論出塊與否,都會驗證並接力廣播新的區塊和未確認交易,這裏的廣播工作佔據了主要的通訊量以及磁盤 I/O 的負荷,對於 TPS 只有十幾的以太坊 (geth) 來說,這個通訊量約爲 1.5Mbps。

爲了可以實時完成對新區塊和未確認交易的驗證,所有用戶的賬簿以及所有智能合約狀態都需要駐留在內存中,這個佔據了主要的內存開銷,當前規模的以太坊會佔用將近 4GB 的內存。每一個全節點都會需要承擔這樣的一個負荷,如果要出塊 (PoW 的挖礦節點或者 PoS 的驗證節點) 還需要做額外的事情。這些負荷的代價,換來的是安全的徹底去中心化,任何一個全節點不需要預先信任任何其他節點,任何全節點也沒有能力去欺騙其他全節點。

普通全節點的價值體現在兩個方面:接力廣播合法的數據和維護全網賬簿的最新狀態以供用戶或者輕量節點查詢。例如手機錢包這樣的輕量節點不驗證也不接力廣播區塊數據或者未確認交易,它依賴並信任預先設定好的一個或者多個全節點,通過這些全節點來獲取特定用戶的狀態,例如賬戶餘額,以及發起轉賬交易。輕量節點自身完全沒有驗證信息真僞的能力,更像是區塊鏈世界裏的一個終端而已。

對於單鏈的「Chain of Blocks」的系統,如果系統的吞吐量 (TPS) 提升 100 倍,需要 150Mbps 的通訊量;或者用戶規模都擴大 100 倍,需要 400GB 的內存,那麼基本上大部分互聯網上的普通服務器都無法順利部署一個全節點了。全節點的參與門檻,是影響區塊鏈系統去中心化程度重要因素。如果全節點只能由專業礦場操作,普通人無法獨立部署一個全節點的話,那麼整個系統就會退化成一個多地部署的中心化雲服務了,而變得容易被攻擊,也容易被封禁。所以,這兩個瓶頸不僅僅對於出塊節點需要解決,對於普通全節點也需要解決。

4. 出路

前面已經說到性能瓶頸和容量瓶頸,在現在單鏈的「Chain of Blocks」的系統中,很難有大的提升,尤其是容量瓶頸。這就是所謂的區塊鏈不可能三角的由來。縱觀計算機技術發展史,大容量高吞吐的設計範式,屢獲大規模成功的只有一個,橫向擴展 (Scale-Out)。

舉個例子,GPU 用了幾千個性能普通的 Core 一起並行工作,實現超越 CPU 計算性能幾個數量級的性能提升,而 GPU 所依賴的半導體技術並沒有和 CPU 芯片有什麼本質的不同。再如,現今的在線雲服務系統,是用幾千甚至上萬臺性能普通的服務器一起並行工作,來支持大容量高吞吐的在線服務。

我在這裏不妨大膽設想:也許一個大容量高吞吐的區塊鏈系統會是類似的方案,即,讓成千上萬個同質的單鏈實例一起並行工作,切分全網的工作量,以實現整體上的大容量和高吞吐。

這樣的一個系統,可以在大幅提高 TPS 的同時,支持 10 億以上級別的用戶量,並且保持每一個參與到這個網絡的中的全節點僅有一個合理的負荷,讓大部分互聯網上的普通服務器都可以輕鬆部署一個全節點,共同參與網絡的維護和治理。

不過,在這樣一個徹底去中心化的設定下,如何一起並行工作,如何切分工作量,又如何保證每個單鏈實例的安全,都是極具挑戰的問題。這樣的系統似乎並不容易實現,但也絕非不可能實現。我先拋出這個想法,也歡迎所有有興趣的同仁共同思考,或批判,或貢獻聰明的設想。就這個想法,我也會繼續梳理,並繼續通過文字分享我的一些思考。歡迎大家通過我的公衆號「王嘉平」和知乎專欄「去中心化數字世界隨想」就這個話題展開更多討論。

來源鏈接:mp.weixin.qq.com