PBFT && RBFT算法流程


PBFT && RBFT算法流程以及其實現(上)

這篇文章主要是講一下RBFT中共識算法流程以及節點的加入的流程。在下一篇博客中,將使用Java實現該算法。

傳統的PBFT算法無法動態的添加和刪除結點,高魯棒拜占庭容錯算法RBFT(Robust Byzantine Tolerance)算法實現了該功能。

在RBFT算法中,有幾個變量我們需要知道:f,N,quorum

  • N ; 代表結點的數量。
  • f :代表PBFT中最多能容忍的錯誤的結點$ f = \lfloor\frac{N-1} { 3} \rfloor$
  • quorum:達到共識需要的結點數量 $quorum = \lceil \frac {N + f +1 }{2 }\rceil $

因此在PBFT算法中,為了能夠容忍f個錯誤,需要的結點數量是$3f+1$

在RBFT算法中,有一個主節點和多個從結點,其中主節點是通過選舉產生的,負責對客戶端發來的交易進行打包處理,而從節點很簡單,進行共識認證以及主結點的選取。

RBFT && PBFT的常規流程

下面是來自hyperchain的關於RBFT流程的一些介紹:

RBFT常規流程

RBFT的常規流程保證了區塊鏈各共識節點以相同的順序處理來自客戶端的交易。RBFT同PBFT的容錯能力相同,需要至少3f+1個節點才能容忍f個拜占庭錯誤。下圖為最少集群節點數下的共識流程,其N=4,f=1。圖中的Primary1為共識節點動態選舉出來的主節點,負責對客戶端發來的交易進行排序打包,Replica2,3,4為從節點。所有節點執行交易的邏輯相同並能夠在主節點失效時參與新主節點的選舉。

常規流程

RBFT共識保留了PBFT原有的三階段處理流程(PrePrepare、Prepare、Commit)的同時增加了重要的交易驗證(validate)環節,在保證對交易執行順序達成共識的同時也保證了對區塊驗證結果的共識。


RBFT常規流程在原生的PBFT算法中穿插了交易驗證環節,主節點將交易打包成塊后先行驗證,並將驗證結果包含到PrePrepare消息中進行全網廣播,這樣PrePrepare消息中既包含了排好序的交易信息也包含了區塊驗證結果。從節點在收到主節點的PrePrepare消息后先檢查消息的合法性,檢查通過后廣播Prepare消息表明本節點同意主節點的排序結果;在收到(quorum-1)個Prepare消息后從節點才會開始驗證區塊,並將驗證結果與主節點的驗證結果進行比對,比對結果一致則廣播Commit表明本節點同意主節點的驗證結果,否則直接發起ViewChange表明本節點認為主節點有異常行為。RBFT常規流程具體分為如下幾個步驟:

  1. 交易轉發階段: 客戶端將交易發送到區塊鏈中的任意節點(包括共識節點與記賬節點),其中記賬節點在收到交易后會主動轉發給與其相連的共識節點;而共識節點在收到客戶端的交易后將其廣播給其他共識節點,這樣所有共識節點的交易池中都會維護一份完整的交易列表;
  2. PrePrepare階段: 主節點按照如下策略進行打包:用戶可以根據需求自定義打包的超時時間(batch timeout)與打包的最大區塊大小(batch size),主節點在超時時間內收集到了足夠多(超過最大區塊大小個數)的交易或者超時時間到達后仍未收集到足夠多的交易都會觸發主節點的打包事件。主節點將交易按照接收的時間順序打包成塊,並進行驗證,計算執行結果,最后將定序好的交易信息連同驗證結果等寫入PrePrepare消息中廣播給所有共識節點,開始三階段處理流程;
  3. Prepare階段: 從節點在收到主節點的PrePrepare消息后,首先進行消息合法性檢查,檢查當前的視圖與區塊號等信息,檢查通過后向共識節點廣播Prepare消息;
  4. Commit階段: 從節點在收到(quorum-1)個Prepare消息以及相應的PrePrepare消息后進行驗證,並將驗證結果與主節點寫入PrePrepare消息中的驗證結果進行比對,比對結果一致則廣播Commit表明本節點同意主節點的驗證結果,否則直接發起ViewChange表明本節點認為主節點存在異常行為,需要切換主節點;
  5. 寫入賬本: 所有共識節點在收到quorum個Commit消息后將執行結果寫入本地賬本。

以上的過程還是很簡單的,就是主節點發送交易信息,如果大部分的從結點(也就是quorum個結點)同意,則這個交易信息會被寫入所有結點的區塊(少數服從多數)。

在前面我們可以發現,從節點是可以懷疑主節點的,也就是說從節點可以發起請求進行重新選舉,得到一個新的主節點(這個在主節點被攻擊或者宕機是非常有效的)。

主節點的生成以及變遷

在PBFT以及RBFT中,都有視圖(View),這個值從零開始只增不減。那么我們如何得到主節點呢?或者說重新選舉,選擇誰為主節點。

設:結點數為N,當前視圖為view,則主結點的id為:

$$primaryId = (view +1) mod N$$

下面的引用還是來自hyperchain,畢竟有圖能夠理解的更好。其中:

  • nullRequest 消息的目的是查看主節點是不是在線

視圖變更流程


上圖中,Primary 1為拜占庭節點,需要進行ViewChange。在RBFT中的ViewChange流程如下:

  1. 從節點在檢測到主節點有異常情況(沒有按時收到nullRequest消息)或者接收到來自其他f+1個節點的ViewChange消息之后會向全網廣播ViewChange消息,自身view從v更改為v+1;
  2. 新視圖中主節點收到N-f 個ViewChange消息后,根據收到的ViewChange消息計算出新視圖中主節點開始執行的checkpoint和接下來要處理的交易包,封裝進NewView消息並廣播,發起VcReset;
  3. 從節點接收到NewView消息之后進行消息的驗證和對比,如果通過驗證,進行VcReset,如果不通過,發送ViewChange消息,進行又一輪ViewChange;
  4. 所有節點完成VcReset之后向全網廣播FinishVcReset;
  5. 每個節點在收到N-f個FinishVcReset消息之后,開始處理確定的checkpoint后的交易,完成整個ViewChange流程。

由於共識模塊與執行模塊之間是異步通信的,而ViewChange之后執行模塊可能存在一些無用的validate緩存,因此共識模塊需要在ViewChange完成之前通知執行模塊清除無用的緩存,RBFT通過VcReset事件主動通知執行模塊清除緩存,並在清理完成之后才能完成ViewChange。

RBFT中結點動態的增添和刪除

在前面我們知道,PBFT算法是無法實現結點動態的增刪的,而新的算法RBFT實現了該功能。

結點的增加和刪除當然會遵守共識原則,下面還是來自hyperchain的介紹。畢竟別人介紹的比我好多了,我就不多介紹了。

簡單點來說,就是新加入的結點會向區塊鏈中的已經存在的結點申請加入,如果存在的結點同意的話,則就加入成功,然后新加入的結點會發送recovery消息(關於recovery可以看hyperchain的介紹),目的是為了讓自己與區塊鏈中結點的內容保持一致。然后新加入的結點會要求進行重新選舉主節點(因為N已經發生改變),然后完成主節點的更改。

新增節點流程


上圖中,Replica 5為待新增的節點。RBFT節點的動態新增節點流程如下:

  1. 新增節點Replica 5通過讀取配置文件信息,主動向現有節點發起連接,確認所有節點連接成功后更新自身的路由表,並發起recovery;
  2. 現有節點接收到Replica 5的連接請求后確認同意該節點加入,然后向全網廣播AddNode消息,表明自己同意該新節點加入整個共識網絡;
  3. 當現有節點收到N條(N為現有區塊鏈共識網絡中節點總數)AddNode消息后,更新自身的路由表,隨后開始回應新增節點的共識消息請求(在此之前,新增節點的所有共識消息是不予處理的);
  4. Replica 5完成recovery之后,向全網現有節點廣播ReadyForN請求;
  5. 現有節點在收到ReadyForN請求后,重新計算新增節點加入之后的N,view等信息,隨后將其與PQC消息封裝到AgreeUpdateN消息中,進行全網廣播;
  6. Replica 5加入后的共識網絡會產生一個新的主節點,該主節點在收到N-f個AgreeUpdateN消息后,以新的主節點的身份發送UpdateN消息;
  7. 全網所有節點在收到UpdateN消息之后確認消息的正確性,進行VCReset;
  8. 每個節點完成VCReset后,全網廣播FinishUpdate消息;
  9. 節點在收到N-f個FinishUpdate消息后,處理后續請求,完成新增節點流程。

這篇文章基本上就是從hyperchain上面copy上來的,在這里僅僅是做一個筆記用。如果想了解更多,建議參考官方文檔。這一篇主要是為了弄清楚PBFT or RBFT的流程,這幾天在看《區塊鏈底層設計 Java實戰》一直沒弄得太懂,然后代碼也寫的沒頭緒。這里不得不感謝牛冬(這本書的作者)大佬,很熱心的回答我的問題(真沒想到加作者的微信竟然加成功了O(∩_∩)O~~)。

哦,還得掉頭發,想一想怎么實現這些算法……


參考

  1. hyperchain:https://hyperchain.readthedocs.io/zh_CN/latest/consensus.html#


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM