分布式一致性問題,區塊鏈里體現就是共識問題。
共識機制就是在一個群體中的個體通過某種方式達成一致性的一種機制,比如在一個團隊、或者一個公司里的個體意見不一致時,就需要有一個領導,由領導來做決定,保證團隊達成共識。
目前的共識算法,主要有基於算力的POW,基於股權的POS和基於投票的DPOS算法,以及著名的拜占庭容錯算法。
一、共識機制
團隊里的共識機制延伸到普通的分布式系統里面,就是系統需要有一個master,系統的所有決定都由master來達成共識,在分布式系統里面master的選舉其實就是基於某種共識機制達成共識。
到了區塊鏈中,由於區塊鏈是一種去中心化的分布式系統,所以區塊鏈中是沒有類似於團隊里的領導,以及分布式系統中的master的角色,這樣就需要有某種共識機制,以便保證系統一致性。
實際上當節點之間的通信網絡不可靠的情況下,系統是無法達成共識的,具體原因請參考“兩軍問題"。
即使在網絡通信可靠的情況下,一個可擴展的分布式系統的共識問題也是無解的。這個結論被稱為”FLP不可能性原理“。一般的把故障(不響應)即信道不可靠的情況稱為”非拜占庭錯誤“,惡意響應(即系統被攻擊)稱為”拜占庭錯誤“。
二、拜占庭將軍問題
拜占庭將軍問題是一個共識問題: 首先由Leslie Lamport與另外兩人在1982年提出,被稱為The Byzantine Generals Problem或者Byzantine Failure。核心描述是軍中可能有叛徒,卻要保證進攻一致,由此引申到計算領域,發展成了一種容錯理論。
論文地址:
The Byzantine Generals Problem
一群將軍想要實現某一個目標(一致進攻或者一致撤退),但是單獨行動行不通,必須合作,達成共識;由於叛徒的存在,將軍們不知道應該如何達到一致。
1.兩軍問題和TCP協議
拜占庭將軍問題中並不去考慮通信兵是否會被截獲或無法傳達信息等問題,即消息傳遞的信道絕無問。Lamport已經證明了在消息可能丟失的不可靠信道上試圖通過消息傳遞的方式達到一致性是不可能的。所以,在研究拜占庭將軍問題的時候,我們已經假定了信道是沒有問題的,並在這個前提下,去做一致性和容錯性相關研究。
如果需要考慮信道是有問題的,這涉及到了另一個兩軍問題,兩軍問題在經典情境下是不可解的,現代通信系統中應用三次握手與TCP協議來處理此類問題,不過這也只是一種相對可靠的方式。
2.口頭協議算法
Lamport論文:
對於這個算法需要說明的是:
(1) 在第一輪將軍會把消息發送給所有的副官,第i個副官收到的記為 Vi。如 1(這里代表的是Attack)
(2) 在第二輪里面,Li(即第i個副官)會懷疑將軍發來的消息Vi是對還是錯,於是他會問其余的副官。這樣他就會得到剩下的(n-2)個副官的值。 i從1到n-1,所以每個副官都會得到剩余的n-2個副官手里的Vi。在這一步驟里,忠誠的副官j會直接將自己的 Vj發送給其它人。叛徒則會發假消息。
在n=7,m=2的時候 如果將軍是忠臣的話,那么在第二輪忠誠的副官確實已經可以判斷出要做的決定,因為他們會收到(1 1 1 0 0 )再加上將軍發來的1就是 1 1 1 1 0 0 但是這個算法是遞歸的所有必須要到第三輪。並且如果將軍是個叛徒的話,那么第二輪有情形是做不出決定的。
這里對進入第三輪的解釋是,如L1收到其它L2~L6發來的Vj, 但是他要懷疑准確性,比如L1會想L2發給自己是否是正確的呢?那么就進入第三輪進行投票。
(3)在第三輪里面,接着(2)中后面的問題。L1會依次詢問L3,4,5,6 ,問他們上一輪L2給他們發了什么,然后L1會得到在(2)中 L2->L3, L2->L4,L2->L5, L2->L6的值 這樣再結合自己的L2->L1的值,從這5個里面用majority函數投出決定得到L2發給自己的消息值。依次再進行L3,L4,L5,L6在第二輪中發給自己的消息的確認。
這樣L1就完成了第二輪的確認。之后L1再從第一步中將軍發給自己的vi和第二輪中確定的5個值中投出自己的決定。
其余的L2,L3后續也進行同樣的步驟。
3.書面協議算法
書面協議和口頭協議最大區別是,副官可以叛變並且說謊,也就是中國人講的口說無憑。
現在我們給消息加上將軍的簽名,必須通過簽名來驗證,就是為了防止說謊。
在簽名算法中加了兩個條件:
- 忠誠將軍的簽名是不能偽造的,內容修改可檢測
- 任何人都可以識別將軍的簽名,叛徒可以偽造叛徒司令的簽名
這里Lamport規定,每條消息只可以復制,然后加上自己的姓名再發出去。
Lamport論文:
三、PBFT 實用拜占庭算法
這里借用一個類比(知乎[Devin Zeng]:
PBFT算法要求至少要4個參與者,一個被選舉為總司令,3個師長。總統對總司令下達命令,你們向前行軍500公里,總司令就會給3個師長發命令向前行軍500公里。3個軍長收到消息后會執行命令,並匯報結果。A師長說我在首都以東500公里,B師長說我在首都以東500公里,C師長說我在首都以東250公里。總司令總結3個師長的匯報,發現首都以東500公里占多數(2票>1票),所以就會忽略C軍長的匯報結果,給總統說,好了,現在部隊是在首都以東500公里了。
1.五個概念
client:請求(request)資源者
replica:副本,所有參與提供服務的節點
primary:承擔起提供服務主要職責的節點
backup:其他副本,但相對於primary角色
view:處於存在primary-bakup場景中的相對穩定的關系,叫視圖。
如果primary出現故障,這種相對穩定的視圖關系就會轉變(transit),某個backup轉變為primary。
2.四個階段
client請求階段,客戶端請求資源。
預准備(pre-prepare):主節點向所有backup節點發送預准備消息,其中包括當前視圖編號,client請求以及請求摘要,簽名是否一致等。
准備(prepare):包括主節點在內的所有副本節點在收到准備消息之后,對消息的簽名是否正確,視圖編號是否一致,以及消息序號是否滿足水線限制這三個條件進行驗證,如果驗證通過則把這個准備消息寫入消息日志中。
確認(commit):每個副本接受確認消息的條件是:1)簽名正確;2)消息的視圖編號與節點的當前視圖編號一致;3)消息的序號n滿足水線條件,在h和H之間。一旦確認消息的接受條件滿足了,則該副本節點將確認消息寫入消息日志中。
回復(reply):結果反饋。
共識真的不能達成嗎
關於拜占庭等問題的討論只是學術上極端情況下的理論值,現實中的物理系統遠比這個要復雜,我們付出一定的代價總是能做到一定程度的共識。