拜占庭將軍問題不少人可能聽過,但不知道具體是什麼意思。那麼究竟什麼是拜占庭將軍問題呢? 本文從最通俗的故事講起,並對該問題進行抽象,並告訴你們拜占庭將軍問題爲何在區塊鏈領域做爲一個重點研究問題。html
「拜占庭將軍問題」也被稱爲「拜占庭容錯」。算法
拜占庭將軍問題是Leslie Lamport(2013年的圖靈講得住)用來爲描述分佈式系統一致性問題(Distributed Consensus)在論文中抽象出來一個著名的例子。服務器
這個例子大意是這樣的:網絡
拜占庭帝國想要進攻一個強大的敵人,爲此派出了10支軍隊去包圍這個敵人。這個敵人雖不比拜占庭帝國,但也足以抵禦5支常規拜占庭軍隊的同時襲擊。這10支軍隊在分開的包圍狀態下同時攻擊。他們任一支軍隊單獨進攻都毫無勝算,除非有至少6支軍隊(一半以上)同時襲擊才能攻下敵國。他們分散在敵國的四周,依靠通訊兵騎馬相互通訊來協商進攻意向及進攻時間。困擾這些將軍的問題是,他們不肯定他們中是否有叛徒,叛徒可能擅自變動進攻意向或者進攻時間。在這種狀態下,拜占庭將軍們才能保證有多於6支軍隊在同一時間一塊兒發起進攻,從而贏取戰鬥? 異步
注:「 拜占庭將軍問題中並不去考慮通訊兵是否會被截獲或沒法傳達信息等問題,即消息傳遞的信道絕無問題。Lamport已經證實了在消息可能丟失的不可靠信道上試圖經過消息傳遞的方式達到一致性是不可能的。因此,在研究拜占庭將軍問題的時候,已經假定了信道是沒有問題的。 」分佈式
單從上面的說明可能沒法理解這個問題的複雜性,咱們來簡單分析一下:post
先看在沒有叛徒狀況下,假如一個將軍A提一個進攻提議(如:明日下午1點進攻,你願意加入嗎?)由通訊兵通訊分別告訴其餘的將軍,若是幸運中的幸運,他收到了其餘6位將軍以上的贊成,發起進攻。若是不幸,其餘的將軍也在此時發出不一樣的進攻提議(如:明日下午2點、3點進攻,你願意加入嗎?),因爲時間上的差別,不一樣的將軍收到(並承認)的進攻提議多是不同的,這是可能出現A提議有3個支持者,B提議有4個支持者,C提議有2個支持者等等。性能
再加一點複雜性,在有叛徒狀況下,一個叛徒會向不一樣的將軍發出不一樣的進攻提議(通知A明日下午1點進攻, 通知B明日下午2點進攻等等),一個叛徒也會可能贊成多個進攻提議(即贊成下午1點進攻又贊成下午2點進攻)。學習
叛徒發送先後不一致的進攻提議,被稱爲「拜占庭錯誤」,而可以處理拜占庭錯誤的這種容錯性稱爲「Byzantine fault tolerance」,簡稱爲BFT。區塊鏈
求解拜占庭將軍問題,隱含要知足如下兩個條件:
1)每一個忠誠的將軍必須收到相同的命令值vi(vi是第i個將軍的命令)。
2)若是第i個將軍是忠誠的,那麼他發送的命令和每一個忠誠將軍收到的vi相同。
因而,拜占庭將軍問題的能夠描述爲:一個發送命令的將軍要發送一個命令給其他n-1個將軍,使得:
IC1.全部忠誠的接收命令的將軍遵照相同的命令;
IC2.若是發送命令的將軍是忠誠的,那麼全部忠誠的接收命令的將軍遵照所接收的命令。
Lamport對拜占庭將軍問題的研究代表,當n>3m時,即叛徒的個數m小於將軍總數n的1/3時,經過口頭同步通訊(假設通訊是可靠的),能夠構造同時知足IC1和IC2的解決方案,即將軍們能夠達成一致的命令。但若是通訊是可認證、防篡改僞造的(如採用PKI認證,消息簽名等),則在任意多的叛徒(至少得有兩個忠誠將軍)的狀況下均可以找到解決方案。
而在異步通訊狀況下,狀況就沒有這麼樂觀。Fischer-Lynch-Paterson定理證實了,只要有一個叛徒存在,拜占庭將軍問題就無解。翻譯成分佈式計算語言,在一個多進程異步系統中,只要有一個進程不可靠,那麼就不存在一個協議,此協議能保證有限時間內使全部進程達成一致。
因而可知,拜占庭將軍問題在一個分佈式系統中,是一個很是有挑戰性的問題。由於分佈式系統不能依靠同步通訊,不然性能和效率將很是低。所以尋找一種實用的解決拜占庭將軍問題的算法一直是分佈式計算領域中的一個重要問題。
在這裏,咱們先給出分佈式計算中有關拜占庭缺陷和故障的兩個定義:
定義1:拜占庭缺陷(Byzantine Fault):任何觀察者從不一樣角度看,表現出不一樣症狀的缺陷。
定義2:拜占庭故障(Byzantine Failure):在須要共識的系統中因爲拜占庭缺陷致使喪失系統服務。
在分佈式系統中,不是全部的缺陷或故障都能稱做拜占庭缺陷或故障。像死機、丟消息等缺陷或故障不能算爲拜占庭缺陷或故障。拜占庭缺陷或故障是最嚴重缺陷或故障,拜占庭缺陷有不可預測、任意性的缺陷,例如遭黑客破壞,中木馬的服務器就是一個拜占庭服務器。
在一個有拜占庭缺陷存在的分佈式系統中,全部的進程都有一個初始值。在這種狀況下,共識問題(Consensus Problem),就是要尋找一個算法和協議,使得該協議知足如下三個屬性。
1)一致性(Agreement):全部的非缺陷進程都必須贊成同一個值。
2)正確性(Validity):若是全部的非缺陷的進程有相同的初始值,那麼全部非缺陷的進程所贊成的值必須是同一個初始值。
3)可結束性(Termination):每一個非缺陷的進程必須最終肯定一個值。
根據Fischer-Lynch-Paterson的理論,在異步通訊的分佈式系統中,只要有一個拜占庭缺陷的進程,就不可能找到一個共識算法,可同時知足上述要求的一致性、正確性和可結束性要求。在實際狀況下,根據不一樣的假設條件,有不少不一樣的共識算法被設計出來。這些算法各有優點和侷限。算法的假設條件有如下幾種狀況:
1)故障模型:非拜占庭故障/拜占庭故障。
2)通訊類型:同步/異步。
3)通訊網絡鏈接:節點間直連數。
4)信息發送者身份:實名/匿名。
5)通訊通道穩定性:通道可靠/不可靠。
6)消息認證性:認證消息/非認證消息。
在出現比特幣以前,解決分佈式系統一致性問題主要是Lamport提出的Paxos算法或其衍生算法。Paxos類算法僅適用於中心化的分佈式系統,這樣的系統的沒有不誠實的節點(不會發送虛假錯誤消息,但容許出現網絡不通或宕機出現的消息延遲)。
中本聰在比特幣中創造性的引入了「工做量證實(POW : Proof of Work)」來解決這個問題,有興趣可進一步閱讀工做量證實(猛擊!)。
經過工做量證實就增長了發送信息的成本,下降節點發送消息速率,這樣就以保證在一個時間只有一個節點(或是不多)在進行廣播,同時在廣播時會附上本身的簽名。
這個過程就像一位將軍A在向其餘的將軍(B、C、D…)發起一個進攻提議同樣,將軍B、C、D…看到將軍A簽過名的進攻提議書,若是是誠實的將軍就會馬上贊成進攻提議,而不會發起本身新的進攻提議。
以上就是比特幣網絡中是單個區塊(帳本)達成共識的方法(取得一致性)。
理解了單個區塊取得一致性的方法,那麼整個區塊鏈(總帳本)若是達成一致也好理解。
咱們稍微把將軍問題改一下:
假設攻下一個城堡須要屢次的進攻,每次進攻的提議必須基於以前最屢次數的勝利進攻下提出的(只有這樣敵方已有損失最大,我方進攻勝利的可能性就更大),這樣約定以後,將軍A在收到進攻提議時,就會檢查一下這個提議是否是基於最多的勝利提出的,若是不是(基於最多的勝利)將軍A就不會贊成這樣的提議,若是是的,將軍A就會把此次提議記下來。這就是比特幣網絡最長鏈選擇 (猛擊!)。
工做量證實其實至關於提升了作叛徒(發佈虛假區塊)的成本,在工做量證實下,只有第一個完成證實的節點才能廣播區塊,競爭難度很是大,須要很高的算力,若是不成功其算力就白白的耗費了(算力是須要成本的),若是有這樣的算力做爲誠實的節點,一樣也能夠得到很大的收益(這就是礦工所做的工做),這也實際就不會有作叛徒的動機,整個系統也所以而更穩定。
礦工挖礦得到比特幣獎勵以及記帳所得的交易費用使得礦工更但願維護網絡的正常運行,而任何破壞網絡的非誠信行爲都會損害礦工自身的利益。所以,即便有些比特幣礦池具有強大的算力,它們都沒有做惡的動機,反而有動力維護比特幣的正常運行,由於這和它們的切實利益相關。
注:原始的拜占庭容錯系統因爲須要展現其理論上的可行性而缺少實用性。另外,還須要額外的時鐘同步機制支持,算法的複雜度也是隨節點增長而指數級增長。實用拜占庭容錯系統(PBFT)(猛擊!)下降了拜占庭協議的運行復雜度,從指數級別下降到多項式級別(Polynomial),使拜占庭協議在分佈式系統中應用成爲可能。
總結:共識算法的核心就是解決拜占庭將軍問題(分佈式網絡一致性問題)。
Lamport L,Shostak R,Pease M.The Byzantine generals problem.ACM Trans.on Programming Languages and Systems,1982,4(3):382-401.
【時間倉促,若有錯誤,歡迎指正! || 歡迎留下您的評語! 你們一塊兒探討、學習區塊鏈!】
【轉載請註明出處!http://www.cnblogs.com/X-knight/】