【分布式共識二】拜占庭將軍問題----口頭協議


區塊鏈兄弟社區,區塊鏈技術專業問答先行者,中國區塊鏈技術愛好者聚集地

作者:吳壽鶴

來源:區塊鏈兄弟

原文鏈接:http://www.blockchainbrother.com/article/7

著權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

拜占庭將軍問題是一個共識問題: 首先由Leslie Lamport與另外兩人在1982年提出,被稱為The Byzantine Generals Problem或者Byzantine Failure。核心描述是軍中可能有叛徒,卻要保證進攻一致,由此引申到計算領域,發展成了一種容錯理論。隨着比特幣的出現和興起,這個著名問題又重入大眾視野。

關於拜占庭將軍問題,一個簡易的非正式描述如下:

拜占庭帝國想要進攻一個強大的敵人,為此派出了10支軍隊去包圍這個敵人。這個敵人雖不比拜占庭帝國,但也足以抵御5支常規拜占庭軍隊的同時襲擊。基於一些原因,這10支軍隊不能集合在一起單點突破,必須在分開的包圍狀態下同時攻擊。他們任一支軍隊單獨進攻都毫無勝算,除非有至少6支軍隊同時襲擊才能攻下敵國。他們分散在敵國的四周,依靠通信兵相互通信來協商進攻意向及進攻時間。困擾這些將軍的問題是,他們不確定他們中是否有叛徒,叛徒可能擅自變更進攻意向或者進攻時間。在這種狀態下,拜占庭將軍們能否找到一種分布式的協議來讓他們能夠遠程協商,從而贏取戰斗?這就是著名的拜占庭將軍問題。

應該明確的是,拜占庭將軍問題中並不去考慮通信兵是否會被截獲或無法傳達信息等問題,即消息傳遞的信道絕無問題。Lamport已經證明了在消息可能丟失的不可靠信道上試圖通過消息傳遞的方式達到一致性是不可能的。所以,在研究拜占庭將軍問題的時候,我們已經假定了信道是沒有問題的,並在這個前提下,去做一致性和容錯性相關研究。

attachments-2017-07-aNZUwMvv5969a75ddbca4.png

拜占庭容錯算法

我們已經了解了拜占庭將軍問題的場景,並且明確了這個問題的解決是建立在通信兵可以正確的傳達信息的基礎上的,即信道絕對可信。接下來,我們將探討拜占庭將軍問題的實質。

拜占庭容錯算法是解決在同步網絡,任意失敗模型情況下達成一致性共識。

​拜占庭將軍問題實質

回顧問題,一群將軍想要實現某一個目標(一致進攻或者一致撤退),但是單獨行動行不通,必須合作, 達成共識;由於叛徒的存在,將軍們不知道應該如何達到一致。注意,這里“一致性”才是拜占庭將軍問題探討的內容,如果本來叛徒數量就已經多到了問題不可解的地步,這個就是“反叛”的問題了;同時,我們的目標是忠誠的將軍能夠達成一致,對於這些忠誠的將軍來說,進攻或者撤退都是可以的,只要他們能夠達成一致就行。

但是,光靠“一致”就可以解決問題嗎?考慮一下,如果萬事俱備,客觀上每個忠誠的將軍只要進攻了就一定能夠勝利,但是卻因為叛徒的存在他們都“一致的”沒有進攻;反之,條件不利,將軍們不應該進攻,但是卻因為叛徒的存在所有人都“一致的”進攻了。

可以發現,只有“一致性”是不足以解決拜占庭將軍問題的,我們還需要提出一個“正確性”要求。這個要求是值得斟酌的,因為如果客觀來看或許會有“絕對正確的”判斷,但是針對每一個將軍,大家的判斷或許都不相同,我們如何定義“正確”呢?我們或許可以簡單地說,正確就是每個忠誠的將軍都正確的表達了自己的意思,不會因為叛徒讓別的將軍認為忠誠的將軍是叛徒而不采用他傳達的消息。

至此,我們將拜占庭將軍問題簡化成了,所有忠誠的將軍都能夠讓別的將軍接收到自己的真實意圖,並最終一致行動;而形式化的要求就是,“一致性”與“正確性”。

如果將問題推廣開來,可以發現針對一致性和正確性的算法並不要求命令必須是“進攻/撤退”或是“1/0”,而可以是“發送消息1/發送消息2/待機”或“x/y/z/w”,這意味着拜占庭將軍問題算法可以為多種分布式系統提供啟發,比如電力系統或網絡系統。

由此可見,這個問題說到底是一個關於一致性和正確性的算法問題,這個算法是針對的是忠誠的將軍,因為叛徒可以做出任何超出約定的判斷。我們就是要在有叛徒的干擾下,找到一個抗干擾的算法。要解決這個算法問題,我們需要將形式化要求具體化。

口頭協議推演

下面的這個截圖是從Lamport發表的論文中截取的:

attachments-2017-07-4niKBl885969a77bc38ca.png

對於這個算法需要說明的是:

(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.等等也進行同樣的步驟。

如果還是沒清晰的話,直接看下面的過程:

attachments-2017-07-KlzHgnSj5969a790c4934.png

這里需要注意的是:Lamport提出的容錯的兩個條件

IC1:即所有的忠誠的副官要遵守同一個命令,即達成一致;

IC2:假如將軍是忠誠的,那么每一個忠誠的副官都應該按照將軍的意思行事。

這里將軍是叛徒,所以只要滿足IC1條件即可。

Step1 : C給L1~L6 依次發 A R A R A X  (A,R代表攻擊和撤退,這里因為C是叛徒,所以可以隨便發給L1-L5消息,這里只是一個例子,可以用其他的值,只要最后滿足IC1就可以)

Step2: L1為例,L1會懷疑將軍發給自己的消息,於是會問L2-L6

 

  L2(R) L3(A) L4(R) L5(A) L6(X) A(L1)
L2 R R R R A R
L3 A A A A R A
L4 R R R R A R
L5 A A A A R A
L6 R A R A A A

Step3:其實在第三步中 L1會依次確認在step2中, L2~L6發給自己的信息. 例如確認L2時 會問L3-L6,在Step2中L2發給你們了什么

最后得到 R, R, R,X (因為L6這時候肯定又說謊) 再結合自己的R , L1確定在Step2中收到L2發來的是R,之后又確認了L3-L6。大家可以自己在草稿紙上畫出。

其實因為L1-L5都是忠誠,他們不會在Step2中撒謊,所以只需投票L6即可 ,(A R A R A )是L6發給L1-L5的信息,最后投出發的是A , 將A修改到step2中L1-L5收到的

信息中其余的信息可以不用改。

最后得到L1-L5均是 4個A, 2個R。 以L1為例=R  A  R  A  A  A 

即L1~L5達成了一致。

文章發布只為分享區塊鏈技術內容,版權歸原作者所有,觀點僅代表作者本人,絕不代表區塊鏈兄弟贊同其觀點或證實其描述


免責聲明!

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



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