Istanbul BFT做爲BFT類算法的一種已經有過在以太坊上的實踐。雖然Istanbul目前還存在一些潛在的問題,但其算法思想和實現仍是值得學習和借鑑的。git
源代碼:https://github.com/jpmorganchase/quorumgithub
core.backlogs
Round
和Sequence
綁定在一塊兒組成view
,validator
對區塊驗證後會對其進行簽名。Istanbul BFT修改自PBFT算法,包括三個階段:PRE-PREPARE
、PREPARE
以及COMMIT
。在N
個節點的網絡中,這個算法能夠最多容忍F
個出錯節點,其中N=3F+1
。在每一輪開始前,validator
會選擇其中一個做爲proposer
,默認以輪詢的方式(除此以外還有sticky的方式,搜索stickyProposer
方法去看細節)。而後proposer會提出一個區塊的proposal,而且廣播PRE-PREPARE
信息。一旦一個validator收到PRE-PREPARE
信息,會把狀態標記爲PRE-PREPARED
,而後廣播PREPARE
信息。這一步是爲了確保全部的validator在同一個seqnence和round(代碼中爲view)上進行共識驗證。一旦收到2F+ 1
個PREPARE
信息,validator進入PREPARED
狀態而後廣播COMMIT
信息。這一步是爲了通知節點的peer已經接收到了提出的區塊,而且即將插入區塊到鏈中。最後,validator等待2F + 1
個COMMIT
信息,而後進入COMMITTED
狀態而後插入區塊到鏈中。
Istanbul BFT算法中的區塊是肯定的,意味着鏈沒有分叉而且合法的區塊必定是在鏈中。爲了防止一個惡意節點生成不一樣的鏈,在把區塊插入進鏈以前,每個validator必須把2F + 1
個COMMIT
簽名放進區塊頭的extraData
字段。所以,區塊時能夠自我驗證的(由於有簽名)而且輕客戶端也支持。然而動態的extraData
也會形成區塊的hash計算問題。由於一個區塊能夠被不一樣的validator驗證,因此會有不一樣的簽名,因此同一個區塊會有不一樣的hash。解決的方案是,計算區塊hash的時候把COMMIT
簽名排除在外。所以咱們任然能夠在保證block hash一致性的同時進行共識驗證。算法
New Round
: 一個proposer發送新的區塊proposal。validator等待PRE-PREPARE
信息。PRE-PREPARED
: 一個validator已經收到PRE-PREPARE
信息,而且廣播PREPARE
信息。而後等待2F + 1
個PREPARE
或者COMMIT
信息。PREPARED
: 一個validator已經收到2F + 1
個PREPARE
信息而且廣播COMMIT
信息。而後等待2F + 1
個COMMIT
信息COMMITTED
: 一個validator已經收到2F + 1
個COMMIT
信息而且此時可以把提出的block插入鏈中。FINAL COMMITTED
: 一個validator已經成功把區塊插入了鏈中,而且等待下一輪。ROUND CHANGE
: 一個validator等待關於同一個round下的2F + 1
個ROUND CHANGE
信息。PRE-PREPARED
狀態。PRE-PREPARED
狀態,一旦收到PRE-PREPARED
信息而且伴隨着如下狀況:
PREPARE
信息給其餘validators。2F + 1
個有效的PREPARE
信息,所以而進入PREPARED
狀態。有效信息須要知足如下條件:
PREPARED
狀態,Validator廣播COMMIT信息。2F + 1
個·有效的COMMIT
信息,以此進入COMMITTED
狀態。有效的信息須要知足如下條件:
2F + 1
個commitment簽名放進區塊頭的extraData
而且嘗試插入區塊進區塊鏈。FINAL COMMITTED
狀態。