導言:
過去一兩年有許多號稱區塊鏈 3.0 的公鏈項目都宣稱克服了所謂不可能三角,但大體而言,至今尚未出現一個具信服力、并廣為接受的解方。不過,由分布式系統專家王嘉平等人提出的 Monoxide 擴容方案,近日獲計算機頂級學術會議 NSDI 2019 收錄。這是繼 2017 年著名的 AlgoRand 項目登上 SOSP 大會后,睽違近兩年再有區塊鏈公鏈論文投中計算機頂會。
王嘉平為微軟總部研究院前主管研究員,專注于分布式系統等領域研究。2016 年起他在創新工場擔任執行董事,負責區塊鏈和人工智能等投資方向,曾主導了對比特大陸的首輪機構投資,成為三大主要投資方之一。去年他曾發表“區塊鏈到底有什么了不起”等系列文章,梳理出為什么他相信區塊鏈是一項了不起的技術,在行業內引發廣大回響。
DeepTech 很高興邀請到王嘉平博士成為 DeepHash 專欄作者,這是他除了個人公眾號外首度在媒體上開設專欄。他將在以下的首篇專欄文章中,獨家披露 Monoxide 具體是如何突破區塊鏈不可能三角的,包含其研究中提出的“連弩挖礦”與“最終原子性”兩個重要創新。
Monoxide:突破區塊鏈不可能三角的極簡架構
圖| Monoxide :以異步共識組來拓展區塊鏈(來源:王嘉平)
上圖是我們的論文,在 NSDI 會場的海報展示環節將使用的海報。本文將順著海報的邏輯介紹 Monoxide 的設計架構和實現原理。雖然 Monoxide 架構可以采用不同的共識算法作為其共識組內的共識機制,本文將基于最簡單最干凈的Nakamoto(中本聰)共識算法(Proof-of-Work)展開討論。
而Monoxide 將同時滿足區塊鏈的安全,性能和去中心化這三項需求。這里需要強調的是,Monoxide 是 Layer 1 的區塊鏈技術,不假設交易結構的任何局部特性,也不假設跨共識組的交易會比較少。
什么是區塊鏈不可能三角?
第一角:怎么樣算安全
區塊鏈系統必須是安全的,這一點是不容妥協的,否則所有其它特性將毫無意義。具體落實到技術指標,就是在系統中構造一系列非法區塊并得到全網認可所需付出的代價。這個代價就 PoW (工作證明)共識機制而言,就是實施攻擊的最小挖礦算力。Nakamoto 共識算法保證惡意算力在50% 以下的時候,系統是安全的。我們保證的是采用 Monoxide 架構之后,這個 50% 算力的安全邊界不會顯著變低。同時,我們繼承了 Nakamoto 算法的其它安全特性,例如不要求出塊節點始終在線,全節點物理 IP 地址僅在一個很小的范圍內暴露等。
第二角:怎么樣算高性能
Monoxide 架構將完全隔離每個共識組的四大工作負荷,即:帶寬(廣播區塊數據和未確認交易)、計算(驗證交易和更新賬簿狀態)、內存(存儲賬簿的最新狀態)、磁盤讀寫(記錄歷史區塊)。我們強調這四個方面的負荷必須全部被切分隔離,才能真正獲得高伸縮性的區塊鏈系統,而不是僅完成部分工作符合的隔離,即所謂的網絡分片,交易分片和狀態分片。
具體落實到技術指標,性能包含兩個方面。一個是眾所周知的吞吐量,即最高每秒處理多少筆交易 (TPS),而另一個是全網表達賬簿狀態的總有效內存總量。前者是速度,后者是容量。
我們實現了吞吐量大致 n/2 倍的線性提升以及狀態容量的 n 倍的線性提升 (以支付交易計算為例)。這里的 n 是共識組的個數,提升是相對于共識組內部采用的單鏈共識系統的性能。現在一個單鏈共識系統,比較輕松能達到的是幾百 TPS 的吞吐量和數十 GB 的狀態空間。注意,這里并不是說 Monoxide 可以無限提升性能,在現有的互聯網平均帶寬的約束下(15Mbps),共識組的個數 n 最高只能到數萬這個量級。
第三角:怎么樣算去中心化
首先,公鏈必須是 permissionless 系統,并且系統中不存在不可替代的角色或者節點,這是一個定性的要求。在滿足這個要求之后,去中心化可以落實到具體的技術指標,即需要多少IT 資源才能順利地參與全網的監管(部分或者全部),也就是全節點的參與門檻。
而這個門檻最關鍵的因素是帶寬,高帶寬只有部署在數據中心才能獲得,其鏈路的地理位置也容易被追蹤;而其它資源諸如 CPU、內存、磁盤等,都可以不受特定地理位置的約束,也無法追蹤,花點錢就有。
Monoxide 架構在獲得幾個數量級的性能提升的同時,始終將全節點帶寬消耗控制在普通家用互聯網接入可以承受的范圍(15Mbps),從而使得 Monoxide 的全節點可以像現在的以太坊全節點一樣,隨便在家里找個普通電腦就開起來。同時 Monoxide 的共識組劃分了歷史交易歸檔的工作量,使得完整同步一個全節點的時間會比現在的以太坊少幾百倍。強調全節點進入門檻的原因是,只有全節點才能夠在不信任其它節點的情況下,獨立驗證交易,重建賬簿狀態,而不是像云計算那樣,需要依賴于信任特定的節點(或服務器),這是區塊鏈和云計算的本質區隔之一。
Monoxide 的總體設計
圖| Monoxide 總體設計(來源:王嘉平)
總體來說,Monoxide 的設計哲學是盡量簡單,在能滿足上述三角特性的前提下,盡量不引入額外的實體,不引入額外的機制,并盡量避免修改現有的機制。Monoxide 網絡是一個并發的多鏈系統,每一個鏈我們稱之為"共識組"。
每個"共識組"其組成部分和現在單鏈系統完全一致,有自己的賬簿狀態,區塊的鏈條,未確認交易的集合,同步區塊數據和交易數據的廣播網絡以及一堆全節點(包括礦工)。各個共識組之間完全對等,無主次之分,除此之外這個網絡就沒有任何其它的角色了,沒有之前那些方案提出的母鏈,根鏈之類的,也沒有任何掌控全局的調度節點或驗證節點。引入這些實體會使得一些功能更容易實現(例如動態負載平衡),但是他們會犧牲去中心化特性,甚至還可能導致嚴重的性能瓶頸。
全網所有共識組用一個整數編號(0到n-1),我們限定共識組的總個數為 2 的 k 次冪,即n=2^k。任何一個賬簿地址,根據其地址二進制數據的前 k 個比特,永久地被分配在一個共識組中。每個交易則根據交易的驗證方的地址(例如轉賬交易的支付方),被分配在驗證方所屬的共識組。所以 Monoxide 網絡的劃分不需要任何中心化的機制來分配地址和交易。
Monoxide 全網由各個共識組的出塊過程和未確認交易集合完全獨立,共識組之間完全并行、異步且無需鎖定和同步,即使某一個共識組發生擁塞也不會干擾其它共識組的吞吐和出塊。
Monoxide 全網由各個共識組的獨立廣播子網所構成,但這些廣播子網互相不重疊、互相不打攪。在我們的設計中,這些廣播子網由 DHT 的 Swarm 實現,每一個廣播子網對應一個 Swarm。新啟動的全節點根據其想要加入的共識組編號直接計算Swarm地址,然后利用 DHT的路由機制找到同一共識組里面的其它全節點,并嘗試連接、入網。
全節點可以隨機選擇加入任意一個或多個共識組,或由上層應用來決定。例如,錢包節點通常會加入登錄用戶的錢包地址所在的共識組,以便實時獲取其賬戶余額等狀態。Monoxide全節點不記錄任何用戶登錄狀態或用戶私鑰,以避免以太網全節點之前出現的 RPC 接口安全隱患。除非其上層應用請求,通常一個共識組的全節點不會主動連接另一個共識組的節點。
同樣礦工可以自由選擇參與一個或多個共識組,進行挖礦,以期獲得每一個共識組中的出塊獎勵。正常情況下,礦工會優先選擇參與當前算力較低的共識組,以獲得更高的利潤,從而導致各個共識組會收斂到一致的挖礦算力和出塊難度。
Monoxide 如何突破區塊鏈不可能三角?
從這個設計,我們可以看到 Monoxide 架構滿足區塊鏈三角的情況。
1.安全:只要各個共識組本身是安全的,Monoxide 就會是安全的。交易的安全和正確(例如避免雙花)依賴于每個共識組內部的共識算法。Monoxide全網應對女巫攻擊(Sybil Attack)也依賴于共識組內部的共識算法本身的抵御能力。就 PoW 而言,每個共識組的安全,依賴于其內部挖礦算力。所以 Monoxide 架構的安全保障,核心是要能夠抵御算力分散的問題,即全網算力分散到每個共識組之后,每個共識組的算力將是全網的 1/n,這時單個共識組的防御壁壘將下降到 51/n %,(即所謂的1%攻擊)。這是一個完全無法接受的值。為了解決這個算力分散的問題,Monoxide引入了”連弩挖礦”(Chu-ko-nu Mining),使得單個共識組的防御壁壘回升到 51%。
2.性能:由于各共識組的區塊驗證、存儲和賬簿狀態更新完全獨立,所以這三個方面將獲得無代價的無限線性提升。共識組之間唯一需要打交道的地方,就是為了正確處理跨共識組的交易。這使得在數據傳輸方面,性能提升是有代價的,并且不是無限的。為了高效完成跨共識組交易,Monoxide 引入了最終原子性(Eventual Atomicity),使得即使跨共識組交易的比例就算是接近 100%,全網仍舊可以輕松地完成交易吞吐,其性能代價為一個和共識組個數無關的常數。
3.去中心化:根據上面的描述,Monoxide 依舊是一個徹底的 permessionless 的系統,并且每個共識組內部的全節點的負擔始終保持在同維護一個單鏈系統相當的水平,可以被輕松部署到大部分有互聯網接入的角落。
所以論文最重要的兩大技術貢獻就是”連弩挖礦”(Chu-ko-nu Mining)和”最終原子性”(Eventual Atomicity)。后面我們將就這兩個方面,詳細展開,并以 Bitcoin (比特幣)數據結構為藍本,給出這兩個機制對 PoW 共識協議的改進。
”連弩挖礦”(Chu-ko-nu Mining),放大有效算力
在 PoW 共識機制中,礦工需要不斷隨機刺探塊頭中的 Nonce (隨機數值)并重算哈希函數,以使得這個塊頭的哈希值滿足當前算力難度的要求,可以最終出塊。這個過程的瓶頸在于計算哈希函數的速度,所以挖礦算力被定義為哈希速率(Hashrate)。這里,我們將實際計算哈希的速度,定義為物理算力(PhysicalMining Power),提高物理算力的唯一方法就是部署更多的礦機,消耗更多的能源。
然而,在 PoW 共識機制中,每個礦工的物理算力是無法直接知道的,這個物理算力最終體現為特定挖礦難度下的出塊速度。全網算力統計也是基于這個出塊速度而反算哈希速率而估計到的。
在發生算力攻擊的時候,無論是最長鏈,還是最難子樹(Ghost協議),都是依據各個分叉上出塊的數量和難度而定,而非各個礦工的實際哈希速率。我們將這個依據挖礦難度和出塊速度反算出來的哈希速率,定義有效算力(Effective Mining Power)。當然在單鏈系統中,有效算力和物理算力,在統計意義上來說是完全相等的。
前面提到的算力分散問題是這樣的一個攻擊模型:在有 n 個共識組的 Monoxide 系統中,全網有效算力為 H,每個共識組的有效算力為 H/n。攻擊者在實施攻擊的時候,將其所有物理算力 T 分配到一個特定共識組,在這個共識組中獲得有效算力T。那邊當其物理算力超過 T > H/n × 51% 的時候,攻擊將可以成功,并構造不一致交易(例如雙花交易)。
為了抵御這個算力聚焦的攻擊模型,我們的思路是強制礦工將算力分散到各個共識組,使其無法集中算力到特定共識組。但在一個去中心化的permissionless 系統中,我們無法控制礦工如何分配其物理算力。
因此,Monoxide 引入了連弩挖礦,其效果是將使得全網的有效算力放大為物理算力的 n 倍,并且在協議的數據結構層面再約束了這種放大后的有效算力必須平均分配到各個共識組,從而規避了這種算力聚焦的攻擊模型。
連弩挖礦允許礦工同時參與多個編號連續的共識組(例如從編號b到b+m-1),每次出塊的時候哈希函數將覆蓋多個將要出塊的塊頭進行計算,同時這些塊頭將共用一個 Nonce。具體做法是將這個 m 個塊頭按序排列,構造 Merkle 樹。然后算力哈希計算將覆蓋下列數據結構:
出塊時,下列數據結構會被廣播到特定的共識組 i (b≤i
其 MerkleTreePath_i是 Block_i在 Merkle 樹路徑上的左右兄弟節點的哈希值,需要 32 × log_2 m個字節。注意這里沒有顯式給 Block_i 在 Merkle樹中的位置,而是需要 Block_i中的共識組編號減去 b 推算出來,這樣做是為了約束連弩挖礦出塊的時候,每個共識組只能出一個塊。
從這個結構中可以看到,即使在連弩挖礦的情況下,各個共識組也不會受到其它共識組出塊情況的影響。連弩挖礦并不要求各個共識組同步接受這些塊,甚至有些塊最終被認為是無效分叉,也不會影響其它塊在其它共識組中被接受。同時,這個結構允許連弩挖礦包含算力難度不同的共識組,一旦部分共識組的挖礦難度被滿足,這些的塊就可以先發出去。
連弩挖礦將礦工有效算力放大,同時也放大了單位物理算力可以獲得的出塊獎勵,同樣的物理算力,同樣的能源消耗,參與到越多的共識組挖礦,所獲得的出塊獎勵也會越多。所以,全網會收斂到主流的礦工都會采用連弩挖礦,并且參與到所有的共識組中。從而,使得全網的有效算力達到 H × n,單個共識組的有效算力達到H 。這樣使得攻擊單個共識組的物理算力要求和攻擊全網的物理算力相當,有效抵御算力聚焦的攻擊。
同時參與到多個共識組挖礦,需要更多的 IT 資源用來同步和驗證每個共識組的交易和區塊(不僅僅是塊頭),也需要更多的磁盤存儲和內存。基于去中心化的考慮,參與連弩挖礦與否,以及參與的共識組個數是一個礦工可以自行配置的選項,Monoxide 并不要求所有礦工都參與所有共識組的挖礦。
同時,得益于共識組獨立性,一個參與所有共識組挖礦的礦場,很容易在其公司內部實現一個分布式的挖礦數據中心,用不同的主機監控各個共識組,用不同主機確認交易構造新區塊,然后在內部的高速網絡中匯總這些塊頭的哈希(Merkle的葉節點),并送給礦機集群。參與更多的共識組會線性增加IT資源的開銷,但是這些和大型礦場的礦機開銷來說,可以忽略不計了。
最后,順便提一下聯合挖礦(Merge Mining),在允許礦工同時參與多條鏈的挖礦這一點上,是很類似的。但是連弩挖礦設計初衷和工作場景和聯合挖礦完全不同,前者是為了放大有效算力,并強制放大后的算力均分在各個共識組,以防止算力集中攻擊特定共識組。而后者是為了借用大算力的鏈,來保證小算力鏈的安全。
''最終原子性''(Eventual Atomicity)
在 Monoxide 中,我們采用非常簡單的和去中心化的方式,將用戶和交易分配到共識組,并不企圖減少跨共識組交易發生概率,我們認為利用交易結構的局域性是Layer 2 技術的事情。全網性能越高,共識組數量越多,跨共識組交易發生概率一定會越高,這不是一個可以回避的問題。
在我們的實驗中,當共識組數量達到 64 的時候,跨共識組交易的比例已經超過了 95% (實驗的測試數據為以太坊 ERC20 的完整歷史交易記錄)。Monoxide 引入了最終原子性來實現高效的跨共識組交易處理,使得每個跨共識組交易帶來的額外開銷是一個很小的常數,并且和共識組數量 n 無關。
區塊鏈系統,每一個交易都是一個原子操作。在單鏈系統中,就好比單線程,這個原子操作并沒有被強調,因為交易本來就是被一個一個地確認和處理,系統無需做任何額外的事情,原子性就自然有保障。而在 Monoxide 中,不同地址的狀態在不同共識組中維護,互相不可見,其狀態的更新也被兩個不同的鏈驅動,就好比多線程。
一個原子操作要在這樣的架構下正確安全地完成,就不是一個簡單的事情了。通常為了協同多線程,我們有兩種辦法,一個是互相對所涉及的資源加鎖,另一個則是借由消息傳遞。我們選擇了后者,一方面是因為加鎖會阻塞對應的共識組的吞吐,嚴重影響性能,另一方面是因為所有的單鏈區塊鏈天生就有一個消息傳遞機制(未確認交易集合),從而避免引入新的實體。
我們先以最簡單的支付交易為例,介紹我們的設計。一個數量為 x 的從地址 A 到地址 B 的支付交易,并且 A 和 B 處于不同的共識組。這是一個原子操作,其中包含一個扣款操作,這個操作有條件,并且不同的執行順序會導致不同的狀態。另一個是存款操作,這個操作無條件,并且不同的執行順序不會導致不一致的最終狀態。
對于這樣的交易邏輯,Monoxide 將先在共識組 A 中,嘗試完成扣款操作。如果成功,則將向共識組 B 轉發一個接力交易,一種特殊的未確認交易。接力交易和普通未確認交易一樣,描述了用什么參數,調用哪個智能合約里面的函數。和普通未確認交易不同的是權限校驗方式。普通未確認交易,通常由錢包簽發,通過其攜帶數字簽名來校驗權限。而接力交易攜帶的是來自另一個共識組的出塊證明:
為了校驗這個接力交易,共識組的塊頭將包含兩個 MerkleRoot,一個是之前就有的覆蓋所有被本塊確認的交易的 Merkle 樹,另一個是新增的覆蓋由本塊中的交易發出去的所有接力交易。后者將被其它共識組接收,并用于校驗由其發出去的接力交易。
默認情況下,構造和轉發接力交易由確認初始交易的那個礦工(在共識組 A)完成。萬一這個轉發失效,共識組 A 中任何一個全節點,都有能力從交易歷史中根據那個初始交易重新構造并轉發丟失的接力交易,無需額外的共識或證明。
無論是接力交易,還是普通的未確認交易,都將以類似的方式在目標共識組的廣播子網中傳播,并被暫存在未確認交易的集合中。礦工在出塊的時候,將同等對待接力交易和未確認交易,通常根據其手續費多少來排優先級。任何產生一個或多個接力交易的初始交易,其手續費會以一定比例分配給初始交易和多個接力交易,給到最終在其它共識組確認這些交易的礦工。在 Monoxide 中,這個分配比例可以由智能合約代碼控制。
從上述流程中,我們可以看到在 Monoxide 系統中交易原子性并沒有得到立即滿足,而是要等到所有接力交易被確認和執行之后,才最終得以完成。我們將此稱為最終原子性,而不是要求即時的原子性。
最終原子性使得跨共識組的交易可以被無阻塞地在多個共識組間接力執行,使得多個交易可以完全并行地重疊交錯執行,這樣 Monoxide 系統的全網吞吐能力就得以完全釋放,即使再多的跨共識組的交易也不會顯著影響性能。
我們即使假設 100% 的交易都是跨共識組的交易,一個支付交易將會變成兩個交易,粗略地說,會使吞吐量減半。但是這個開銷,和共識組的總數無關。當全網性能獲得幾個數量級的提升時,這個開銷始終是吞吐量減半。
故而,在我們的實驗中,2048 個共識組能夠獲得近 1000 倍的吞吐量提升。基于最終原子性的執行邏輯,需要初始操作和接力操作滿足前述的正確性約束,否則可能導致不一致的最終狀態。誠然,這會對 Monoxide 平臺上的智能合約開發帶來一些難度。不過我們認為這是一個不可避免的代價,就好像給 GPU 寫代碼,給 OpenMP 寫代碼或者是給Hadoop 寫代碼,就是會比單機單線程的 CPU 的代碼要困難一些,思路上要繞一些。當然,結合恰當的合約語言模型、形式化驗證工具,以及開發和調試工具的支持,開發的難度也會大大減少。
Oxidation 語言是 Monoxide 平臺的智能合約語言,一種基于函數編程(Functional programming)的語言。這個語言模型的設計并不是論文的一部分,這部分工作也尚未全部完成。這里給出一個類似 ERC20 代幣的合約示例代碼。這里比較特殊的是系統調用 yield 。這個調用將在合約執行的過程中生成接力交易,如果 b 為一個跨共識組的地址的話。代碼中可以出現多個 yield 調用,也可以有條件地調用 yield,但是 yield 調用不允許重入。
伸縮性的上限——為什么說區塊鏈不可能三角被突破了?
為了正確完成跨共識組交易,接力交易的權限校驗需要接收到發起方所在的共識組的對應的塊頭。這件事情成為了 Monoxide 全網伸縮性的最主要瓶頸。這意味著,每個全節點都需要同步并跟蹤所有共識組中的塊頭,同時加上連弩挖礦機制,這個同步消耗的帶寬為:
( BlockHeadSize + 32 ×log2 n ) × n / BlockInterval
BlockHeadSize 為塊頭的元數據,大致 120 字節。這個部分為不定長,是因為Monoxide 采用可變長度的 Nonce,以適配不同的挖礦難度。32 × log2 n 部分為連弩挖礦機制引入的算力證明,即前文的 MerkleTreePath_i。BlockInterval為出塊間隔。基本上,這是一個 O(nlog2 n)的開銷,只要 n 大到一定程度,性能的提升會低于這個開銷的增加,從而確定了伸縮性的天花板。
既然,每個全節點都需要同步并跟蹤所有共識組中的塊頭,我們將給出另一種連弩挖礦的出塊數據結構,改為一次出所有的塊頭,而不是按逐個共識組出塊頭,不可用的塊頭(哈希難度未達到挖礦難度的)用其哈希值代替。當然區塊本身仍舊是逐個共識組分開廣播的。同時為了實現這個優化,我們將引入一個全局的特殊廣播子網,僅用來傳播塊頭或者成批的塊頭,并要求所有全節點和挖礦節點加入這個特殊的廣播子網。這樣就可以省去原先每個塊頭的算力證明部分,將帶寬消耗將降到 O(n):
BlockHeadSize × n / BlockInterval
即使優化之后,對于每個全節點來說,這仍舊是一個不容忽視的開銷。n總能大到一定程度,使得本地帶寬被耗盡。那么我們來推演一下這個天花板到底是多少。假設約束全節點帶寬為 15Mbps,即上限為 1.88MB/s。以 Nakamoto 共識為基礎,我們設定其出塊間隔為 1 分鐘,出塊大小為 8MB。
這樣單個共識組單鏈吞吐量將約為 560 TPS,區塊傳輸開銷為 0.13MB/s。當共識組數量為 65536 個的時候,全網塊頭傳輸開銷也為 0.13MB/s。加起來也遠小于帶寬上限,有足夠的剩余帶寬用于下行廣播。然后,這個時候全網吞吐量約為 15M TPS 左右,狀態容量在幾百 TB 的數量級。無論是再多的共識組總量,還是再高的共識組單鏈吞吐量,都會逐漸使得全節點本地帶寬顯得局促。
所以,我們認為 Monoxide 的伸縮性天花板大致在這個水平,千萬 TPS 的吞吐量和幾百 TB 的狀態容量。千萬 TPS 這個數量級,已經可以應付大部分互聯網級別應用的峰值流量,同時仍舊滿足區塊鏈對安全和去中心化的要求。這就是為什么我們說,區塊鏈不可能三角被突破了。當然,要伸縮到這個程度,也需要整個社區的總參與節點數到達百萬數量級。
-
cpu
+關注
關注
68文章
10829瀏覽量
211196 -
人工智能
+關注
關注
1791文章
46896瀏覽量
237670 -
區塊鏈
+關注
關注
110文章
15560瀏覽量
105807
原文標題:DeepHash專欄|Monoxide:突破區塊鏈不可能三角的極簡架構
文章出處:【微信號:deeptechchina,微信公眾號:deeptechchina】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論