區塊鏈時代的拜占庭容錯:Tendermint(四)

原文題目:《Tendermint: Byzantine Fault Tolerance in the Age of Blockchains》

原文作者:Ethan Buchman

翻譯:潘振東

校對:杜滿想

本文爲節選

 

構建應用

Tendermint被設計成爲可複製的最終確定性狀態機的通用的算法。它使用Tendermint套接字協議(TMSP)標準化共識引擎和狀態機之間的溝通,使得應用開發者可以用任何語言去構建他們的狀態機,並通過這種方式自動複製了基於Tendermit的BFT算法。

 

背景

互聯網上的應用程序通常可以表徵爲包含兩個基本要素:

  • 引擎:處理核心安全性,網絡,複製。這通常像一個網絡服務器,如Apache或Nginx,可以構建Web應用程序,或者構建分佈式應用程序的一致性算法。

  • 狀態機:處理交易的實際應用程序邏輯,從引擎接收並更新內部狀態。

這種引擎和狀態機結構的分離使應用程序開發人員可以用任何編程語言編寫想要的應用程序的狀態機,在引擎之上可能專門定義其性能,安全性,可用性,支持性和其他考慮因素。與Web服務器及其應用程序不同,後者通常採用的形式是進程通過公共網關接口(CGI)協議使用套接字進行通信。而共識算法一般來說要以更少的可用性或者更少的通用性接口來構建應用程序。像zookeeper,etcd,consul和其他分佈式鍵值對存儲應用一樣,提供HTTP接口到簡單鍵值對應用程序的特定實例,還有一些更有趣的功能,如原子比較和交換操作並推送通知。但他們沒有給應用程序開發人員控制狀態機代碼本身。

比特幣的成功以及源源不斷對區塊鏈技術的興趣產生了要對狀態機運行進行高級別的超越共識引擎的控制需求。通過構建更多高級應用直接進入共識,用戶,開發商,監管機構等等,可以在任意狀態機上實現更大的安全保障,遠遠超出鍵值對存儲,如貨幣,交易所,供應鏈管理 - 治理等等。它之所以引起了這麼多人的注意,是因爲這個系統巨大的潛力是允許集體執行前執行代碼。它實際上是對許多方面的重新發明法律制度,使用分佈式共識算法和確定性可執行合同,而不是警察,律師,法官,陪審團和個人喜好。這對人類社會發展的影響是爆炸性的,就像引入民主法治一樣。Tendermint旨在提供基本的接口和共識引擎可以構建此類應用程序。

 

Tendermint 套接字協議

Tendermint套接字協議(TMSP)定義了共識引擎和應用程序狀態機之間通訊的核心接口。這個接口定義包括一系列的消息類型,使用Google’s Protocol Buffers (一個長度作爲前綴通過套接字傳輸的協議),一系列的消息類型,他們的參數,返回值和用途都在圖5.1中,整體的結構和消息流程也在圖5.2中。

圖5.1

Golang定義的TMSP Application interface,TMSP消息被定義爲使用Google’s Protocal Buffers,序列化格式是通過TMSP套接字傳輸之前將長度作爲前綴,返回值包括一個代碼,和HTTP的狀態碼類似,代表了任意的錯誤信息,0表示沒有錯誤,消息在客戶端緩存直到一個flush消息被髮出,在這個點所有的緩存消息都會被髮出。服務端設計的是異步化的,消息返回必須是和請求相匹配的正確的順序。

圖5.2

共識邏輯與應用程序邏輯進行通信是通過TMSP(套接字協議)。維護兩個sockets(套接字),一個用於mempool檢查新交易的有效性,另一個用於執行共識的新提交的塊。

TMSP協議被實現爲一個有序的異步的服務,消息類型請求和返回是成對的,當一個特殊的消息類型出現的時候,清空並通過連接推送緩存的所有消息然後等待消息。

在TMSP協議有兩種消息是核心,AppendTx 和Commit,一旦塊由共識產生,引擎就會在塊上調用AppendTx處理每個塊中的交易,將其傳遞給應用程序狀態機處理。如果交易有效,則會導致應用程序中的狀態轉換。

一旦所有AppendTx調用返回,共識引擎調用Commit,使得應用程序提交到最新狀態,並將其永久存儲到磁盤。

 

分離協議和執行

使用TMSP可以使我們明確區分共識,或者關於交易順序的協議,以及它們在狀態機中的實際執行情況。特別是,我們首先就順序達成共識,並且然後按順序執行交易。這種分離實際上有所提升系統的容錯,但是仍然需要總數3f + 1個節點去容忍f個拜占庭式節點的失敗,只需要2f + 1個節點執行。也就是說,雖然我們仍需要三分之二的多數來排序,我們只需要一半的多數來執行。

另一方面,事實上交易的執行放在排序之後會導致可能是無效的交易,這可能會浪費系統資源。這種情況使用額外的TMSP消息CheckTx解決的,由mempool調用,允許它檢查交易是否會對最新的狀態有效。但請注意,事實上塊中的一次性提交會引起CheckTx處理消息的複雜性。特別是,應用程序希望維護第二個狀態機只執行主狀態機相關的交易有效性的規則。第二個狀態機由CheckTx消息更新狀態並在每次提交後重置爲最新的已提交狀態。在本質上,第二個狀態機描述了交易池的過濾規則。 

在某種程度上,CheckTx可以用作`樂觀的執行`返回並將結果發送給交易發送者,但結果可能是錯誤的,比如一個帶有衝突交易的塊在利息交易之前提交。這種`樂觀的執行`是擴展BFT系統的方法的關注焦點,可以很好地適用於交易之間衝突很少的應用程序。與此同時,它增加了客戶端的額外複雜性,因爲可能需要處理無效的結果。

 

微服務架構

採用分離關注點作爲應用程序設計的策略是從普遍上來看是明智的做法。特別是,許多當今的大規模應用部署採用微服務架構。其中每個功能組件實現爲獨立的網絡服務,通常封裝在Linux容器中(例如使用Docker)以提高部署效率,可伸縮性和可升級性。

在Tendermint共識之上運行的應用程序通常會被分解成微服務,例如,許多應用程序將使用一個鍵值對存儲用於存儲狀態。爲了利用數據存儲的優勢和某些特有功能,將鍵值存儲作爲獨立運行的服務很常見,如高性能數據類型或默克而樹。
應用程序的另一個重要的微服務是治理模塊,它管理某個TMSP消息子集,啓用該應用程序控制驗證器集更改。這樣的模塊可以在BFT中變成強大系統治理範式。 

某些應用程序可能爲用戶使用本機貨幣或帳戶結構,因此,提供支持基本元素的模塊是有用的,例如,處理數字簽名和管理賬戶動態。用微服務構成複雜TMSP應用程序例子還有很多。實際上,人們甚至可以構建一個可以啓動的,包含了使用交易中發送的數據的子應用程序的應用程序。例如,在交易中包含了一個存儲docker鏡像的哈希,以便從一些文件存儲後端pull下來運行並作爲未來的子應用程序運行共識中的交易以導致其運行。這是以太坊使用的方法,允許開發人員將一些代碼部署到網絡中可以通過上面的方式觸發在以太坊虛擬機中運行交易(智能合約),以及IBM最近的OpenBlockChain(OBC)項目,它允許開發人員在交易中發送完整的docker上下文,定義運行任意代碼以響應發往他們地址的交易的容器。

 

確定性

關於使用TMSP構建應用程序的最爲嚴格的忠告是他們必須是確定性的,也就是說,對於複製狀態機而言不保證安全。每個節點在執行時針對同一狀態的同一交易必須獲得相同的結果。這不是Tendermint的獨特要求。比特幣,raft,以太坊,任何其他分佈式共識算法,以及鎖步等多人遊戲必須嚴格具有確定性,以免達成共識失敗。編程語言中有許多非確定性的來源,最明顯的是通過隨機數和時間,但也可以通過使用浮點精度,並通過哈希表迭代(一些諸如Go之類的語言強制對哈希表進行隨機迭代程序員明確何時需要有序數據結構)。對確定性機制的嚴格限制,以及確定性在每種主流編程語言中的缺失,促使以太坊開發自己的,圖靈完備的,完全確定的虛擬機,它構成了應用程序開發人員在以太坊區塊鏈之上構建應用程序的平臺。雖然確定性,它有許多特別之處,例如32字節堆棧字,存儲鍵和存儲值,不支持字節位移操作,一切都是大數算術。確定性編程在實時世界中得到充分研究,例如鎖步,多方遊戲。這類遊戲構成了另一個複製狀態機的例子。並且在許多方面與共識算法非常相似。鼓勵使用TMSP構建的應用程序開發人員進行學習使用他們的方法,並在實現應用程序時要小心。使用函數式編程語言和證明方法可以啓用正確程序的構建。在另一方面,編譯器也在構建以將可能的非確定性程序轉換爲規範化確定性的。

 

終止性

如果說確定性是爲了保證安全很嚴格,那麼交易執行的終止性就是爲了嚴格的保證存活。然而,它不是一般的可以確定給定程序是否因單個輸入而停止,更不用說所有這些問題,這個問題被稱爲停機問題。

以太坊的虛擬機通過計量解決問題,具體來說,在執行中的每個操作收費。這樣,交易就保證在發起者資金不足時終止。這樣的計量在更一般的情況下,可以通過編譯程序的編譯器實現計量他們自己的版本。

沒有顯着的開銷就很難解決這個問題。在本質上,驗證器無法判斷執行是處於無限循環中還是隻是緩慢,但幾乎完成。可以使用Tendermint共識協議決定交易超時,超過三分之二的驗證人必須同意交易超時,因此被視爲無效(即對狀態沒有影響)。但是,我們沒有在這裏進一步實踐這個想法,留待未來的工作。同時,預計應用程序將在進行全面測試之前部署在任何共識系統中,監控和治理機制在達成共識的情況下,將用來恢復系統失敗。

 

舉個例子

在本節中,將介紹和討論越來越複雜的TMSP應用程序,特別是CheckTx和管理mempool。

Merkleeyes

TMSP應用程序的一個簡單示例是基於Merkle樹的鍵值存儲。Tendermint提供Merkleeyes,這是一個包裝的TMSP應用程序,一個自平衡的Merkle二元搜索樹。交易的第一個字節確定交易是get,set還是delete操作。對於get,delete操作,剩餘的字節是鍵(key)。對於set操作,其餘字節是包含鍵和值的序列化列表。Merkleeyes可能使用CheckTx的簡單實現對交易進行解碼,以確保其格式正確。也可以實現更高級的CheckTx,get和delete操作對未知key無效。調用Commit後,將添加最新更新進入Merkle樹,重新計算所有哈希值,樹的最新狀態也在磁盤上提交存儲。

請注意,Merkleeyes被設計爲其他TMSP應用使用的基於Merkle樹的鍵值存儲的模塊。而不是單獨的TMSP應用程序,雖然TMSP接口的簡單性使它適用於兩者。

貨幣應用

一個更重要的完整實例是一個簡單的貨幣,用的賬戶結構由以太坊創立,每個用戶都有一個公鑰和一個基於該公鑰的帶有餘額的賬戶,該帳戶還包含一個序列號,等於帳戶發送的交易數量。交易可以從賬戶發送資金,如果它們包括正確的序列號,並由正確的私鑰簽名。沒有序列號,系統容易受到重放攻擊,可以重播從帳戶中扣除帳戶的已簽名交易,從而導致借記多次發生。此外,防止重放攻擊在多鏈環境中,交易簽名應包括網絡或區塊鏈標識符。

一個支持貨幣職能的應用程序自然具有比鍵值存儲更多的邏輯。特別是,某些交易明顯無效,例如簽名無效,序列號不正確或發送超過發起人帳戶餘額的金額。這些情況都可以通過CheckTx檢查。

此外,必須在CheckTx中維護補充應用程序狀態是爲了在更新時更新序列號和帳戶餘額當同時在mempool中有多個涉及相同帳戶的交易時。調用commit時,將重置補充應用程序狀態到最新的提交狀態。任何仍在mempool中的交易都可以通過CheckTx重播最新狀態。

以太坊

以太坊使用已經描述的機制來過濾掉mempool中的交易,但它也在虛擬機中運行一些交易,它會更新狀態並返回結果。虛擬機執行沒有在CheckTx中完成,因爲它們包含在塊中,它更昂貴且嚴重依賴交易的最終順序。

 

總結

TMSP提供了一種簡單而靈活的方法來構建任意應用程序,可以用任何編程語言,繼承複製自Tendermint一致性算法的BFT狀態機。它扮演的角色大致類似於共識引擎和一個應用程序。例如,CGI扮演爲Apache和Wordpress。但是,應用程序開發人員必須特別注意確保他們的應用程序是確定性的,並確保交易執行終止。

 

相關閱讀:

區塊鏈時代的拜占庭容錯:Tendermint(一)

區塊鏈時代的拜占庭容錯:Tendermint(二)

區塊鏈時代的拜占庭容錯:Tendermint(三)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章