你一覺醒來,發現自己沒躺牀上,而是站到皇帝身邊,變成貼身侍衛。皇帝合上奏摺,扭頭問你:甘肅有沒有旱災?

你剛來,不熟悉業務,但欺君是罪,只好抱着問題溜出門,幸虧遇到三位大臣圍在門口點菸,於是你湊前一步說:皇上讓我問問你們,甘肅有旱災?

兩個大臣連忙點頭,但另一個卻吐出兩個菸圈,笑而不語。

你的挑戰纔剛剛開始——到底有沒有旱災?

按照 PBFT 共識算法,你應該馬上挽起兩位點頭大臣的手臂,找皇上彙報:甘肅確有旱災一事。因爲已達成 2/3 多數的共識,但且慢一步,先搞清楚一件事:

一、什麼是 PBFT?

PBFT 指實用拜占庭容錯算法,和 POW (戳藍字複習概念) 一樣,PBFT 也是一種共識算法,解決的是拜占庭將軍問題:幾名將軍帶領各自部隊圍住敵城,合攻則勝,分攻則敗,於是將軍們約定攻城時間,但必須通過信使聯絡,可如果出現叛徒該怎麼辦?

將軍喻指網絡節點,解決拜占庭將軍問題就要祭出一個概念:拜占庭容錯。

網絡節點總有錯誤,它們可能是叛徒(惡意節點),也可能是傻子(故障節點),各節點並不能確保收到的信息沒被做過手腳。“拜占庭容錯”指在分佈式系統裏容下這些“錯”的同時,又能達成正確的共識。

我們已經熟悉經典的拜占庭容錯解決方案:POW 算法——使用工作量證明找隨機數。

如果你讀過專欄第一季的文章,就能體驗到那場面的轟轟烈烈:腱鞘炎都快翻出來了,但隨機數還是很難找到。可一旦找到隨機數,硬邦邦的事實就戳在地上,誰都無法撼動。

很安全,但是沒效率。

PBFT 只是嫌棄傳統方案不實用而已,所以增加一個假設,千萬別小看這個假設,它把原本鋪漫到天邊的工作量變成幾乎不需要工作量,這個假設就是:
不良節點不超過節點總數的 1/3

最終,從效率角度望過去,拜占庭將軍問題的傳統解法 POW 在 PBFT 這種火箭推進器面前頓時灰頭土臉,像臺燒劈柴的鍋爐。

那 PBFT 具體是如何運作的?

二、PBFT 的運作過程

PBFT 共識算法的全過程分五步:第一步是“請求”,相當於客戶端發出讀寫需求,第五步是“答覆”,相當於系統給客戶端的最終答覆。

真正達成共識的是中間三步:

第二步:你問大臣(預準備

第三步:大臣回答(準備

第四步:官僚系統間再次確認(確認

PBFT 把你和所有大臣(全網節點)稱爲“副本”,而你是最重要的副本,即“主節點”,負責從大臣們處蒐集信息,統籌分發確認,最終牽頭答覆。

主節點向全網廣播,這個過程就是預準備。預準備的關鍵是分發,主節點爲每個請求編上號,然後羣發向所有副本。

圖 1 PBFT 算法的前兩步:請求和預準備

預準備消息(圖 1 右側三個箭頭)含有請求的 數字簽名(戳此複習),這使得其他副本很容易驗證真僞。

通過驗證後進入準備階段:此時,副本向全網廣播它自己的答覆。爲防惡意攻擊,副本把預準備消息和準備消息都記在自己的小本子上。如果看預準備消息不順眼,就什麼都不做。

圖 2 PBFT 算法的前三步:請求、預準備和準備

準備階段最重要的事:確保所有正常節點達成一致

但總有不一致的節點,比如那位只吐菸圈不吐字的大臣(副本 3),PBFT 將這種沒有響應的節點視作失效。處理失效節點是下一步“確認階段”要做的事。

進入確認階段,副本首先驗證消息的數字簽名,廣播確認後,主節點負責統計共識,說白了,你只做一件事:統計出達到系統節點總數 2/3 的共識,這個共識就是最終答覆。

你發現:兩票點贊,一票失效,於是主節點在圖 3 右側雙虛線處敲定共識:甘肅有旱災。

圖 3 PBFT 的完整過程

最後,進入答覆環節,主節點和其他正常副本一起答覆客戶端,整個過程都在全網監督下一氣呵成,“一氣呵成”的意思是一秒鐘完成。

但你可能會提個問題:如果主節點不按規矩辦事系統會怎麼辦?即,圖 3 左下角的“×”畫在主節點上,那系統又該如何應對?

我們稱這種情況爲“主節點失效”,一旦遇到主節點失效時,系統的應對方案很簡單:變更視圖

什麼是視圖?視圖即節點排位,變更視圖就是其他副本確認主節點出問題後,立即認副本 1 爲主節點,原主節點到後面去排隊,變成副本 3。

圖 4 變更視圖示例

當主節點無法執行請求時,副本必須變更視圖,這樣才能保持系統活性,關於變更視圖條件有三點說明:

第一,至少確保 2/3 多數的正常節點在同一視圖中,換句話說,如果共識未超越 2/3 多數,主節點就跑去答覆客戶端,副本就會認定主節點失效。

第二,請求編號必須在系統規定的範圍內。還記得在預準備環節裏,主節點要給請求分配編號才能廣播麼?設計這一編號,本來是爲便於相互確認,否則請求一多就會對不上賬,但這也給主節點擾亂系統的留下一個後門:故意分配超大編號,塞爆內存。

應對方案也很樸素,設一個編號上限就 ok,這個上限稱爲“水線”。一旦副本發現請求編號超出水線範圍,就會認定主節點失效。

第三,必須定義出超時的時長,不能讓副本無底線地等待;

爲滿足這點要求,每當副本收到一個請求,就開始計時,直到副本做出最終答覆計時才停止。如果超過系統設定的響應時間,而沒有看到主節點答覆客戶端,副本就會認定主節點失效。

於是,系統始終能夠應對主節點失效:好好幹活你就是中心,一旦作假或怠工,找人換你只是下一秒的事,這就是 PBFT 算法的核心邏輯

作者把 PBFT 說成了花,那它有沒有軟肋呢?

你一定看出來了,如果湧進足夠多的不良節點(超過總節點的 1/3),則網絡勢必奔潰,因爲根本假設已不成立,所以基於 PBFT 構建的網絡不能像 比特幣網絡 一樣完全開放。

於是,我們必須引入一個新概念:

三、許可鏈

指經許可才能接入的鏈。

小規模的許可鏈就像私家莊園,稱爲私有鏈;較大規模的許可鏈就像經濟開發區內的企業集羣,我們稱之爲聯盟鏈。不管是私有鏈還是聯盟鏈,入網都必須經過有權人覈准。

與許可鏈對應的概念就是公有鏈(公鏈),公有鏈的代表是比特幣,任何節點都能隨時出入、隨時讀取,賬本全公開,沒有私密性。

而許可鏈則在地上圍了一圈籬笆,你想進來嗎?先拿到批准再說,所以私密性好。

當然,和公有鏈相比,許可鏈的安全性就短了一截。比如就在 4 天前,基於 PBFT 開發的應用 Ripple 就被曝永久丟失 32570 個區塊,這意味着沒有人能夠審覈 Ripple 的完整區塊鏈。

雖然當事方稱未對普通用戶造成影響,但和比特幣平穩運行 9 年多相比,安全性瞬間矮下一頭。甚至有人稱 Ripple 的 PBFT 共識機制爲“沒有必要又毫無意義的煙霧鏡像”。

沒有錯,PBFT 算法並不是去中心化的共識,而是中心化的控制,這就是爲什麼很多人並沒有把 Ripple 的代幣 XRP 劃爲去中心化貨幣的原因。

但 PBFT 的效率終究秒殺 POW,所以幾乎所有的大型金融項目都傾向使用 PBFT 構建聯盟鏈,那這麼做對我們有什麼好處呢?

舉個小例子:傳統跨境支付需要 3-5 天,而基於 PBFT 的 Ripple 搞定同樣的事只需 3-5 秒,同時費用下降 50% 以上。

你看,不管是去中心化還是中心化,足夠先進的科技,都和魔法無異。

結語

1779 年,和珅上表乾隆,西征軍在甘肅遇澇,行軍延期。皇帝合上奏摺,心中蹊蹺不已,甘肅已報旱災多年,不僅減稅,而且開捐(賣官),所得全部賑濟災民。

1781 年,甘肅布政司王亶望被處斬,陪他一起被誅的還有 56 名官員,乾隆親手終結清史上最轟動的欺上瞞下運動——甘肅冒賑案。

原來,鏈並不會因爲私有而安全,如果缺乏足夠的信息迴路,PBFT 算法就會失效,古代官場就是一個例子。

雖然皇帝端坐權力系統中央,但他並不居於信息系統中心,皇帝只是一個與信息系統若即若離的客戶端,在本文的例子中,你 纔是信息系統的君王

官僚體系本質上是權力系統,但它同時也是信息系統。皇帝要了解民情,得通過官僚,民情想上傳天聽,也得過官僚,而官僚內部的貪腐網絡阻斷着上下政情。

而我們現代社會就不同,因爲有更多的信息流,這讓信息系統從權力系統中獨立出來,最終使得傳統權貴的招數在現代社會根本玩不下去。

有人說根治腐敗得靠講道德,有人說嚴刑峻法更有效,還有人說只要貼上民主的膏藥就能藥到病除。但歷史證明,這些符合常人直覺的土辦法,都煉不出好鋼。

腐敗看起來是權力問題,但說到底是信息問題,只要我們鑿通更多的信息迴路,把更多事實擺在人們面前,把內部信息攤到陽光下一曬,自然能根治腐敗。

所以,想想這兩年清透很多的官場,難道是因爲公務員們多上了兩節黨課、多抄了三遍黨章?還是因爲全國人手一部智能手機?

一段視頻了斷一堆官員前途的故事,不應該被忘記。

本文從 PBFT 共識算法分叉聊到治理腐敗,結論也就一句話,這句話同時也是區塊鏈的意義所在:

陽光是最好的殺毒劑

回到我們專欄的主題,考慮到難度已經爬坡,爲讓你的思路更柔順,正文沒有鋪設一個英文單詞。

如果你想深扒一層,請自行對照文末詞彙表,這可以讓你更潤滑地閱讀 PBFT 算法發明者的說明書:

http://pmg.csail.mit.edu/papers/osdi99.pdf

如果你不習慣看原文,可參考趣鏈科技聯合創始人、浙大博士李啓磊的文章:

http://blog.liqilei.com/bai-zhan-ting-gong-shi-suan-fa-zhi-pbftjie-xi/

其中不僅有對預準備、準備和確認三步的技術描述,而且一些小概念的精緻說明,如消息日誌、穩定檢查點和水線。

詞彙表

實用拜占庭容錯算法(PBFT)

Practical Byzantine Fault Tolerance

拜占庭容錯(BFT)

Byzantine Fault Tolerance

工作量證明(POW)

Proof Of Work

客戶端 client 文中的皇帝

副本 replica 系統中的記賬節點,文中的官僚系統

主節點 primary 文中的你

備份 backup 即除主節點外的其他節點,當主節點失效時按序備份

視圖 view “你-大臣 1-大臣 2-大臣 3”的順位架構就是一種視圖

變更視圖 change view 主節點失效時的系統策略

活性 liveness 主節點沒失效,就說明系統有活性

消息日誌 message log

水線 watermark

穩定檢查點 stable checkpoint

請求 request

預準備 pre-prepare

準備 prepare

確認 commit

答覆 reply

爲便於你理解,和上篇講述 DPOS 的文章 一樣,作者把共識確認條件從 2/3+1 多數簡化爲 2/3,因爲當節點數足夠多時,2/3+1 多數≈2/3 多數。

另外,實際場景中不可能只有 4 個節點,更可能是 40 個、400 個或者更多,你可以把本文的例子推廣到 9 個大臣,然後在 A4 紙上推演一遍五步過程和視圖變更。

因爲這樣你就能輕而易舉地發現:正文變更視圖的案例好不嚴謹——4 個副本一旦變更視圖,只剩 2 個正常副本,另外 2 個是失效節點:吐菸圈的大臣和你。所以,這局視圖根本玩不下去。

如果用 9 個節點推演就不存在這樣的問題,相信我,在 A4 紙上推演一遍,你一定能徹底理解 PBFT。

祝你每週都有進步。