文章目錄
-
- 1. 寫在前面
- 2.兩/三階段共識中的鎖定機制
- 3.共識協定中Leader可信度的不同
- 4.Single-modal類共識中鎖定機制的設計
-
- 4.1 對鎖定機制中規則2活性的了解
- 4.2 為什麼`Tendermint`在進行`leader`切換的時候要等待 Δ \Delta Δ
-
- 4.2.1 `Tendermint`不等待 Δ \Delta Δ導緻的`Hidden Lock`問題
- 4.2.2 為什麼等待 Δ \Delta Δ可以解決`Hidden Lock`問題
- 4.3 為什麼`HotStuff`不需要等待 Δ \Delta Δ
- 5. 一個問題:`replica`接收到舊`view`中的消息如何處理
-
- 5.1 假設一:認為舊`view`中的消息是無效的
- 5.2 假設二:認為舊`view`中的消息有效的
1. 寫在前面
在
HotStuff
的
PODC
版本論文和
Arxiv
版本論文中,多次将不同共識協定的活性(
liveness
)和響應度(
responsiveness
)進行比較。此外,一些部落格和其他相關論文中也有關于
liveness
問題和
responsiveness
問題的叙述。其中涉及到兩點叙述:
中在
Tendermint
切換的時候需要等待一個最大的網絡延遲 Δ \Delta Δ,導緻
leader
無法做到
Tendermint
optimistic responsiveness
- 如果
在
Tendermint
切換的時候不等待 Δ \Delta Δ,将導緻
leader
中無法進行有效共識,進而破壞協定的
Tendermint
。
liveness
但筆者在看這兩點叙述的時候,總感覺論文作者和部落客沒有将問題講透,看得雲裡霧裡的。這些大佬們似乎都覺得這兩點叙述很容易了解,甚至是一些一點就該通的常識。
為了真正弄懂以上兩點叙述,筆者查閱了大量資料,并将自己的一些了解整理在這篇部落格中。這篇部落格需要讀者對共識算法已經有了一定的了解。否則,可能有些讀不太懂,甚至不知道筆者想要讨論的問題是什麼。
2.兩/三階段共識中的鎖定機制
我們先從共識協定中的“鎖定機制”開始說起。
無論是
PBFT
、
Tendermint
還是
HotStuff
,都在共識過程中隐式或顯示地引入了鎖定機制。其中,
PBFT
論文中沒有顯示定義這種鎖定機制,但每個
replica
在本地
prepared
之後,就可以認為是在鎖定了。
PBFT
和
Tendermint
/
HotStuff
中鎖定的作用是不同的:
-
中的鎖定機制隻是為了防止一個誠實PBFT
同時對兩個沖突的replica
投票,而不會檢查新的proposal
是否基于已鎖定的proposal
。這樣的鎖定機制也就不對已鎖定的proposal
做出任何承諾,即:在發生proposal
切換的時候,上一個leader
中鎖定的view
在本輪中可以被輕易推翻。proposal
- 相反,
/Tendermint
中的鎖定機制除了防止一個誠實HotStuff
對兩個沖突replica
投票外,還會進一步檢查新的proposal
是否基于已鎖定的proposal
。這樣的鎖定機制對于已鎖定的proposal
做出了一定的承諾,即:在上一個proposal
中已經被鎖定的view
,除非發生特殊情況(proposal
接收到的replica
基于更高的proposal
),在新的QC
中不會被推翻。view
這兩種鎖定機制的不同源于他們對于
leader
賦予的可信度是不同的。
3.共識協定中Leader可信度的不同
PBFT
中
leader
的可信度是很大的(其作惡空間很小),這是因為
leader
在進行
View
的切換時,其在發出的
New-View
消息中攜帶了充分的證明性資料,其他
replica
有理由相信
leader
在
New-View
消息中是很難作惡的。是以大家都把本地鎖定的資料修改為
leader
發來的
New-View
中攜帶的資料。
這也導緻了
HotStuff
等論文中诟病的
PBFT
進行
View
切換時的高開銷問題,因為
New-View
消息中需要攜帶證明性資料。
相反,
Tendermint
/
HotStuff
中的
leader
在進行
view
切換時,無需攜帶證明性資料。是以,
leader
的可信度較低(作惡空間很大)。對于
leader
發來的新的
proposal
,其他
replica
需要對其進行更為嚴格的檢查,也即出現了在上一節中所述的:
Tendermint
/
HotStuff
中的鎖定機制要求進一步檢查新的
proposal
是否基于已鎖定的
proposal
。
接下來,我們繼續對
Tendermint
/
HotStuff
類的鎖定機制的設計進行分析,并将這一類共識簡稱為“
single-modal
”類共識(
PBFT
被稱為
bi-modal
類共識)
4.Single-modal類共識中鎖定機制的設計
在第2節中,我們介紹到:
Single-modal
類共識在檢查新的
proposal
時,會進一步檢查該
proposal
是否基于其本地已經鎖定的
proposal
(或者說
QC
)。如果新
proposal
不是基于鎖定的
QC
,那麼這個
replica
會拒絕對該
proposal
投票。
同時,我們也補充說明了另外一種情況:如果新的
proposal
所指向(基于)的
QC
高于
replica
本地鎖定的
QC
,該
replica
會将自己鎖定的
QC
更新到
proposal
所基于的
QC
,并對其進行投票。
為了友善讨論,我們對這兩種投票的情況分别命名為規則1和規則2。這兩條規則也對應于
HotStuff
論文中的
SAFENODE
原語的設計,如下所示:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyMDNzETZ3MmMzkDO0U2M5EDZ4QDOmJGOxUjZihTZ3E2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
關于規則1,前面也讨論了,是為了減小
leader
的作惡空間,進而保證安全性;關于規則2,論文中寫到是為了保證活性(
liveness
)。我們來看看這一點如何了解。
4.1 對鎖定機制中規則2活性的了解
我們假想一下,如果沒有規則2,
Single-modal
類共識會出現什麼樣的問題。沒有規則2,也就意味着:每個
replica
都隻會對基于自己的
QC
的
proposal
投票。
我們考慮如下一個例子:
- 假設在
的時候,
view 0
是
replica 0
,且隻有其收到了
leader
并在本地鎖定了
QC
,此時由于網絡原因發生了
v0
的切換.
view
- 在
的時候,新的
view 1
(
leader
)由于沒有在
replica 1
鎖定,于是基于更早的一個
v0
(假設是
view
)發起了
vold
;此時
proposal
是不會進行投票的,因為這個
replica 0
不是基于
proposal
的,但其他的節點還是可能會投票,當
v0
收到了足夠多的投票組成
replica 1
後,其在本地鎖定
QC
;此時也由于網絡原因發生了
v1
的切換。
view
- 在
的時候,同理,
view 2
鎖定了
replica 2
v2
。
…
- 在
的時候,
view f
鎖定了
replica f
。
vf
- 此時,
~
replica (2f+1)
下線了,隻剩下
replica (3f)
~
replica 0
。(這也是滿足系統假設的,有超過
replica 2f
個正确節點,并且我們假設接下來是同步網絡)
2f+1
- 但接下來,協定就會卡住。
- 在新一輪次(所有
輪一遍稱為一個輪次)的
replica
中,
view
發起的新
replica 0
,
proposal
~
replica 1
都不認,因為不是基于他們鎖定的
replica f
發起的,進而無法收集到新的
view
;
QC
- 同理,
發起的新
replica 1
,
proposal
,
replica 0
~
replica 2
都不認,因為不是基于他們鎖定的
replica f
發起的,進而無法收集到新的
view
QC
;
…
上面這個例子在第4步之後,
replica 0
~
replia f
都不會給除了自己之外的其他節點的
proposal
投票。在每個
view
中
leader
無法都無法收集到
2f+1
個投票,也無法生成/鎖定新的
QC
。
是以,整個協定就卡住了。
也就是說,在沒有規則2的情況下,
Single-modal
類共識會卡住,進而失去活性。
相反,當引入規則2後,我們看看上面的例子會怎麼變化:
- 假設在
的時候,
view 0
是
replica 0
,且隻有其收到了
leader
并在本地鎖定了
QC
,此時由于網絡原因發生了
v0
的切換.
view
- 在
的時候,新的
view 1
(
leader
)由于沒有在v0鎖定,于是基于更早的一個
replica 1
(假設是
view
)發起了
vold
;此時
proposal
是不會進行投票的,因為這個
replica 0
不是基于
proposal
的,但其他的節點還是可能會投票,當
v0
收到了足夠多的投票組成
replica 1
後,其在本地鎖定
QC
;此時也由于網絡原因發生了
v1
的切換。
view
- 在
的時候,同理,
view 2
鎖定了
replica 2
v2
。
…
- 在
的時候,
view f
鎖定了
replica f
。
vf
- 此時,
~
replica (2f+1)
下線了,隻剩下
replica (3f)
~
replica 0
。(這也是滿足系統假設的,有超過
replica 2f
2f+1
個正确節點,并且我們假設接下來是同步網絡)
---------- 上面和前一個例子一樣,下面是規則2引入後的不同
- 在新一輪的
中,雖然
view
~
replica 0
發起的新
replica f-1
,都無法得到其他所有節點的認可,進而無法收集到新的
proposal
;但當輪轉到
QC
的時候,其基于
replica f
發起新的
view f
能夠得到所有
proposal
的認可,進而對其投票,因而
replica
可以收集到足夠多的投票并生成
replica f
QC
。
這就從上面例子中“協定卡住”的情況解脫出來了。
這裡,我們可能會有一個想法
每一個輪次,前面的~
replica 0
發起的
replica f-1
都無法得到其他所有節點的投票,隻有等到
proposal
的時候,才真正收集到足夠多的投票形成
replica f
,不會效率太低了嘛?
QC
針對該問題,
Single-modal
類共識都做了一個優化設計:
在每個發起新的
replica
之前,允許其收集其他
proposal
中的鎖定的
replica
資訊,再基于收集到的最高的
QC
發起新的
QC
,就可以大大提升效率了。
proposal
舉例來說,在上個例子中,如果
replica 0
在發起
proposal
之前就收到了
replica f
發來的
QC
(鎖定在
vf
高度),其基于該
QC
發起新的
proposal
,就可以得到其他所有
replica
的認可了。
4.2 為什麼 Tendermint
在進行 leader
切換的時候要等待 Δ \Delta Δ
Tendermint
leader
一切似乎都很美好了。但
Tendermint
在進行
leader
切換的時候,要求
leader
在發起
proposal
之前等待一個網絡時延的上限 Δ \Delta Δ。這使得
Tendermint
無法實作
optimistic responsiveness
。
我們先來分析一下為什麼要等待 Δ \Delta Δ。
4.2.1 Tendermint
不等待 Δ \Delta Δ導緻的 Hidden Lock
問題
Tendermint
Hidden Lock
Hidden lock
考慮的是同步網絡下的問題,因為異步網絡比同步網絡更難解決。如果同步網絡中存在
Hidden lock
問題,異步網絡中也會存在類似且更複雜的問題。
以下,我們考慮同步網絡下的
Hidden lock
問題。為了解釋該問題,我們也舉個例子如下。該例子中一開始是異步網絡,後面切換到同步網絡。
- 假設一開始所有
都是鎖定在一個
replica
(
view
)的
vold
QC
上。
接下來,在
的時候,
view 0
是
replica 0
,其首先收集
leader
個其他
2f
發來的
replica
(加上自身的
QC
一共
QC
個),這
2f+1
個
2f+1
中的最大值是
QC
的
vold
;
QC
基于該
replica 0
發起了
QC
;其他
proposal
對該
replica
紛紛進行投票;
proposal
收集到
replica 0
個投票後組成
2f+1
,并在本地鎖定了
QC
;此時,由于網絡原因發生
v0
的切換,使得除了
view
之外其他的節點都沒有收到
replica 0
對應的
v0
;
QC
- 在
的時候,
view 1
是
replica 1
,其首先收集
leader
個其他
2f
發來的
replica
(加上自身的
QC
一共
QC
個),這
2f+1
個
2f+1
中的最大值是
QC
的
vold
(也即其未收到
QC
發來的
replica 0
);
QC
基于該
replica 1
發起了
QC
;除了
proposal
之外的其他
replica 0
對該
replica
紛紛進行投票;
proposal
收集到
replica 1
個投票後組成
2f+1
,并在本地鎖定了
QC
;此時,由于網絡原因發生
v1
的切換,使得除了
view
之外其他的節點都沒有收到
replica 1
對應的
v1
;
QC
- 同理,在
的時候,隻有
view 2
在本地鎖定了
replica 2
對應的
v2
,其他
QC
replica
都未收到;
…
- 在
的時候,隻有
view f
在本地鎖定了
replica f
對應的
vf
,其他
QC
都未收到;
replica
- 在
的時候,
view (f+1)
發起
replica (f+1)
,但
proposal
~
replica 0
都不會進行投票。這一輪的
replica f
不會生成任何
view
…
QC
- 在
的時候,
view (3f)
發起
replica (3f)
,但
proposal
~
replica 0
都不會進行投票。這一輪的
replica f
不會生成任何
view
-----------以上是異步網絡環境,接下來進入同步網絡環境。在該網絡環境中,除了拜占庭節點,所有的節點之間的消息在 Δ \Delta Δ時間内都能正确送達------------
QC
- 在
的時候,又回到
view (3f+1)
,其首先收集了
replica 0
個其他
2f
發來的
replica
(加上自身的
QC
一共
QC
個),但巧合(也可能是惡意節點對網絡的操縱)的是這
2f+1
個
2f+1
中的最大值是
QC
自身的
replica 0
,也即鎖定在
QC
上的
v0
(這種情況下,
QC
收到的前
replica 0
個
2f
中沒有來自
QC
~
replica 1
節點的)。于是,其基于
replica f
發起新的
v0
,但
proposal
~
replica 1
都不會投票,
replica f
~
replica (f+1)
中的拜占庭節點也全不投票(假設其中有k個拜占庭節點),導緻
replica (3f)
隻能收到
replica 0
個投票(包含自身的),無法組成
(2f+1-k)
。其他誠實節點由于無法及時收到
QC
将
QC
切換到
view
。此時,拜占庭節點進行投票,使得
3f+2
又收到了足夠多的投票,組建出
replica 0
。于是,
QC
鎖定了
replica 0
。但其他節點已經切換到
v (3f+1)
了,即使接收到
view (3f+2)
發來的
replica 0
,也不會更新自己本地鎖定的
QC
了。
QC
- 在
的時候,又回到
view (3f+2)
,其首先收集了
replica 1
個其他
2f
發來的
replica
(加上自身的
QC
一共
QC
個),但巧合(也可能是惡意節點對網絡的操縱)的是這
2f+1
個
2f+1
中的最大值是
QC
自身的
replica 1
,也即鎖定在
QC
上的
v1
。于是,其基于
QC
發起新的
v1
,但
proposal
和
replica 0
~
replica2
都不會投票,
replica f
~
replica (f+1)
中的拜占庭節點也全不投票(假設其中有
replica (3f)
個拜占庭節點),導緻
k
隻能收到
replica 1
個投票(包含自身的),無法組成
(2f+1-k)
。其他誠實節點由于無法及時收到
QC
将
QC
切換到
view
。此時,拜占庭節點進行投票,使得
3f+3
又收到了足夠多的投票,組建出
replica 1
。于是,
QC
鎖定了
replica 1
v (3f+2)
。
…
- 在
的時候,又回到
view (3f+f+1)
,同理,隻有
replica f
鎖定了
replica f
。
v (3f+f+1)
- 在
的時候,又回到
view (3f+f+2)
,其首先收集了
replica (f+1)
個其他
2f
發來的
replica
(加上自身的
QC
一共
QC
個),但巧合(也可能是惡意節點對網絡的操縱)的是這
2f+1
個
2f+1
中的最大值是
QC
發來的
replica 0
,即鎖定在
QC
上。于是,其基于
v (3f+1)
發起新的
v (3f+1)
,但
proposal
~
replica 1
都不會投票,
replica f
~
replica (f+1)
中的拜占庭節點也全不投票(假設其中有
replica (3f)
個拜占庭節點),導緻
k
隻能收到
replica (f+1)
個投票(包含自身的),無法組成
(2f+1-k)
。其他誠實節點由于無法及時收到
QC
将
QC
切換到
view
3f+f+3
。
…
- 在
的時候,又回到
view (3f+3f+1)
,其同樣無法組成
replica (3f)
。其他誠實節點由于無法及時收到
QC
将
QC
切換到
view
。
3f+3f+2
- 在
的時候,又回到
view (3f+3f+2)
replica 0
,其又回到步驟6
…
上面的例子可能叙述得比較複雜,簡單來說就是:在每個輪次中,前
f+1
個
view
中有且隻有
leader
對應得
replica
鎖定到目前
view
上,後
2f
個
view
中所有
replica
都無法更新鎖定的
view
。這兩點又是分别通過以下的思路來實作的:
- 前
個f+1
中,在view
收集leader
的時候,隻收集到自身的QC
和後QC
個2f
的replica
,導緻這QC
個2f+1
中的最大值是QC
自身的leader
,QC
基于該leader
發起新的QC
;對于發起的proposal
,前proposal
個f+1
中除了自身之外都不會投票;後replica
個2f
中所有拜占庭節點一開始也不投票,導緻replica
收集不到足夠的投票,觸發其他誠實節點逾時切換到下一個leader
;然後,拜占庭節點進行投票,使得view
收集到足夠多的投票,生成更新的leader
,該QC
比前QC
個f+1
中的其他replica
中的replica
都要大。QC
- 在後
個2f
中,在view
收集leader
的時候,除了收集到的後QC
個2f
中發來的replica
,也會收集到前QC
個f+1
中的某一個replica
,我們假設其隻能收集到最低的那個QC
;QC
基于該leader
發起新的QC
;對于發起的proposal
,前proposal
個f+1
隻有一個會進行投票;後replica
個2f
中所喲有拜占庭節點一直不投票,導緻replica
一直收集不到足夠多的投票,進而無法生成更新的leader
,其他誠實節點也被觸發逾時切換到下一個QC
。view
這裡需要引入
Single-modal
類共識有效運作的定義:隻有發生了兩連跳才算是真正完成了一次有效(為什麼要求這一點,我們在後面的部落格進行詳細解釋,這裡先記住這個結論)。也即:在
view k
,必須是基于
view (k-1)
中鎖定的
QC
發起
proposal
。
而上面舉的例子顯然無法完成任何共識,因為整個協定在運作過程中不存在兩連跳。這個問題也被稱為
hidden lock
問題。
4.2.2 為什麼等待 Δ \Delta Δ可以解決 Hidden Lock
問題
Hidden Lock
造成
hidden lock
問題的根本原因是,一個
leader
在發起新的
proposal
之前并沒有等待其他所有誠實節點發來的
QC
,進而從中選出最高的
QC
。也即:有些誠實節點中的
QC
被隐藏 (hidden)了。
反過來說,如果我們要求每個
leader
在發起新的
proposal
之前必須等待同步網絡中的一個最大網絡時延,使得其能接收到所有誠實節點發來的
QC
,那麼在上面的例子中:
replica 1
中就可以基于
replica 0
中剛剛更新的
QC
發起
proposal
。該
QC
是網絡中最高的
QC
,一定可以得到其他所有誠實節點的投票,進而在
replica 1
中生成
QC
。這樣,就保證了
replica 1
和
replica 0
中分别生成的兩個
QC
是兩連跳的。
4.3 為什麼 HotStuff
不需要等待 Δ \Delta Δ
HotStuff
HotStuff
增加了一個輪次。其中第一個輪次後的
QC
稱為
prepareQC
,第二個輪次後的
QC
稱為
lockedQC
。
Leader
在發起新的
proposal
時将基于收集到的最高的
prepareQC
進行,而
replica
投票時将基于
proposal
中攜帶的最高
prepareQC
和本地儲存的
lockedQC
作比較。
對于任意一個
lockedQC
而言,其至少在
2f+1
個節點中儲存有對應的
prepareQC
,這進一步保證了
leader
在發起新的
proposal
時至少收集到一個該
prepareQC
。
是以,對于所有節點中儲存的最高的
lockedQC
,
leader
一定會接收到其對應的
prepareQC
,進而基于該
prepareQC
發起
proposal
,也一定會被所有誠實節點投票。
總結來說,
HotStuff
通過增加一個階段,保證了
leader
一定可以搜集到最高
lockedQC
對應的
prepareQC
。
因而,
HotStuff
不需要等待 Δ \Delta Δ。
5. 一個問題: replica
接收到舊 view
中的消息如何處理
replica
view
在4.2.1小節中,我們舉了個例子來說明
hidden lock
問題。其中,我們假設:當
replica
切換到下一個
view
後,即使其再接收到上一個
view
中的
QC
,也不會更新自己本地鎖定的
QC
。這樣的假設源于我們對于
HotStuff
論文中僞代碼的解讀,而且可以簡化4.2.1小節中的例子。
但筆者在在思考另外一種假設的合理性:
replica
接收并認可上一個
view
中的
QC
貌似也是合情合理的,而且可以讓協定更加魯棒。在本節,我們就對兩種假設進行更深入的讨論。
5.1 假設一:認為舊 view
中的消息是無效的
view
這一種假設在
HotStuff
論文中的
Algorithm 2
(
Basic HotStuff
)和
Algorithm 3
(
Chained HotStuff
)都是明确指明的,相應的僞代碼分别截圖如下:
這三處僞代碼中,
replica
在收到來自
leader
的消息後,都會調用
MATCHINGQC
或
MATCHINGMSG
對消息進行檢查,其中就包括消息中包含的
viewNumber
是否等于
curView
。也即:當
replica
已經切換到下一個
view
後,即使其再接收到上一個
view
中的消息,也會直接丢棄。
但另一方面,在
HotStuff
論文的
Algorithm 4
(
Event-driven HotStuff
)中,并沒有對接收到的消息的
viewNumber
進行明确檢查。這一點需要閱讀
HotStuff
源碼後進行進一步确認。
5.2 假設二:認為舊 view
中的消息有效的
view
Tendermint
論文對是否進行
viewNumber
檢查也沒有進行明确說明。我們暫且不考慮
Tendermint
以及
HotStuff
中
Algorithm 4
的設計,來推演一下:如果認可舊
view
中的消息,
Single-modal
類的二階段共識會存在什麼問題。
基于該假設,我們需要對4.2.1小節中構造的例子進行更新,更新後的例子如下:
- 假設一開始所有
都是鎖定在一個
replica
(
view
vold
)的QC上
接下來,在
的時候,
view 0
是
replica 0
,其首先收集
leader
個其他
2f
發來的
replica
(加上自身的
QC
一共
QC
個),這
2f+1
個
2f+1
中的最大值是
QC
的
vold
;
QC
基于該
replica 0
發起了
QC
;其他
proposal
對該
replica
紛紛進行投票;
proposal
收集到
replica 0
個投票後組成
2f+1
,并在本地鎖定了
QC
;此時,由于網絡原因發生
v0
的切換,使得除了
view
之外其他的節點都沒有收到
replica 0
對應的
v0
;
QC
- 在
的時候,
view 1
是
replica 1
,其首先收集
leader
個其他
2f
發來的
replica
(加上自身的
QC
一共
QC
個),這
2f+1
個
2f+1
中的最大值是
QC
的
vold
(也即其未收到
QC
發來的
replica 0
);
QC
基于該
replica 1
發起了
QC
;除了
proposal
之外的其他
replica 0
對該
replica
紛紛進行投票;
proposal
收集到
replica 1
個投票後組成
2f+1
,并在本地鎖定了
QC
;此時,由于網絡原因發生
v1
的切換,使得除了
view
之外其他的節點都沒有收到
replica 1
對應的
v1
;
QC
- 同理,在
的時候,隻有
view 2
在本地鎖定了
replica 2
對應的
v2
,其他
QC
replica
都未收到;
…
- 在
的時候,隻有
view f
在本地鎖定了
replica f
對應的
vf
,其他
QC
都未收到;
replica
- 在
的時候,
view (f+1)
發起
replica (f+1)
,但
proposal
~
replica 0
都不會進行投票。這一輪的
replica f
不會生成任何
view
…
QC
- 在
的時候,
view (3f)
發起
replica (3f)
,但
proposal
~
replica 0
都不會進行投票。這一輪的
replica f
不會生成任何
view
-----------以上是異步網絡環境,接下來進入同步網絡環境。在該網絡環境中,除了拜占庭節點,所有的節點之間的消息在 Δ \Delta Δ時間内都能正确送達------------
QC
- 在
的時候,又回到
view (3f+1)
,其首先收集了
replica 0
個其他
2f
發來的
replica
(加上自身的
QC
一共
QC
個),但巧合(也可能是惡意節點對網絡的操縱)的是這
2f+1
個
2f+1
中的最大值是
QC
自身的
replica 0
,也即鎖定在
QC
上的
v0
(這種情況下,
QC
收到的前
replica 0
個
2f
中沒有來自
QC
~
replica 1
節點的)。于是,其基于
replica f
發起新的
v0
,但
proposal
~
replica 1
都不會投票,
replica f
~
replica (f+1)
中的拜占庭節點也全不投票(假設其中有
replica (3f)
個拜占庭節點),導緻
k
隻能收到
replica 0
個投票(包含自身的),無法組成
(2f+1-k)
。其他誠實節點由于無法及時收到
QC
将
QC
切換到
view
,并将一個舊的
3f+2
(低于
QC
)發送給下一任
3f+1
(
leader
)。
replica 1
- 在
的時候,又回到
view (3f+2)
,其首先收集了
replica 1
個其他
2f
發來的
replica
(加上自身的
QC
一共
QC
個),這
2f+1
個
2f+1
中的最大值是
QC
中的
replica f
,也即鎖定在
QC
上的
vf
。于是,其基于
QC
發起新的
vf
。與此同時,拜占庭節點向
proposal
發送
replica 0
的投票,使得
view (3f+1)
又收到了針對
replica 0
的足夠多的投票,組建出
view (3f+1)
的
v (3f+1)
,并進一步将這個
QC
廣播給其他節點。當誠實的
QC
(
replica
~
replica 0
)接收到
replica 2f
的
replica 1
後,除了
proposal
,其他的
replica 0
都會進行投票(尚未收到
replica
的
v (3f+1)
),所有的拜占庭節點(
QC
~
replica 2f+1
)也都不投票。導緻,
replica 3f
隻能收到
replica 1
個投票(包含自身的),無法組成
2f
。其他誠實節點由于無法及時收到
QC
将
QC
切換到
view
。此時,所有誠實節點都接收到了
3f+3
的
v (3f+1)
,因而在進行
QC
切換時,将
view
的
v (3f+1)
發送給下一任
QC
(
leader
)。
replica 2
- 在
的時候,又回到
view (3f+3)
,其首先收集了
replica 2
個其他
2f
發來的
replica
(加上自身的
QC
一共
QC
個),這
2f+1
個
2f+1
中的最大值是鎖定在
QC
上的
v (3f+1)
。于是,其基于
QC
發起新的
v (3f+1)
。與此同時,拜占庭節點向
proposal
發送
replica 1
的投票,使得
view (3f+2)
又收到了針對
replica 1
的足夠多的投票,組建出
view (3f+2)
的
v (3f+2)
,并進一步将這個
QC
廣播給其他節點。當誠實的
QC
(
replica
~
replica 0
)接收到
replica 2f
的
replica 2
後,除了replica 1,其他的replica都會進行投票(尚未收到
proposal
的
v (3f+2)
),所有的拜占庭節點(
QC
~
replica 2f+1
)也都不投票。導緻,
replica 3f
隻能收到
replica 2
個投票(包含自身的),無法組成
2f
。其他誠實節點由于無法及時收到
QC
将
QC
切換到
view
。此時,所有誠實節點都接收到了
3f+4
的
v (3f+2)
,因而在進行
QC
切換時,将
view
的
v (3f+2)
發送給下一任
QC
(
leader
replica 3
)。
…
- 同理,在
的時候,又回到了
view (3f+2f+1)
,其基于
replica (2f)
的
v (3f+2f-1)
發起新的
QC
;與此同時,拜占庭節點對
proposal
進行投票,使得
view (3f+2f)
組建成
replica (2f-1)
的
v (3f+2f)
,并廣播給其他節點。其他節點接收到
QC
的
replica (2f)
後,
proposal
~
replica 0
會進行投票,
replica (2f-2)
和所有拜占庭節點都不投票,導緻
replica (2f-1)
隻能收到
replica (2f)
個投票(包含自身的),無法組成
2f
。其他誠實節點由于無法及時收到
QC
将
QC
切換到
view
。此時,所有誠實節點都接收到了
3f+2f+2
的
v (3f+2f)
,因而在進行
QC
切換時,将
view
的
v (3f+2f)
發送給下一任
QC
(
leader
)。
replica 2f+1
~
replica (2f+1)
都是拜占庭節點,直接跳過
replica (3f)
~
view (3f+2f+2)
view( 3f+3f+1)
- 在
的時候,又回到
view (3f+3f+2)
,其基于
replica 0
的
v (3f+2f)
發起新的
QC
;與此同時,拜占庭節點對
proposal
進行投票,使得
view (3f+2f+1)
組建成
replica (2f)
的
v (3f+2f+1)
,并廣播給其他節點。其他節點接收到
QC
的
replica 0
後,
proposal
~
replica 1
會進行投票,
replica (2f-1)
和所有拜占庭節點都不投票,導緻
replica (2f)
隻能收到
replica 0
個投票(包含自身的),無法組成
2f
。其他誠實節點由于無法及時收到
QC
将
QC
切換到
view
。此時,所有誠實節點都接收到了
3f+3f+3
的
v (3f+2f+1)
,因而在進行
QC
切換時,将
view
的
v (3f+2f+1)
發送給下一任
QC
(
leader
replica 1
)。
…
以上的例子同樣暴露了一個問題,就是不存在兩連跳的
QC
,舉例來說:
v (3f+3)
的
QC
是基于
v (3f+1)
的
QC
,而
v (3f+2f+1)
的
QC
是基于
v (3f+2f-1)
的
QC
。這使得共識無法有效運作,失去了
liveness
。
更嚴重的是,這是比
hidden lock
更為棘手的一個問題,因為這個問題是沒法通過等待 Δ \Delta Δ來解決的。可能,這也是為什麼
HotStuff
論文的
Algorithm 2
和
Algorithm 3
需要對消息的
viewNumber
進行檢查的原因。