【區塊鏈】Tendermint——概述、PoS共識算法與架構

什麼是 Tendermint?

Tendermint 是一種能夠爲多臺機器安全和保證數據一致性複製應用程序的軟件。從安全性層面看,分佈式系統中即使 1/3 的隨機節點即使宕機了,Tendermint 依然能夠保證分佈式系統正常運行。另外在數據一致性方面,故障的節點能夠看到相同的事務日誌並計算出相同的狀態。安全且保持一致性複製是分佈式系統的基本問題,在很多應用程序中起着關鍵性的作用,比如貨幣系統、選舉和基礎設備編排等系統。

分佈式系統需具備容忍節點離線或出錯,也就是拜占庭容錯。拜占庭容錯理論歷史悠久,區塊鏈技術落地成功的案例、比如比特幣、以太坊的成功促使該理論在計算機領域的實現得以流行。區塊鏈技術着重結合對等網絡(P2P) 和密碼認證對拜占庭容錯加以進化。交易被批量打包成塊,每個塊通過加密哈希連接上一個塊從而形成鏈,這也是把該技術命名爲 區塊鏈 (BlockChain) 的原因。

Tendermint 包含兩個組件: 區塊鏈共識引擎 (blockchain consensus engine)、 通用應用接口 (generic application interface) ,共識引擎被稱爲 Tendermint Core ,確保交易記錄在任何一個節點都能一致被排序。通用應用接口被稱爲 應用區塊鏈接口 (Application BlockChain Interface) 簡稱爲 ABCI ,交易能夠被任何編程語言處理。大部分區塊鏈和共識方案預先打包內置狀態機(比如存儲鍵值對或者通過腳本),而開發者通過 Tendermint 可以對任意編程語言編碼的應用實現 BFT 狀態機複製,並且開發環境對開發者也很適合。

Tendermint 以易用、易懂、高性能爲設計原則,對各種分佈式應用程序都有用。

Tendermint 與同類軟件對比

Tendermint 與兩類軟件相似。一類是分佈式鍵值對存儲軟件,例如 Zookeeper, etcd, 和 consul, 但他們使用了 non-BFT 共識。另外一類就是區塊鏈技術。區塊鏈技術包含加密貨幣,例如比特幣和以太坊,還包含非傳統類的分佈式賬本,譬如 Hyperledger 的 Burrow

Zookeeper, etcd, consul

Zookeeper, etcd 和 consul 都是典型的鍵值對存儲和 non-BFT 共識算法的實現。Zookeeper 使用 Zookeeper Atomic Broadcast 版本的 Paxos 算法;etcd 和 consul 使用比較新和簡單的 Raft 共識算法。非拜占庭容錯共識實現的分佈式集羣中,假設包含 3-5 個節點,可以允許一半的節點離線,但是如果出現一個拜占庭錯誤節點(作惡節點)足以摧毀該分佈式系統。

三者都各有特色稍微不同地實現了鍵值對存儲,但都重點圍繞着給分佈式系統提供基礎服務,例如動態配置、服務發現、鎖、領導節點選舉 (leader-election)

Tendermint 和上述類型的軟件本質作用差不錯,但有兩個重要的不同點:

  • 支持拜占庭容錯算法,意味着智能容忍三分之一以內的節點錯誤,這個錯誤包括任意節點離線和節點作惡
  • 獨立於特定類型軟件,例如鍵值存儲類。而 Tendermint 只是關注任意狀態機複製,開發者根據軟件需求業務邏輯,例如通過狀態機複製實現鍵值對存儲、加密貨幣乃至分佈式電子投票平臺等分佈式應用。

比特幣、以太坊及其他加密貨幣

Tendermint 誕生於傳統的加密貨幣之後。相比於比特幣的工作量證明 (Proof of Work) ,它實現的共識算法更高效和安全。早期的 Tendermint 內置了簡單的數字貨幣並實現了共識功能。節點需要繳納保證金,如果作惡保證金就會被沒收。Tendermint 實際上也是一種股權證明 (Proof of stake)

加入可股權證明算法之後,Tendermint 演變爲區塊鏈共識引擎,允許任何機器都可以加入作爲節點的分佈式系統。這也意味這 Tendermint 可以作爲其他區塊鏈項目即插可用的共識引擎,替換原有的共識模塊。也就是說,舉個例子你可以使用 Tendermint 共識運行任何語言實現的以太坊節點源碼作爲 ABCI 應用(上文提到,最終實現了一種基於股權證明共識以太坊。
事實上,我們基於以太坊實現了上述的 demo

the Cosmos network 共識算法就是內置了 Tendermint

其他區塊鏈項目

Fabric 採用了與 Tendermint 相似的方法,但是它更偏向於如何管理狀態,並要求所有的應用行爲能夠運行在 docker 容器中,我理解Fabric 的 chaincode 就像以太坊的智能合約。它基於 PBFT 實現。在 Tendermint 中,可以把這種基於容器的行爲作爲 ABCI 應用。

Burrow 實現了以太坊虛擬機和交易機制,並擴展了名字註冊 (name-registery),許可權限、原生合約提供多種方式調用區塊鏈接口 (REST 和 JSON-RPC)。它使用 Tendermint 作爲共識引擎,提供的特殊的應用狀態(這裏的狀態由賬戶、驗證人集合、和名字註冊)

ABCI 概述

通用區塊鏈接口 ABCI 允許任意類型編程語言編寫的拜占庭容錯複製類的應用程序。

初衷

迄今爲止,實現區塊鏈的源碼都是一個巨大的應用(譯者注:這裏的說法有點絕對,17 年國內有一家公司開源的 CITA 代碼把區塊鏈各個功能模塊拆分單獨部署),也就是一個應用包含了所有的功能模塊,包含 P2P 網絡,"mempool" 廣播交易,共識模塊,賬戶餘額,圖靈完備的合約模塊和用戶用戶權限模塊等。

CITA將單個節點按照功解構爲交易共識、合約引擎、鏈 式存儲、網絡同步、服務網關等多個鬆耦合的微服務,一方面利用雲計算基礎設 施來按需提升性能,另一方面,各個組件可獨立替換升級。

一個軟件代碼過於龐大會導致組件複用和維護過於複雜,特別是當代碼模塊封裝不夠好的情況下更糟糕;

另外會限制大一統架構會限制編程語言的使用,譬如在以太坊中,它支持圖靈完備的字節碼虛擬機,它限制開發者必須要可以編譯爲那種類型字節碼的語言,當前只有 Serpent 和 Solidity 滿足。

所以,基於上述兩種缺陷,Tendermint 從特定區塊鏈應用(例如 Bitcoin-core 和 go-ethereum) 的把共識引擎和 P2P 網絡分離。區塊鏈應用的細節抽象爲一個接口,並通過 socket 協議實現。

所以就有了接口的概念,通用區塊鏈接口 (ABCI) , 和實現接口的 Tendermint Socket Protocol (簡稱爲: TSP 或 Teaspoon)

ABCI 介紹

Tendermint Core 也就是共識引擎,通過 一種滿足 ABCI 規範的 socket 協議和應用通信。

用比特幣作爲例子,比特幣加密貨幣區塊鏈中每個節點都維護一份公鏈完整的所有未交易輸出數據庫。如果想要在 ABCI 上實現一個比特幣類(Bitcoin-like)的系統,Tendermint 將會負責:

  • 在節點間共享區塊和交易
  • 給所有交易建立一個規範且不可篡改的順序

而區塊鏈應用 (也就是 bitcoin-coer) 負責:

  • 維護 UTXO 數據庫
  • 驗證交易的加密簽名
  • 阻止交易花費尚未存在的交易
  • 允許客戶端查詢 UTXO 數據庫

Tendermint 在應用(例如 Bitcoin-core) 進程和共識進程之間提供簡單的接口(例如 ABCI),以此分解龐大的區塊鏈應用軟件。

ABCI 由三種主要的消息類型組成,這些消息類型從 Tendermint-core 發往區塊鏈應用(例如 bitcoin-core),應用會對消息作出對應的響應。

消息的詳細說明可查閱:ABCI Message Types

DeliverTx 是應用中的很重要組成部分,它會傳遞鏈中的每筆交易。應用(例如 Bitcoin-core)需根據當前狀態,應用程序協議和交易的加密憑證來驗證來自 DeliverTx 消息傳遞過來的每筆交易。每筆被驗證通過的交易然後更新應用的狀態,例如存儲交易鍵值對,或更新 UTXO 數據庫。

CheckTx 消息和 DeliverTx 類型相似,但它只是驗證交易的有效性。Tendermint Core mempool 首先通過 CheckTx 檢測交易的有效性,然後將有效的交易轉發給它的節點。例如,一個應用的驗證規則爲檢測交易的遞增序列號,如果序列號是舊的,則 CheckTx 返回錯誤。

Commit 消息用以給當前應用狀態計算加密保證 (cryptographic commitment),加密保證被放入下一個區塊頭。節點狀態更新不一致表明鏈出現分叉。加密保證同時簡化了安全的輕節點客戶端開發,因爲 Merkle-hash 證明可以通過檢測區塊哈希去驗證是否正確,而區塊已被 quorum 簽名。

多個 ABCI socket 可以連接到同一個應用上,Tendermint Core 新建三個 ABCI 連接應用:一個用以驗證被廣播到 mempool 中的交易;另一用以共識引擎去運行新區塊提議;最後一個 socket 連接被用於查詢應用狀態。

顯然在開發區塊鏈底層鏈時,開發者要對消息處理需十分嚴謹。但是 Tendermint 的 ABCI 的三種消息模型架構給消息處理提供了很不錯的範例。下圖展示了 ABCI 的消息流:

abci.png

關於確定性的說明

區塊鏈處理交易的邏輯必須是確定的,否則 Tendermint Core 複製的節點之間將不會達成共識。

在以太坊平臺選用 Solidity 開發區塊鏈應用是很好的選擇,除其他因素外,它是一個完全確定的編程語言(也就是在各種環境下輸出都一樣,與之相反的例子就是普通編程語言多線程競爭問題導致輸出不確定),然而通過普通的編程語言如果知遵循規範話(譬如避免線程競爭),也是可以做到在各種條件下同一輸入會得到確定的輸出。遊戲程序員和區塊鏈開發者對在不確定的的情況情景下開發最終確定的程序比較熟悉,例如:

  • 生成隨機數 (使用確定的種子)
  • 線程競爭條件(避免多線程)
  • 系統時鐘
  • 未初始化的內存 (in unsafe programming languages like C or C++)
  • 浮點數計算
  • 隨機的語言特性(例如 Go 中迭代 Map 也是隨機的)

謹慎編碼可以避免寫出不確定輸出的代碼,同時創造特殊的語法檢測器或靜態分析器檢測確定性也是行得通的。將來我們團隊可能會開發這樣的工具。

共識概述

Tendermint 是一種易懂,大部分都是異步和拜占庭容錯的共識協議。它遵循的的一個簡單的狀態機,如下圖所示:

 

協議中的角色稱謂 驗證人 ;他們輪流對交易的區塊提議並對提議的區塊投票。區塊被提交到鏈上,且每個區塊就是一個區塊高度。但是區塊也有可能不被提交到鏈上,面臨這種情況時,協議將繼續下一輪對區塊提議和投票,有權提議新塊的驗證人可以爲當前區塊高度選擇區塊並對其投票,然後剩下的認證人投票,超過 2/3 的驗證人對同一個塊投票即可提交該區塊。驗證人對一個提議的區塊進行預投票和預提交,當超過 2/3 的驗證人在同一輪提議中對同一個塊投票,那麼這個區塊纔會被提交。

驗證人面臨當前的提議者離線或者網絡延遲,則會出現提交區塊失敗的情況。Tendermint 允許驗證人確認出現故障的驗證人可以被忽略。在進行下一輪投票之前,所有驗證人等待一小段時間接收提議者完成對塊的提議。驗證人依賴超時才進行下一輪操作體現了 Tendermint 是部分同步的協議,而非全異步協議。完成對區塊提議之後,協議剩下的部分是完全是異步的,驗證人只要接收到超過 2/3 的驗證人集時就放棄當前一輪投票,執行下一步操作。Tendermint 足以簡單是因爲提交區塊也使用了上述的機制,當超過三分之二的節點成功對提議的區塊投票時就表示區塊已經被提交,剩下的馬上轉入下一個區塊的提議和投票。

假設少於三分之一的驗證有主觀惡意,Tendermint 就能保證共識算法就能保證系統安全。也就是說,多個驗證人永遠不會在同一高度提交區塊造成區塊衝突。Tendermint 確保系統安全是通過引入 鎖定 規則,一旦驗證者預提交了一個區塊,那麼該驗證人就會被鎖定在這個區塊。然後:

  1. 該驗證人必須在預提交的區塊進行預投票
  2. 當前一輪預提議和預投票若沒成功提交區塊,該驗證人就會被解鎖,然後進行對新塊的下一輪預提交

Stake

在很多系統中,並不是所有的驗證人都在共識協議中有中同樣的投票權重。因此我們對 1/3 或 2/3 的驗證人並不十分感興趣,而是關心所有投票的佔比,這個比例對於單個驗證人並不是均勻分佈的,在數字貨幣系統中,可以依據幣量和幣齡分配投票權重。

因爲 Tendermint 可以使用現有的區塊鏈項目作爲 ABCI ,所以可以給基於 Tendermint 實現的系統定義一套數字貨幣,然後根據各個節點持有的幣量(根據持有幣的數量或者持幣的幣齡也可,在這需根據業務來定)計算節點的投票權重。當投票權是基於節點持有的數字貨幣作爲依據,那麼這樣的系統就成稱爲股權證明 (Proof of stake)。節點通過把持有的幣作爲保證金之後就成爲驗證人,如果作惡,這筆保證金就會被銷燬。這就給協議的安全性加了經濟的因素,就像比特幣系統中的工作量證明依賴礦機算力一樣,增強了區塊鏈網絡的安全性,同時也可量化違反共識的成本,想要控制股權證明的分佈式區塊鏈網絡,必須控制超過全網超過 2/3 的投票權重。

Cosmos Network 內置了加密貨幣的 ABCI 應用,使用股權證明機制

 

發佈了51 篇原創文章 · 獲贊 12 · 訪問量 5150
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章