0.前言
最近一直在研究區塊鏈中的核心技術組件:共識算法。
作為一個非CS專業出身的人,理解共識算法我更多的強調邏輯的正確而非數學公式及代碼實現。那么考慮問題的思路如下:
三連問:
為什么需要共識?—-如何共識?——達成共識的效果如何?
這三個問題對應到區塊鏈中是這樣的:
一個區塊鏈面臨著怎樣的信任環境?
在該信任環境下應該采用何種共識算法?
該共識算法下區塊鏈的性能及其他特性如何?(TPS,資源消耗,安全隱私等)
本文我們主要關注為什么需要共識—-由此衍生出需要著重討論的兩軍問題和拜占庭將軍問題,并討論兩軍問題和拜占庭將軍問題的共識策略和效果。而關于區塊鏈當中不同共識算法的使用,我會再下一篇中進行描述。
為什么需要共識?從社會學的角度上來說這似乎是一個無需回答的問題:群體總是需要合作協力,而共識是合作協力的前提。上句是一個非常宏觀的共識理由,但如果以通信的視角來看我們則會發現更加具體的理由。
1.信道不可靠情況下能否共識—-兩軍問題
“馬上相逢無紙筆,憑君傳語報平安。”—-岑參《逢入京使》
上句是一個典型的通信場景:主角需要通過中間人向家人傳遞自己平安的消息。誠然,托熟人帶個信這個行為從古至今都是合理的,但其合理性建立在一個暗含的前提上———這個熟人是可靠的。
當傳遞信息的人或者信道本身有問題時,下面的兩軍問題就發生了:
如下圖所示,一支實力強大的白軍駐扎在山谷中,兩支單兵實力較弱的藍軍駐扎在山谷兩側。兩支藍軍合力進攻可以擊破白軍,但在這之間他們必須就進攻時間達成一致:比如午夜偷襲或者正午猛攻。
一個限制性條件是,兩支藍軍無法通過遠程喊話的方式來協商進攻時間,他們必須穿過山谷派出通信兵去傳信,此時就存在著通信兵可能被白軍俘獲的問題——即傳令信道是不可靠的。那么在信道不可靠的前提下,兩軍之間有辦法就攻擊時間問題達成一致嗎?且看以下推演:
a.假設左側藍軍提議午夜0點進行攻擊,他派出通信兵將該信息傳遞給右側藍軍。
b.左側藍軍考慮到信使被截獲的危險,所以他必須收到右側藍軍的回信“收到了你的0點進攻指令”
c.右側藍軍即使真的收到了左側藍軍的指令并予以回信,但他仍會猶豫是否0點進攻。因為有白軍截獲可能,右側藍軍無法確認左側藍軍是不是聽到了“我同意你0點進攻的提議”。于是右側藍軍還需左側藍軍再回信,回信內容為“我知道了你確認了我的提議”
d.左側藍軍繼續對C中的內容進行回復,”我知道了你確認了我0點進攻的提議“,但考慮到信使被截獲的危險,他也不敢100%的到點進攻,因此他又需要右側藍軍對這一輪回信再進行答復。
e.以上步驟會形成死循環:無論通信進行多少輪,兩側藍軍都需要等待對方的下一輪回復,這個通信系統中永遠都需要下一個回執。
經過以上推演可知,在信道不可靠的情況下,不存在一個通信的方法使得兩側藍軍達到共識。更進一步的考慮,當這個通信兵被截獲且傳令內容被白軍修改時,情況將會變得更加復雜。因此一般看來,兩軍問題是沒有一個完美的解決方案的。
2.信道可靠情況下能否共識—拜占庭將軍問題
“千人同心,則得千人之力;萬人異心,則無一人之用” —《淮南子.兵略訓》
那么當信道可靠的情況下,能夠做到千人同心達成共識嗎?或者如果不能做到千人同心,能夠做到多少異心者的情況下達成共識?這實際上就涉及到了另外一個叫做拜占庭將軍的問題:
古代拜占庭帝國兵多將廣,他們決議合力圍攻一個城市。但帝國的將軍們分散在這個城市的周圍,單兵作戰必敗無疑,只有軍隊數量超過一定規模之后才有成功進攻的可能。同樣,他們只能通過信使傳令的方式做出一致性的軍事決策:打還是不打?幾點打?這個例子跟之前的兩軍問題在某種程度上是類似的,即多個軍隊通過信使傳令的方式做出一個決定。但拜占庭將軍問題的不同之處在于:
a.該問題中假設信道是可靠的,信使能夠正確的傳遞將軍們的指令,不存在截獲和干擾的可能。
b.將軍并不都一定是誠實正直的,他們當中不是所有人都有意愿想要進攻,其中可能存在反叛的將軍故意破壞整個軍事行動的一致性,即反叛將軍可能傳遞錯誤的指令,干擾其他誠實將軍。
c.所有的將軍都知道有反叛將軍的存在。
在以上條件下,這些將軍們有可能對一次軍事行動達成共識嗎?即是否存在一個通信協議,使得當N個將軍中存在f個叛徒時,仍能采取一致的策略(此一致性可意味著都打,或都不打)。且看以下推演:
2.1當將軍總數為3,叛徒數量為1時:(3個將軍2個叛徒情況下肯定無法達成一致了)
a.假設A將軍誠實且為司令,他首先向BC兩位將軍發送我下午1點進攻的指令。
b.假設B將軍叛徒,他在收到A的命令之后,向C將軍發送“A告訴我下午2點進攻”的消息
c.假設C將軍誠實,他在收到A的命令之后,向B將軍發送“A告訴我下午1點進攻”的消息
那么在上述通信之后,情況如下:
A1點進攻,B不進攻,C收到1點進攻和2點進攻2條信息,并且無法判斷以哪一條為準。最好的情況是,A和C同時1點進攻,最差的情況是A1點去,B不去,C2點去,時間段內單兵作戰行動失敗。
由此可見,3個節點一個叛徒的情況下,拜占庭將軍問題中還是不存在一個必定達成一致性的共識協議。
2.2接下來考慮4個節點1個叛徒的情況:
a.假設A為司令且誠實,他向BCD三位將軍發送1點進攻的指令
b.假設B將軍叛徒,他向CD將軍分別發送“A讓我2點進攻”的消息;
c.假設C將軍誠實,他向BD將軍分別發送“A讓我1點進攻”的消息
d.假設D將軍誠實,他向BC將軍分別發送“A讓我1點進攻”的消息
那么在上述通信之后,情況如下:
A因為誠實選擇1點進攻,B收到的三個消息分別是(1點,1點,1點),C收到的三個消息分別是(1點,2點,1點),D收到的三個消息分別是(1點,2點,1點)B為叛徒不選擇進攻,但對于C和D來說,他們收到的三個消息里有2個都是1點進攻,因此他們只需要按照多數命令行事即可,最后結果是ACD發起進攻,保證了此次軍事行動的一致性。
2.3同樣還是4個節點1個叛徒,但此時叛徒為司令A:
a.假設A叛徒,分別告訴BCD“下午1點進攻“,”下午2點進攻“,”下午三點進攻“
b.假設B誠實,告訴CD“A讓我1點進攻”
c.假設C誠實,告訴BD“A讓我2點進攻”
d.假設D誠實,告訴BC“A讓我3點進攻”
那么在上述通信之后,情況如下:
A是叛徒不進攻,B收到三個消息(1點,2點,3點),C和D也同樣收到(1點,2點,3點),BCD很容易判斷出來是將軍A故意擾亂行動,因此BCD三者自然選擇不進攻,本次軍事行動仍達成了一致
2.4 4個節點,2個叛徒的情況:
這種情況下的推演不再贅述,A為誠實司令,BC為叛徒,D為誠實將軍時,D最后收到的3個信息必將各異(有興趣可以自己推演下),D無法判斷幾點攻打,那么最好的情況就是AD一起攻打,但寡不敵眾;最差的情況就是A和D各自在不同的時間打,軍事行動無法達成一致。這種情況下軍事行動無法100%保證一致。
2.5拜占庭將軍問題有解的條件
拜占庭將軍問題的實質就是在信道可靠的情況下,容忍惡意節點存在并使誠實節點達成一致。
通過上面的一些推到可以看出,要使拜占庭將軍問題有解,節點總數量至少為4個,且通過節點之間互相通信告知收到的消息來進行一致性判斷,當節點數上升到一定量級時,可想而知通信的效率將顯著降低,通信復雜度和成本將顯著提高。
此外,目前大量的研究也表明,在N(總數)≥3F(惡意節點數)+1時,拜占庭將軍問題有解,各節點之間能夠達成共識
3.總結
“前人之述備矣” —-《岳陽樓記》
對于區塊鏈而言,共識是基石,基石之上才有了價值的可信轉移。
而關于共識的兩軍問題和拜占庭將軍問題之前已經有大量成熟的實證研究,早在區塊鏈之前就已經存在,且已經運用到解決分布式系統中各節點對指令執行的一致性和共識當中。區塊鏈在本質上也是一個分布式系統,尤其為了應對拜占庭將軍問題,區塊鏈1.0時期的比特幣就提出了工作量證明算法來加以解決,后續又有POS,DPOS等變種。此外,針對分布式系統的一致性和共識問題的算法還有Paxos,Raft,PBFT等,之后有時間我將逐一進行分析和研究。