Istanbul BFT共識算法詳細文檔
Istanbul BFT作為BFT類算法的一種已經有過在以太坊上的實踐。雖然Istanbul目前還存在一些潛在的問題,但其算法思想和實現還是值得學習和借鑒的。
源代碼:https://github.com/jpmorganchase/quorum/tree/master/consensus/istanbul
術語
- Validator: 區塊驗證者。
- Proposer: 出塊者。
- Round: 共識的輪數。一輪從出塊者提出一個區塊proposal開始,結束於區塊提交或者輪數改變(輪數改變可能由於出錯或者區塊更新)。
- Proposal: 提出的一個在處理中的新的區塊。
- Sequence: proposal的高度。塊高和sequence相對應。
- Blocklog: 將來的信息記錄在backlog里面。
core.backlogs - Round state:
Round和Sequence綁定在一起組成view, - Consensus proof: 提交的區塊簽名。每個
validator對區塊驗證后會對其進行簽名。 - Snapshot: 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信息,此時把自身狀態標記為PREPARED,並且廣播COMMIT信息。然后等待2F + 1個COMMIT信息COMMITTED: 一個validator已經收到2F + 1個COMMIT信息,此時把自身狀態標記為COMMITTED,並且開始把提出的block插入鏈中。FINAL COMMITTED: 一個validator已經成功把區塊成功插入了鏈中,此時把自身狀態標記為FINAL COMMITTED,並且等待下一輪。ROUND CHANGE: 一個validator等待關於同一個round下的2F + 1個ROUND CHANGE信息。
狀態轉換
- NEW ROUND -> PRE-PREPARED:
- Proposer在txpool中收集交易。
- Proposer提出一個區塊proposal並且廣播給validator。然后進入
PRE-PREPARED狀態。 - 每一個validator進入到
PRE-PREPARED狀態,一旦收到PRE-PREPARED信息並且伴隨着以下情況:- 區塊proposal是來自於有效的proposer。
- 區塊頭有效。
- 區塊proposal的sequence和round和validator的狀態匹配。
- Validator廣播
PREPARE信息給其他validators。
- PRE-PREPARED -> PREPARED:
- Validator收到
2F + 1個有效的PREPARE信息,因此而進入PREPARED狀態。有效信息需要滿足以下條件:- sequence和round匹配。
- 交易hash匹配。
- 信息是來自已知的validators。
- 一旦進入
PREPARED狀態,Validator廣播COMMIT信息。
- Validator收到
- PREPARED -> COMMITTED:
- Validator收到
2F + 1個·有效的COMMIT信息,以此進入COMMITTED狀態。有效的信息需要滿足以下條件:- sequence和round匹配。
- block hash匹配
- 信息是來自已知的validators。
- Validator收到
- COMMITTED -> FINAL COMMITTED:
- Validator把
2F + 1個commitment簽名放進區塊頭的extraData並且嘗試插入區塊進區塊鏈。 - 當插入區塊成功,Validator進入
FINAL COMMITTED狀態。
- Validator把
- FINAL COMMITTED -> NEW ROUND:
Validators選一個新的proposer開始新的一輪。
潛在問題
- Fail-Stop failures
- 這篇文章詳細分析了IBFT
- 沒有激勵機制
