1.名詞解釋:
QC:表示一個被<span id="MathJax-Span-8" class="mrow"><span id="MathJax-Span-9" class="mo">(<span id="MathJax-Span-10" class="mi">n<span id="MathJax-Span-11" class="mo">−<span id="MathJax-Span-12" class="mi">f<span id="MathJax-Span-13" class="mo">)個節點簽名確認的資料包及viewNumber。比如,對某個區塊的<span class="MathJax_Preview"><span id="MathJax-Element-3-Frame" class="MathJax"><span id="MathJax-Span-14" class="math"><span id="MathJax-Span-15" class="mrow"><span id="MathJax-Span-16" class="mo">(<span id="MathJax-Span-17" class="mi">n<span id="MathJax-Span-18" class="mo">−<span id="MathJax-Span-19" class="mi">f<span id="MathJax-Span-20" class="mo">)個投票集合。
prepareQC: 對於某個prepare訊息,Leader收集齊<span id="MathJax-Span-22" class="mrow"><span id="MathJax-Span-23" class="mo">(<span id="MathJax-Span-24" class="mi">n<span id="MathJax-Span-25" class="mo">−<span id="MathJax-Span-26" class="mi">f<span id="MathJax-Span-27" class="mo">)個節點簽名所生成的證據(聚合簽名或者是訊息集合),可以視為第一輪投票達成的證據
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">lockedQC: 對於某個precommit訊息,Leader收集齊<span class="MathJax_Preview"><span id="MathJax-Span-28" class="math"><span id="MathJax-Span-29" class="mrow"><span id="MathJax-Span-30" class="mo">(<span id="MathJax-Span-31" class="mi">n<span id="MathJax-Span-32" class="mo">−<span id="MathJax-Span-33" class="mi">f<span id="MathJax-Span-34" class="mo">)個節點簽名所生成的證據(聚合簽名或者是訊息集合),可以視為第二輪投票達成的證據
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">2.演算法流程
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">四階段演算法,三階段投票
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">prepare階段:
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">每個View開始時,新的Leader收集由<span class="MathJax_Preview"><span id="MathJax-Span-41" class="math"><span id="MathJax-Span-42" class="mrow"><span id="MathJax-Span-43" class="mo">(<span id="MathJax-Span-44" class="mi">n<span id="MathJax-Span-45" class="mo">−<span id="MathJax-Span-46" class="mi">f<span id="MathJax-Span-47" class="mo">)個副本節點傳送的NEW-VIEW訊息,每個NEW-VIEW訊息中包含了傳送節點上高度最高的prepareQC(如果沒有則設為空)。
Leader從收到的NewView訊息中,選取高度最高的preparedQC作為highQC。因為highQC是viewNumber最大的,所以不會有比它更高的區塊得到確認,該區塊所在的分支是安全的。
Leader節點會在highQC所在的安全分支來建立一個新的區塊,並廣播proposal,proposal中包含了新的區塊和highQC,其中highQC作為proposal的安全性驗證。
其他節點(replica)一旦收到當前View對應Leader的Proposal訊息,Replica會根據會safeNode-predicate規則檢查Proposal是否合法。如果Proposal合法,Replica會向Leader傳送一個Prepare-vote(根據自己私鑰份額對Proposal的簽名)。
由於比較的是lockedQC,因此第一輪投票可以反悔(safety判斷規則對比的是lockQC,而不是第一輪投票的結果,所以即使在上一輪針對A投了prepare票,假如A沒有commit,那麼下一輪依然可以對A’投票,所以說第一輪投票可以反悔。)
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">precommit階段:
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">Leader發出proposal訊息以後,等待<span class="MathJax_Preview"><span id="MathJax-Span-55" class="math"><span id="MathJax-Span-56" class="mrow"><span id="MathJax-Span-57" class="mo">(<span id="MathJax-Span-58" class="mi">n<span id="MathJax-Span-59" class="mo">−<span id="MathJax-Span-60" class="mi">f<span id="MathJax-Span-61" class="mo">)個節點對於該proposal的簽名,集齊簽名後會將這些簽名組合成一個新的簽名,以生成<em>prepare-QC</em>儲存在本地,然後將其放入PRECOMMIT訊息中廣播給Replica節點。
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo"><span class="MathJax_Preview"><span class="math"><span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">當Replica收到Precommit訊息時,會對其簽名,然後回覆給leader。
-
在HotStuff中,一輪投票的過程,是透過replica與Leader的互動完成
- replica收到proposal,對其簽名後,傳送給Leader
- Leader集齊簽名(投票)後,將簽名(投票)組裝,廣播precommit訊息
- replica收到Precommit,驗證其中籤名,驗證透過則表示第一輪投票成功。
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">commit階段;
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">Leader先收集(n-f)個precommit-vote,然後將其組合為precommit-QC,並將其放在COMMIT訊息中廣播。
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">當Replica收到COMMIT訊息時,會對其簽名commit-vote,然後回覆給leader。更為重要的是,在此時,replica鎖定在precommitQC上,將本地的lockQC更新成收到的precommitQC.
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo"><br data-mce-bogus="1">
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">decide階段:
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">當Leader收到了(n-f)個commit-vote投票,將他們組合成commitQC,廣播DECIDE訊息。
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">Replica收到DECIDE訊息中的commitQC後,認為當前proposal是一個確定的訊息,然後執行已經確定的分支上的tx。Viewnumber加1,開始新的階段。
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo"><br data-mce-bogus="1">
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo"><br data-mce-bogus="1">
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo"><br data-mce-bogus="1">
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">綜上所述:hotstuff之間只有leader和replica之間的資訊傳遞,而PBFT中不同replica之間也是可以進行訊息傳遞的
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo"><br data-mce-bogus="1">
<span class="mrow"><span class="mo"><span class="mi"><span class="mo"><span class="mi"><span class="mo">chained hotstuff流程:
- 非Leader節點
- 等待來自Leader的Proposal訊息
- 收到Leader的Proposal訊息後,檢查訊息中的QC,更新本地的prepareQC、lockedQC等變數,發出投票
- 向下一Leader發出NewView訊息
- Leader節點
- 等待NewView訊息,然後發出Proposal
- 發出Proposal後,等待其他節點的投票
- 向下一個Leader發出NewView訊息
正常情況下,每個View中都有一個區塊產生並集齊簽名,但是情況不會總是這麼完美,有時不會有新的區塊產生。為了保持區塊高度與viewNumber的一致,hotStuff中引入了<em>Dummy block</em>的概念。假如在一個View中,不能達成共識,那麼就在為該View新增一個<em>Dummy block</em>。
lockedQC是pre-commitQC,prepareQC是prepareQC它們都在副本本地更新。
都是第二輪投票完成的時候對方案和投票進行了鎖定,防止一個副本對一個方案投兩次矛盾的票