1. 程式人生 > >拜占庭共識演算法RBFT:Redundant Byzantine Fault Tolerance

拜占庭共識演算法RBFT:Redundant Byzantine Fault Tolerance

最近在研究拜占庭共識,做個記錄吧,有些可能也沒理解透。
RBFT : Redundant Byzantine Fault Tolerance
論文地址:http://lig-membres.imag.fr/aublin/rbft/report.pdf

摘要:

提出其他已有的BFT演算法(prime、Aardvark、Spinning)其實並不能真正的進行拜占庭容錯,主要是由於存在一個“primary”用來排序的。如果primary作惡,整個系統的效能會顯著下降而且不會被發現。而RBFT則提出了新的模式:採用多核機機器並行執行多個PBFT的協議例項,只有master例項的結果會被真正執行,每個協議例項都會被監控其效能並與master例項比較,如果master的效能不行,則會認為此master的primary節點為壞節點併發起替換流程。據測算RBFT在存在BFT攻擊時的效能下降最大為3%,而其他的協議為:Prime(78%)、Aardvark(87%)、Spinning(99%)。

RBFT協議:

綜述:
N= 3f+1個nodes(f為拜占庭節點最大數),每個node裡並行跑f+1個(why?:如果f個例項的primary都是壞節點,那麼系統將無法識別拜占庭錯誤。當f+1個的時候就能保證,見下面的定理或者引理)BFT例項(PBFT協議),只有一個為master,其他的例項為backup。每個例項都有自己的replica,f+1個例項的primary必須滿足:每個node最多隻是一個例項的primary。每個例項都會對請求排序,但是隻有master才會真正的執行,backup只排序與master效能作比較。每個node會執行一個監控程式,監控所有f+1個例項的吞吐量。如果2f+1個node發現master和最佳的backup例項效能差達到一定閾值則此master的primary節點會被認為是惡意節點,將會選出新的primary,還可以選擇將表現最好的backup升級為master不過這樣需要一個機制在切換master的時候保證各個例項狀態的同步(機制參考文獻11)。RBFT正確的工作需要f+1個例項接收到的是同樣的客戶端請求。不過當一個node收到req的時候並不會直接給他自己的f+1個例項執行,而是先轉發給所有的其他節點。當他收到2f+1(why?:一定會收到2f+1個,不過應該只需要f+1就可以確定好節點一定都收到了這個請求)個客戶端請求copy時(包括自己的)此節點會每一個好節點最終都會接收到請求(因為請求至少傳送給了一個好節點)然後再將請求發給f+1個例項去執行。與Aardvark不同的是,RBFT的view change是又監控策略控制並且應用到所有f+1個例項裡,而Aardvark由協議發起。
在這裡插入圖片描述

具體步驟:
1、客戶端吧請求傳送到所有節點
請求格式如下:o:請求操作,rid:請求識別符號,c:client
在這裡插入圖片描述
客戶端需要用私鑰簽名,通過MAC認證。節點接到請求需要驗證簽名、MAC認證,如果不對則加入黑名單不執行後續。如果請求已經執行過,則直接返回執行結果給client。
2、好節點傳播(propagate)請求給所有節點
傳播資訊格式如下:
在這裡插入圖片描述
請求驗證通過則節點發送PROPAGATE資訊給所有其他節點。此過程可以保證只要有一個好節點收到了請求那麼每一個好節點最終都會收到請求。節點接收其他節點的PROPAGATE資訊要驗證其MAC認證和簽名。如果有效,且之前沒有接受過此reqest則會發送PROPAGATE給其他節點(這麼說即使client沒發到節點也可以通過其他節點傳來的做驗證,然後轉發,讓其他節點也收到此req)。當一個節點收到f+1(why?:只要有一個好節點收到了這個request則所有的request就會收到這個request)個PROPAGATE資訊(針對某個req)則此請求就準備好給f+1個例項去執行排序了(只排序識別符號而不是整個請求即:client id 、reqest Id、 hash值,這麼做可以提高效能,畢竟處理位元組少了)(why?不怕被改以後無法恢復req麼)。
3、4、5 、 每個例項執行一個3階段提交協議(PBFT協議)來對請求排


RBFT的三階段請求 (只有MAC驗證)
每個例項的primary replica接收到請求後傳送PRE-PREPARE訊息給其他節點,包含MAC認證。非primary的replica則會儲存此請求並等待對應的primary的PRE-PREPARE訊息並驗證其MAC。當node收到f+1個同樣的request後然後這些非primary replica傳送PREPARE訊息給所有的replica。如果有2f個(primary不轉PREPARE,最多f個是壞掉的,那麼f個是好的,加上本身比壞的返回多)PREPARE和PRE-PREPARE訊息吻合,則replica傳送COMMIT訊息給所有replica,MAC認證。收到2f+1個COMMIT資訊後會將這此排好序的請求返回給其執行的node上。
6、節點執行請求併發送返回給client
RBFT的處理過程。(只有MAC驗證)
節點收到排好序的請求後會執行master 的返回的請求。執行完畢後會返回給client結果,MAC認證。當客戶端接收到f+1個REPLY有效且一致的返回後則接受此返回作為request執行的結果。
在這裡插入圖片描述
在這裡插入圖片描述

監控機制:

RBFT提供一個監控機制來發現master例項是否壞掉了。
每個節點為每個例項維護一個計數器(一共f+1個),用來記錄此例項已經排序的請求數(也就是說收到2f+1個COMMIT訊息的請求數)。節點會使用這些計數器週期性的計算每個例項的吞吐量並更新計數器。以下一些情況master會認為壞掉了觸發協議例項變更:
1、master的吞吐量比backup的平均吞吐量低達到一定閾值。閾值是根據無拜占庭錯誤和有拜占庭錯誤的吞吐量差異設定的。
2、監控程式還監控排序時間,此機制為了保證master對於所有的client處理都是公平的。設定了每個請求的最大處理時間和client在不同例項裡處理的時間差值。如果請求超過最大處理時間或者某個client在不同的例項裡處理的時間差異過大也會觸發協議變更

協議例項變更機制:

變更壞掉的primary。由於每個節點最多是一個例項的primary所以要動就是要所有primary全動。
每個節點維護一個計數器來記錄每個例項的變更資訊。如果節點發現需要變更primary則會發送INSTANCE CHANGE訊息給所有的節點,MAC認證。節點接收到傳來的INSTANCE CHANGE訊息後驗證MAC,然後跟自身的計數器比對,如果自身的更大,則忽略,如果傳來的更大則檢視自己是否也需要傳播INSTANCE CHANGE訊息(也是比較master和backup的效能),如果收到2f+1個有效的INSTANCE CHANGE訊息則計數器加1然後啟動view change流程(就是改primary,PBFT也是)。此後每個例項的primary都得到了更新,當然也包括master 的。(更新策略如果又換到了壞的呢?那會觸發再次更新。。 前面提到的直接換最好的backup為master可能會更好點)

兩種BFT攻擊形式:

f個node是壞的,所以執行在此node裡的所有例項都是壞的,所有的client都是壞的。
master例項執行的primary的node是好的:
此時:壞節點的目標是儘可能降低master例項的效能而不觸發協議變更(why要不觸發協議變更?: 論文裡有證明,當primay of master為好節點時不會觸發,主要是master的吞吐量比backup的平均吞吐量低達到一定閾值的這個閾值是不是隨意定的是根據理論算出來的)。
方式:

  • client傳送req請求給所有節點,master primary節點請求驗證無效,其他有效
  • faulty node 給master primary節點發送無效的最大size的PROPAGATE訊息,給他其他的正常
  • faulty node 在master例項的replica傳送最大的訊息
  • faulty node 在master例項的replica不參與協議

master例項執行的primary的node是壞的:
此時:壞節點的目標是儘可能的降低backup例項的效能,這樣就可以留給壞的primary富裕的空間來降低master的效能而不被發現(怎麼定義發現?)。
方式:

  • client 給好節點發送無效的請求
  • faulty node給好節點發無效且最大size的訊息並且不參與PROPAGATE階段
  • faulty node在backup節點上的replicas傳送無效資訊,且不參與協議。

論文中的幾個定理或者引理:

  • 如果primary of master 是好的那麼不會觸發instance change
  • 如果primary of master 是壞的並且吞吐量過低滿足限制條件,則一定會觸發instance change
  • 要確保拜占庭容錯,必須至少執行f+1個例項