背景介紹
曾經一篇標題為"震驚!V神和BM竟如此互懟!"的文章在網上熱議起來,這是一篇BM和V神在issue上對于DPOS的機制的討論,接下來我們具體討論下他們的討論內容:
先看一下英文版的:


翻譯成中文版的:


單輪共識引起不可逆塊沖突
我們先來看一下最初EOS的DPOS2.0+BFT的共識機制:當一個特定的區(qū)塊被(2/3+1)生產者確認的時候,該塊成為不可逆塊。
假設現在有A,B和C三個塊: A 生產了一個區(qū)塊 N, B 生產區(qū)塊 N + 1 并且確認了區(qū)塊 N, C 生產區(qū)塊 N + 2 并且確認了區(qū)塊 N, N + 1 , 此時 N 已經有 3 個確認,達到了 2/3 + 1 個確認,則區(qū)塊 N 成為不可逆。
提出問題:上面所述的共識只經過了一次共識,那么會出現什么問題呢?
V神就在issue上提出一個例子,如下圖:

?
可以看出第一條鏈 A 生產的 2 經過 B、C 已經達到了 3 個確認數已經成為不可逆了, 但此時 D 因網絡不好, 沒接收到這些塊, 從而產生分叉開始生產區(qū)塊 2 , 之后 A 生產區(qū)塊 3 , 因為塊高度大于之前的 2 ,所以是可生產的,B同理, 經過 A, B 之后 D 生產的 2 同樣達到了三個確認數, 這樣就會有 2 個塊高度為 2 的區(qū)塊成為了不可逆,造成沖突。
分析解決不可逆塊沖突
為什么會造成這個原因呢?因為區(qū)塊 2 沒有經過所有節(jié)點就成為不可逆了, 導致后面的產生的區(qū)塊 2 可在下一輪被確認成為不可逆塊。如果說 A ,B ,C ,D 都確認了區(qū)塊 2, 那么下一輪誰都沒可能生產塊高度為 2 的區(qū)塊。也就不會同時出現 2 個不可逆塊了。 但全部節(jié)點確認才成為不可逆這就破壞了引入BFT的想法, 而且你沒辦法保證所有節(jié)點都會對他進行確認,畢竟網絡延遲一直存在。
那怎么解決不可逆塊沖突,但是又不會破壞BFT的想法呢?V神給出的解決方法:經過2輪(2/3+1)的確認,繼續(xù)使用BFT的思想,破壞掉分叉的區(qū)塊2成為最終的不可逆區(qū)塊,因為最終的不可逆塊已經是3,小于3的區(qū)塊都認為是不可逆塊了。
這里引進proposed lib的概念, 即可能成為不可逆的區(qū)塊,簡稱plib:一個區(qū)塊經過2/3 + 1共識后,他不會立馬成為lib, 會先成為plib, 然后再plib經過 (2/3+1) 共識后才會成為lib。兩輪共識的正常流程如下圖:

再來看一輪共識,不可逆塊產生沖突時,兩輪共識的結果:

上圖中,當D因網絡不好,沒接收到之前的塊,從而產生分叉開始生產區(qū)塊2,當一輪共識時,區(qū)塊2成為不可逆區(qū)塊時會產生沖突,經過兩輪共識后,分叉的鏈,產生的備選不可逆塊為2時,正常的鏈產生的最終的不可逆塊已經是3,此時,小于3的區(qū)塊都是最終的不可逆區(qū)塊了。
其實這種方式你可以看成對有多條分叉鏈的處理,節(jié)點對這些鏈進行(2/3+1)共識來選出哪條plib分叉鏈作為主鏈(不可逆序號最大的鏈),丟棄掉其他plib分叉鏈。
總結
dpos3.0+BFT由最初的一次共識增加到了兩次,避免掉出現conflict(沖突)lib, 但是這也讓head_block_num和lib的高度拉到((2/3+1) * 21 - 1)? * 12 * 2 = 336 個塊(不考慮漏塊的情況)。根據一個區(qū)塊生產的時間為0.5秒計算,產生最終的不可逆塊的用時為:336 * 0.5 = 168
鏈接