區塊鏈快速入門(四)——BFT(拜占庭容錯)共識算法

區塊鏈快速入門(四)——BFT(拜占庭容錯)共識算法

1、BFT簡介

一、拜占庭將軍問題簡介

拜占庭將軍問題(Byzantine Generals Problem)是Leslie Lamport(2013年的圖靈獎得主)用來爲描述分佈式系統一致性問題(Distributed Consensus)在論文中抽象出來一個著名的例子。
拜占庭將軍問題簡易的非正式描述以下:
拜占庭帝國想要進攻一個強大的敵人,爲此派出了10支軍隊去包圍這個敵人。這個敵人雖不比拜占庭帝國,但也足以抵禦5支常規拜占庭軍隊的同時襲擊。基於一些緣由,這10支軍隊不能集合在一塊兒單點突破,必須在分開的包圍狀態下同時進攻。他們任一支軍隊單獨進攻都毫無勝算,除非有至少6支軍隊同時襲擊才能攻下敵國。他們分散在敵國的四周,依靠通訊兵相互通訊來協商進攻意向及進攻時間。困擾這些將軍的問題是,他們不肯定他們中是否有叛徒,叛徒可能擅自變動進攻意向或者進攻時間。在這種狀態下,拜占庭將軍們可否找到一種分佈式的協議來讓他們可以遠程協商,從而贏取戰鬥?這就是著名的拜占庭將軍問題。
拜占庭將軍問題中並不去考慮通訊兵是否會被截獲或沒法傳達信息等問題,即消息傳遞的信道絕無問題。Lamport已經證實了在消息可能丟失的不可靠信道上試圖經過消息傳遞的方式達到一致性是不可能的。因此,在研究拜占庭將軍問題的時候,假定信道是沒有問題的,而後去作一致性和容錯性相關研究。算法

二、兩將軍問題

拜占庭問題前,就已經存在兩將軍問題(Two Generals Paradox):兩個將軍要經過信使來達成進攻仍是撤退的約定,但信使可能迷路或被敵軍阻攔(消息丟失或僞造),如何達成一致?
根據FLP不可能原理,兩將軍問題無通用解。數據庫

三、BFT簡介

BFT(Byzantine Fault Tolerance),即拜占庭容錯,是分佈式計算領域的容錯技術,拜占庭容錯來源於拜占庭將軍問題。拜占庭將軍問題是對現實世界的模型化,因爲硬件錯誤、網絡擁塞或中斷以及遭到惡意***等緣由,計算機和網絡可能出現不可預料的行爲。拜占庭容錯技術被設計用來處理現實存在的異常行爲,並知足所要解決的問題的規範要求。
區塊鏈網絡環境符合拜占庭將軍問題模型,有運行正常的服務器(忠誠的拜占庭將軍),有故障的服務器,還有破壞者的服務器(叛變的拜占庭將軍)。共識算法的核心是在正常的節點間造成對網絡狀態的共識。
一般,發生故障的節點被稱爲拜占庭節點,而正常的節點爲非拜占庭節點。
拜占庭容錯系統是一個擁有n臺節點的系統,整個系統對於每個請求,知足如下條件:
  A、全部非拜占庭節點使用相同的輸入信息,產生一樣的結果;
  B、若是輸入的信息正確,那麼全部非拜占庭節點必須接收這個信息,並計算相應的結果。
拜占庭系統廣泛採用的假設條件包括:
  A、拜占庭節點的行爲能夠是任意的,拜占庭節點之間能夠共謀;
  B、節點之間的錯誤是不相關的;
  C、節點之間經過異步網絡鏈接,網絡中的消息可能丟失、亂序並延時到達,但大部分協議假設消息在有限的時間裏能傳達到目的地;
  D、服務器之間傳遞的信息,第三方能夠嗅探到,可是不能篡改、僞造信息的內容和驗證信息的完整性。
原始的拜占庭容錯系統因爲須要展現其理論上的可行性而缺少實用性。另外,還須要額外的時鐘同步機制支持,算法的複雜度也是隨節點增長而指數級增長。安全

2、PBFT算法

一、PBFT算法簡介

PBFT(Practical Byzantine Fault Tolerance),即實用拜占庭容錯算法,由Miguel Castro和Barbara Liskov在1999年發表的論文《Practical Byzantine Fault Tolerance and Proactive Recovery》中提出。PBFT算法能夠工做在異步環境中,而且經過優化解決了原始拜占庭容錯算法效率不高的問題,將算法複雜度由指數級下降到多項式級,使得拜占庭容錯算法在實際系統應用中變得可行,目前已獲得普遍應用。PBFT算法能夠在失效節點不超過總數1/3的狀況下同時保證Safety和Liveness。
PBFT 算法採用密碼學相關技術(RSA 簽名算法、消息驗證編碼和摘要)確保消息傳遞過程沒法被篡改和破壞。服務器

二、PBFT算法原理

PBFT是一種狀態機副本複製算法,即服務做爲狀態機進行建模,狀態機在分佈式系統的不一樣節點進行副本複製。每一個狀態機的副本都保存了服務的狀態,同時也實現了服務的操做。將全部的副本組成的集合使用大寫字母R表示,使用0到|R|-1的整數表示每個副本。爲了描述方便,一般假設故障節點數爲f個,整個服務節點數爲|R|=3f+1個,f是有可能失效的副本的最大個數。儘管能夠存在多於3f+1個副本,但額外的副本除了下降性能外不能提升可靠性。
全部的副本在一個被稱爲視圖(View)的輪換過程當中運做。在某個視圖中,一個副本做爲主節點(primary),其它的副本節點做爲備份節點(backups)。視圖是連續編號的整數。主節點由公式p = v mod |R|計算獲得,v是視圖編號,p是副本編號,|R|是副本集合的個數。當主節點失效的時候就須要啓動視圖輪換過程。
PBFT算法實現流程以下:
區塊鏈快速入門(四)——BFT(拜占庭容錯)共識算法
(1)REQUEST
客戶端C向主節點p發送網絡

<REQUEST, o, t, c>

請求。
o:請求的具體操做
t:請求時客戶端追加的時間戳
c:客戶端標識。
REQUEST: 包含消息內容m,以及消息摘要d(m)。
客戶端對請求進行簽名。
(2)PRE-PREPARE
主節點收到客戶端的請求,須要對客戶端請求消息簽名是否正確進行校驗。
非法請求則丟棄。正確請求,分配一個編號n,編號n主要用於對客戶端的請求進行排序。而後廣播一條異步

<<PRE-PREPARE, v, n, d>,  m>

消息給其它副本節點。
v:視圖編號
d客戶端消息摘要
m:消息內容分佈式

<PRE-PREPARE, v, n, d>

進行主節點簽名。
n是要在某一個範圍區間內的[h, H]。
(3)PREPARE
副本節點i收到主節點的PRE-PREPARE消息,須要進行如下校驗:
A、主節點PRE-PREPARE消息簽名是否正確。
B、當前副本節點是否已經收到了一條在同一v下而且編號也是n,可是簽名不一樣的PRE-PREPARE信息。
C、d與m的摘要是否一致。
D、n是否在區間[h, H]內。
非法請求則丟棄。正確請求,副本節點i向其它節點包括主節點發送一條ide

<PREPARE, v, n, d, i>

消息, v, n, d, m與上述PRE-PREPARE消息內容相同,i是當前副本節點編號。性能

<PREPARE, v, n, d, i>

進行副本節點i的簽名。記錄PRE-PREPARE和PREPARE消息到log中,用於視圖輪換過程當中恢復未完成的請求操做。
PREPARE階段若是發生視圖輪換會致使丟棄PREPARE階段的請求。
(4)COMMIT
主節點和副本節點收到PREPARE消息,須要進行如下校驗:
A、副本節點PREPARE消息簽名是否正確。
B、當前副本節點是否已經收到了同一視圖v下的n。
C、 n是否在區間[h, H]內。
D、d是否和當前已收到PRE-PPREPARE中的d相同
非法請求則丟棄。若是副本節點i收到了2f+1個驗證經過的PREPARE消息,代表網絡中的大多數節點已經收到贊成信息,則向其它節點包括主節點發送一條區塊鏈

<COMMIT, v, n, d, i>

消息,v, n, d,  i與上述PREPARE消息內容相同。

<COMMIT, v, n, d, i>

進行副本節點i的簽名。記錄COMMIT消息到日誌中,用於視圖輪換過程當中恢復未完成的請求操做。記錄其它副本節點發送的PREPARE消息到log中。
COMMIT階段用來確保網絡中大多數節點都已經收到足夠多的信息來達成共識,若是COMMIT階段發生視圖輪換,會保存原來COMMIT階段的請求,不會達不成共識,也不會丟失請求編號。

(5)REPLY
主節點和副本節點收到COMMIT消息,須要進行如下校驗:
A、副本節點COMMIT消息簽名是否正確。
B、當前副本節點是否已經收到了同一視圖v下的n。
C、d與m的摘要是否一致。
D、n是否在區間[h, H]內。
非法請求則丟棄。若是副本節點i收到了2f+1個驗證經過的COMMIT消息,說明當前網絡中的大部分節點已經達成共識,運行客戶端的請求操做o,並返回

<REPLY, v, t, c, i, r>

給客戶端,r:是請求操做結果,客戶端若是收到f+1個相同的REPLY消息,說明客戶端發起的請求已經達成全網共識,不然客戶端須要判斷是否從新發送請求給主節點。記錄其它副本節點發送的COMMIT消息到log中。

三、PBFT算法的垃圾回收

爲了確保在視圖輪換的過程當中,可以恢復先前的請求,每個副本節點都記錄一些消息到本地的log中,當執行請求後副本節點須要把以前該請求的記錄消息清除掉。最簡單的作法是在Reply消息後,再執行一次當前狀態的共識同步,但成本比較高,所以能夠在執行完多條請求K(例如:100條)後執行一次狀態同步。狀態同步消息就是CheckPoint消息。
副本節點i發送

<CheckPoint, n, d, i>

給其它節點,n是當前節點所保留的最後一個視圖請求編號,d是對當前狀態的一個摘要,該CheckPoint消息記錄到log中。若是副本節點i收到了2f+1個驗證過的CheckPoint消息,則清除先前日誌中的消息,並以n做爲當前一個stable checkpoint。
實際中,當副本節點i向其它節點發出CheckPoint消息後,其它節點尚未完成K條請求,因此不會當即對i的請求做出響應,還會按照本身的節奏,向前行進,但此時發出的CheckPoint並未造成stable,爲了防止i的處理請求過快,設置一個上文提到的高低水位區間[h, H]來解決問題。低水位h等於上一個stable checkpoint的編號,高水位H = h + L,其中L是指定的數值,等於checkpoint週期處理請求數K的整數倍,能夠設置爲L = 2K。當副本節點i處理請求超太高水位H時,此時就會中止腳步,等待stable checkpoint發生變化,再繼續前進。

四、PBFT算法的視圖輪換

若是主節點做惡,可能會給不一樣的請求編上相同的序號,或者不去分配序號,或者讓相鄰的序號不連續。備份節點應當有職責來主動檢查這些序號的合法性。若是主節點掉線或者做惡不廣播客戶端的請求,客戶端設置超時機制,超時的話,向全部副本節點廣播請求消息。副本節點檢測出主節點做惡或者下線,發起視圖輪換協議。
副本節點向其它節點廣播

<VIEW-CHANGE, v+1, n, C, P, i>

消息。n是最新的stable checkpoint的編號,C是2f+1驗證過的CheckPoint消息集合,P是當前副本節點未完成的請求的PRE-PREPARE和PREPARE消息集合。
當主節點p = v + 1 mod |R|收到2f個有效的VIEW-CHANGE消息後,向其它節點廣播

<NEW-VIEW, v+1, V, O>

消息。V是有效的VIEW-CHANGE消息集合。O是主節點從新發起的未經完成的PRE-PREPARE消息集合。PRE-PREPARE消息集合的選取規則以下:
A、選取V中最小的stable checkpoint編號min-s,選取V中prepare消息的最大編號max-s。
B、在min-s和max-s之間,若是存在P消息集合,則建立

<<PRE-PREPARE, v+1, n, d>, m>

消息。不然建立一個空的PRE-PREPARE消息,即:

<<PRE-PREPARE, v+1, n, d(null)>, m(null)>

, m(null)爲空消息,d(null)爲空消息摘要。
副本節點收到主節點的NEW-VIEW消息,驗證有效性,有效的話,進入v+1狀態,而且開始O中的PRE-PREPARE消息處理流程。

五、PBFT算法的優缺點

PBFT算法的優勢:
PBFT算法具備高交易通量和吞吐量,高可用性,易於理解。
PBFT算法的缺點:
A、計算效率依賴於參與協議的節點數量,因爲每一個副本節點都須要和其它節點進行P2P的共識同步,所以隨着節點的增多,性能會降低的很快,但在較少節點的狀況下能夠有不錯的性能,而且分叉的概率很低,不適用於節點數量過大的區塊鏈,擴展性差。
B、系統節點是固定的,沒法應對公有鏈的開放環境,只適用於聯盟鏈或私
有鏈環境。
C、PBFT算法要求總節點數n>=3f+1(其中,f表明做惡節點數)。系統的失效節點數量不得超過全網節點的1/3,容錯率相對較低。

六、PBFT算法的應用場景

PBFT算法的節點數量是固定的,節點身份提早肯定,沒法動態添加或刪除,只能適用於節點數目固定的聯盟鏈或私有鏈場景中。
PBFT在不少場景都有應用,在區塊鏈場景中,通常適合於對強一致性有要求的私有鏈和聯盟鏈場景,但若是可以結合DPOS節點表明選舉規則,也能夠應用於公有鏈,而且能夠在一個不可信的網絡裏解決拜占庭容錯問題。在Hyperledger Fabric項目中,共識模塊被設計成可插拔的模塊,支持像PBFT、Raft等共識算法。

3、POW算法

一、POW算法簡介

POW(Proof of Work),即工做量證實,也稱挖礦。工做量證實經過計算來猜想一個數值(nonce),使得拼湊上交易數據後內容的Hash值知足規定的上限。因爲Hash難題在目前計算模型下須要大量的計算,能夠保證在一段時間內,系統中只能出現少數合法提案。若是可以提出合法提案,證實提案者確實已經付出了必定的工做量。
哈希現金是一種工做量證實機制,是Adam Back在1997年發明的,用於抵抗郵件的拒絕服務***及垃圾郵件網關濫用。

二、POW算法原理

工做量證實的主要特徵是客戶端須要作必定難度的工做得出一個結果,驗證方卻很容易經過結果來檢查出客戶端是否是作了相應的工做。工做量證實方案的一個核心特徵是不對稱性:工做對於請求方是適中的,對於驗證方則是易於驗證的。
區塊鏈快速入門(四)——BFT(拜占庭容錯)共識算法
給定一個基本字符串,在基本字符串後面添加一個叫作nonce的整數值,對變動後(添加nonce)的字符串進行SHA256哈希運算,若是獲得的哈希結果(以16進制的形式表示)是以某個字符串(如"0000")開頭的,則驗證經過。爲了達到工做量證實的目標,須要不停的遞增nonce值,對獲得的新字符串進行SHA256哈希運算。
因爲給定的基本字符串在不一樣的場合並不肯定,對於不一樣的基本字符串和nonce的組合,要使用SHA256計算獲得某個字符串開頭Hash值的計算次數並不肯定,但會是一個符合統計學規律的機率事件。
按照規則,預期大概要進行2^16 次嘗試(哈希值的僞隨機特性能夠作機率估算),才能獲得4個前導0的哈希散列。

三、比特幣的POW實現

比特幣區塊由區塊頭和該區塊所包含的交易列表組成。區塊頭大小爲80字節,其構成包括:
   4字節:版本號
   32字節:上一個區塊的哈希值
   32字節:交易列表的Merkle根哈希值
   4字節:當前時間戳
   4字節:當前難度值
   4字節:隨機數Nonce值
   80字節長度的區塊頭,即爲比特幣Pow算法的輸入字符串。
  交易列表附加在區塊頭以後,其中第一筆交易爲礦工得到獎勵和手續費的特殊交易。
工做量證實過程,即爲不斷調整Nonce值,對區塊頭作雙重SHA256哈希運算,使得結果知足給定數量前導0的哈希值的過程,其中前導0的個數,取決於挖礦難度,前導0的個數越多,挖礦難度越大。
每建立2016個塊後將計算新的難度,此後的2016個塊使用新的難度。計算步驟以下:
  A、找到前2016個塊的第一個塊,計算生成這2016個塊花費的時間。
即最後一個塊的時間與第一個塊的時間差。時間差不小於3.5天,不大於56天。
  B、計算前2016個塊的難度總和,即單個塊的難度x總時間。
  C、計算新的難度,即2016個塊的難度總和/14天的秒數,獲得每秒的難度值。
  D、要求新的難度,難度不低於參數定義的最小難度。

四、POW算法的優缺點

POW算法的優勢:
A、徹底去中心化
B、節點自由進出
C、安全性高
POW算法的缺點:
A、記帳權向資本集中
B、挖礦形成大量的資源浪費。
C、網絡性能過低,須要等待多個確認,容易產生分叉,區塊的確認共識達成的週期較長,不適合商業應用。

五、POW算法的應用場景

POW共識機制用在了大部分挖礦的區塊鏈項目,好比BTC、ETH、LTC。

4、POS算法

一、POS算法簡介

POS(Proof of Stake),即權益證實,是POW的一種升級共識機制,根據每一個節點所佔代幣的比例和時間,等比例的下降挖礦難度,從而加快找隨機數的速度。
鑑於POW的缺陷,2012年Sunny King提出了POS,並基於POW和POS的混合機制發佈了點點幣PPCoin。

二、POS算法原理

POS原理的核心概念爲幣齡,即持有貨幣的時間。例若有10個幣、持有90天,即擁有900幣天的幣齡。
  使用幣即意味着幣齡的銷燬。
  在POS中有一種特殊的交易稱爲利息幣,即持有人能夠消耗幣齡得到利息,同時得到爲網絡產生區塊以及POS造幣的優先權。
POW經過算力證實本身有資格寫區塊鏈,而PoS經過擁有的幣齡來證實本身有資格寫區塊鏈。

三、POS算法的優缺點

POS算法的優勢:
A、不消耗大量算力挖礦,節省能耗。
B、在必定程度上縮短了共識達成的時間
C、防做弊。
POS算法的缺點:
A、本質仍然須要挖礦,未解決商業應用的痛點
B、極端的狀況下會帶來中心化的結果

四、點點幣的POS實現

點點幣的POS證實計算公式爲:
  proofhash < 幣齡x目標值
  展開以下:
  hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget x bnCoinDayWeight
  其中proofhash,對應一組數據的哈希值,即hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime)。
  幣齡即bnCoinDayWeight,即幣天,即持有的幣數乘以持有幣的天數,此處天數最大值爲90天。
  目標值,即bnTarget,用於衡量POS挖礦難度。目標值與難度成反比,目標值越大、難度越小;反之亦然。
  所以,持有的幣天越大,挖到區塊的機會越大。

5、DPOS算法

一、DPOS算法簡介

DPOS(Delegated Proof of Stake),即股份受權證實算法,是在POW及POS基礎上誕生的一種新型共識算法,2014年4月由Bitshares的首席開發者Dan Larimer (現爲EOS CTO)提出並應用。DPOS既能解決POW在挖礦過程當中產生的DPOS大量能源過耗的問題,也能避免POS權益分配下可能產生的信任天平偏頗的問題。
DPOS是由被社區選舉的可信帳戶(超級節點,好比得票數前101位能夠成爲)來建立區塊。好比選出101個超級節點,即101個礦池,超級節點之間的權利是徹底相等的。普通的持幣者能夠隨時經過投票更換超級節點(礦池),DPOS的去中心化不是每一個持幣者就有直接的股份權益,而是須要間接的投票權力,來保證被推選出來的超級節點不做惡,同時也能夠本身拉選票成爲超級節點或者備用超級節點。

二、DPOS算法原理

DPOS算法的基本原則:
A、持股人依據所持股份行使表決權,而不是依賴挖礦競爭記帳權。
B、最大化持股人的盈利。
C、最小化維護網絡安全的費用。
D、 最大化網絡的效能。
E、 最小化運行網絡的成本 (帶寬、CPU等),在不浪費大量電力的狀況下實現網絡的安全穩定。
在DPOS共識算法中,區塊鏈的正常運轉依賴於超級節點,超級節點的職責主要有:
A、提供一臺服務器節點,保證節點的正常運行;
B、節點服務器收集網絡裏的交易;
C、節點驗證交易,把交易打包到區塊;
D、節點廣播區塊,其它節點驗證後把區塊添加到本身的數據庫;
E、帶領並促進區塊鏈項目的發展;
DPOS算法運行機制以下:
A、全部持幣者先選出超級節點負責簽署區塊
B、DPOS的規則是最長鏈勝出,每一個超級節點必須按照生產排程,輪流產生區塊。假設排程排定A、B、C分別輪流生產區塊,在必定時間內產生的區塊以下:
區塊鏈快速入門(四)——BFT(拜占庭容錯)共識算法
C、若是惡意節點生產了分叉區塊,假設A、C都是誠實的節點,只有B節點是惡意的,因爲B產生區塊的速度(每一個週期生產一個區塊)慢於A、C協力產生區塊的速度(每一個週期生產一個區塊),根據最長鏈勝出的規則,誠實的節點仍是會勝出。
區塊鏈快速入門(四)——BFT(拜占庭容錯)共識算法
D、同一個節點要產生重複兩個區塊的速度也要慢於誠實節點合做產生區塊的速度,因此最長鏈勝出規則會保證誠實節點的鏈會勝出。
E、若是A,B,C三個超級節點的網絡出現碎片化,各自爲政的狀況。在短時間內的確可能三鏈並行,但一旦網絡鏈接恢復,短鏈天然會向最長鏈迴歸。超級節點數量爲奇數,因此兩大派系平分秋色僵持不下的狀況不會維持過久,最終勢必會有其中一方的鏈更長。
區塊鏈快速入門(四)——BFT(拜占庭容錯)共識算法

三、DPOS對惡意節點的懲罰

註冊成爲候選超級節點須要支付一筆保證金(約10 XTS),一般擔任超級節點約兩週後纔可達到損益平衡,所以促進了受託人的穩定性,確保至少會挖滿兩週的礦。
DPOS對惡意節點的懲罰爲:不按排程產生區塊的超級節點將在下一輪被投票剔除,被沒收繳納的保證金。
惡意節點在短時間內是可以做惡的,惡意的區塊只是短期保留而已,很快超級節點之間會迴歸誠實節點達成的共識,製造出最長鏈,向沒有做惡區塊的最長鏈迴歸。

四、DPOS算法的優缺點

DPOS算法的優勢:
A、能耗優點,網絡運行成本低。
B、理論上更加去中心化。
C、較快的確認速度。出塊速度秒級,交易確認分鐘級。
DPOS算法的缺點:
A、壞節點不能被及時處理,只有通過選舉才能清除壞節點。
B、小散投票積極性不高。
C、依賴代幣

五、DPOS算法的應用場景

比特股(Bitshare)是一類採用DPOS機制的密碼貨幣,經過引入一個技術民主層來減小中心化的負面影響。DPOS系統任然存在中心化,但中心化是受到控制的,超級節點由普通持幣者選舉產生。DPOS經過保留持幣者的控制權,從而使系統去中心化。

相關文章
相關標籤/搜索