Hyperledger Consensus
共識過程
Hyperlydger中建立共識的過程由以下兩個獨立的過程構成:
- Ordering of transactions (交易排序)
- Validating Transactions(交易驗證)
邏輯上將這個兩個過程分離可以保證Hyperledger快講可以應用任何的共識模塊。
建立共識的第一步是從client端接收交易,然后由Ordering Service進行交易排序。Ordering Service 可以用多種方法實現,在開發測試階段可以用中心化的排序服務,也可以面向不同的網絡采用分布式協議。
為了實現交易的私密,排序層不應看到交易的具體內容(對交易內容不可見),交易的內容可以采用加密或者是哈希處理。
交易通過接口被傳遞到排序服務,然后排序服務根據共識算法和配置策略將交易排序。為了提高效率,排序服務會將多個交易打包成一個塊再輸出,排序服務中需要保證塊內交易的順序。
為了校驗交易的正確性,共識的建立依賴於智能合約層,智能合約層定義了商業邏輯來確認如何驗證交易有效。智能合約層根據特定的策略與約定來確認每一筆交易都是有效的。無效的交易會被拒絕,並在塊中剔除。
潛在的校驗失敗主要分為以下兩種:語法錯誤、邏輯錯誤。
語法錯誤包含以下幾種類型,比如無效輸入、未驗證的簽名、重復的交易等,這類交易應該被丟棄。
第二類錯誤比較復雜,需要有特定策略來覺得如何處理。比如,一筆交易經驗證是多重支付。我們需要記錄這類交易已驗證是否是策略所需要的。
共識層通過通訊層來實現與client或者是其他節點的消息互通。
共識屬性
共識必須遵循以下兩個屬性:安全性(Safety)和活躍性(Liveness)。
- 安全性,是指要保證每個節點都有相同的輸入序列,並在每個節點上產生相同的輸出。當節點收到一組交易時,每個節點上的狀態變化都應該是相同的。算法需要實現在一個節點上,交易以原子方式進行處理,即每次只能處理一個交易。
- 活躍性,網絡中的每個節點都必須接收到每一條提交的交易,除非節點出現錯誤。
Hyperledger Frameworks 中的共識
因為商業區塊鏈的需求是多樣的,因此需要不同的共識機制。Hyperledger工作於多種不同的共識機制上,並且是模塊化的。
上面表格比較了Hyperledger中用到的共識算法。
Hyperledger Fabric 中的共識
Fabric中的共識達成過程分解為以下三個步驟:
- Endorsement,網絡參與式endorse一個交易
- Ordering,接收經過endorse的交易,將其排序,並打包成block
- Validation, 接收經過排序的block,驗證其中交易結果的正確性,包括檢查endorsement策略、二次支付等問題。
Fabric建立共識的三個階段都支持可配置,用戶可以實現自己的endorsement、ordering、validation過程。除此之外,Ordering Service還支持配置基於拜占庭容錯的共識算法。Ordering Service API包括兩個基本動作:廣播、傳輸。
- 廣播:client端調用該接口實現任意消息的廣播,當向一個service發送請求時,在BFT部分也被稱為request。
- deliver:Ordering Service調用該接口用來發送帶有特定消息序列值和prehash值得消息。或者說,這是一個從排序服務中用到的輸出事件。deliver()在廣播-訂閱系統中,有時也被稱為notify(),在BFT系統中稱之為commit()。
多個排序組件正處於開發之中,這包括BFT Smart、Simplified Byzantine Fault Tolerance(SBFT)、Honey Badger of BFT 等等。在Fabric v1中,Apache Kafka作為一個包外參考實現被提供。用戶根據使用場景及容錯模型來決定使用哪個組件。
Hyperledger Indy 中的共識
Hyperledger Indy 中的共識是基於Redundant Byzantine Fault Tolerance (RBFT)的,RBFT是由 Plenum Byzantine Fault Tolerance (Plenum)發展來的,可以把RBFT想象成是幾個Plenum實例的並行實現。
由一個單一實體發向master的經過排序的請求消息被用來更新ledger,但是master的性能(吞吐量、延遲等)會周期性的與其他實體的平均值進行比較。如果發現master性能低下,則會發生視圖更改,將不同的實例分配給master的角色。
與PBFT一樣,RBFT至少需要\(3f+1\)個節點來處理\(f\)個錯誤節點。下圖展示了一個4個節點的網絡,該網絡可以處理1個錯誤節點。其中每個節點都可以運行一個primary(leader)實例。
圖4中展現了一個RBFT結構視圖,在網絡中client向節點發送請求。沒有必要向所有的節點發送消息,因為發送\(f+1\)個就足夠了。節點收到client的請求后,會將消息傳播,從而使得其他節點都知道請求消息。每個primary節點在收到請求后,都會創建一個proposal(PRE-PREPARE),然后將其發送到其他所有節點。如果其他節點收到主節點的PRE-PREPARE,會返回一個PREPARE消息。一旦節點收到PRE-PREPARE消息以及\(2f\)個PREPARE消息,那么該節點就有足夠的信息來接收proposal並發送commit消息。一旦一個節點收到\(2f+1\)個commit消息,那么這批請求可以被排序確認並加入到賬本中。
Hyperledger Indy 使用RNFT來同處理ordering和validation,從而實現一個簡單賬本同時實現排序和驗證。這一點與很多其他區塊鏈網絡有所不同,很多只是使用BFT協議來ordering。這些網絡將驗證留到請求被排序之后進行。
RBFT中用狀態來描述賬本,所有有效的、被接收的請求都可能改變賬本狀態。賬本狀態是保存在數據庫中的變量及其值的組合。狀態以Merkle Patricia樹的結構被加密保存在數據庫中(Merkle Patricia樹在以太坊中實現)。Hyperledger Indy將Decentralized Identifers (DIDs) 作為狀態來存儲,其中狀態包括驗證秘鑰及其他東西。內存中賬本交易的復制及狀態的改變是在proposal過程中更新的,主節點在發出proposal后就更新狀態,而非主節點是在收到確認proposal時才更新狀態。當proposal獲得排序驗證,賬本的狀態改變就會被確認。如果由於某種原因,proposal失敗了,那么尤其發生的狀態改變將會恢復。
Hyperledger Iroha 中的共識
Hyperledger Iroha中引入了稱為Sumeragi的BFT算法,該方法可以容錯\(f\)個錯誤節點,在下面論文中提出。
BChain: Byzantine Replication with High Throughput and Embedded Reconfiguration
在B-Chain中,我們在驗證交易時考慮全局順序的概念,並且把節點分為A、B兩組,其中A包含\(2f+1\)個節點,B組包含剩余的節點。在正常情況下,確認一個交易只需要\(2f+1\)個節點簽名就可以了,因此這是我們在交易確認中只使用\(2f+1\)個節點。只有當確認出現錯誤時,才會用到剩余的節點,第\(2f+1\)個節點稱為代理尾部。正常情況下的交易驗證過程如下圖所示:
Client端首先會向主導節點提交交易,這個主導節點會驗證交易並將其放到隊列中,並且對交易簽名。之后,該節點將交易光波導其他\(2f+1\)個驗證節點。
處理節點的順序是由稱之為hijiri的服務器信譽系統來決定的,Hijiri基於以下三個因素來計算服務器的可靠性。
- 每個server在成員管理系統中注冊的時間
- 成功處理交易的次數
- 是否發生過錯誤
為了檢測錯誤,每個server在簽署並向代理尾部節點(第2f+1個節點)廣播一個交易時會設置一個定時器。如果在定時器時間內沒有收到回復或者是發生了錯誤,那么該server會繼續下尾部節點的下一個節點廣播該交易。這個過程如下圖所示。
當一個驗證節點收到和交易時,會做如下幾步操作:
-
- 驗證簽名有效
-
- 驗證交易內容有效
-
- 臨時性將交易加入到賬本,這包括更新全局狀態的merkel root
-
- 簽署更新的Merkel root 以及交易內容的hash
-
- 廣播
-
- 當節點間同步時,Merkel樹的有效部分會在root符合的情況下共享。
Hyperledger Sawtooth中的共識
Hyperledger Sawtooth 推動同時使用lottery-based和voting-based算法的共識機制。默認情況下,Sawtooth使用一個lottery-based算法,稱為PoET。為了實現更為有效的分布式共識,一個好的lottery-based算法需要具備以下特點:
- 公平性,各個節點應該基於公平的相同的概率參與投票
- 投入,選舉的結果應該從潛在的投入值來獲得
- 有效性,應該有一個建檔的方式是所有的節點都可以驗證結果有效性
當前的Hyperledger Sawtooth實現中,構建了一個TEE(Trusted Execution Environment )系統,這保證了選舉過程的安全性及隨機性,而不用電力耗費或者是特殊硬件來加速工作量證明算法。
Every PoET validator requests a random time to wait from a trusted function before claiming leadership. The validator with the shortest wait time for a particular transaction block is implicitly elected the leader. The function “CreateTimer” creates a timer for a transaction block that is guaranteed to have been created by the TEE. The “CheckTimer” function verifes that the timer was created by the TEE and, if it has expired, creates an attestation that can be used to verify that validator did, in fact, wait the allotted time before claiming the leadership role.
The PoET leader election algorithm meets the criteria for a good lottery algorithm. It randomly distributes leadership election across the entire population of validators with a distribution that is similar to what is provided by other lottery algorithms. The probability of election is proportional to the resources contributed, where resources are general purpose processors with a TEE. An attestation of execution provides information for verifying that the certifcate was created within the TEE and that the validator waited the allotted time. Further, the low cost of participation increases the likelihood that the population of validators will be large, increasing the robustness of the consensus algorithm.