SCAR:一種可伸縮共識演算法

買賣虛擬貨幣
諸如PoW(Proof of Work)、PoS(Proof of Stake)等傳統的區塊鏈公式演算法,為了減少分叉保證網路的穩定性,通常區塊的間隔在10秒以上。例如Ethereum的區塊間隔時間是15秒,Qtum是144秒,Bitcoin是10分鐘。過高的區塊間隔時間,導致了使用者等待交易確認的時間較長,不利於實時支付等應用。而一些聯盟鏈的共識演算法,例如EOS的DPoS [1](Delegated Proof of Stake)、Parity的Aura [2](Authority Round)等,透過投票選出超級節點來執行共識演算法,可以將區塊間隔時間降到甚至1秒以內。但這樣帶來的問題就是block的數量過多,對網路頻寬和資料儲存都帶來了很大的壓力。執行一個全節點,甚至僅下載block header的輕節點,都對節點裝置的效能有較高的要求。對於區塊鏈的大多數商業應用而言,如徵信上鍊、商品溯源等,對於區塊鏈的寫操作通常是週期性的。即每天的部分時間交易量較大,其餘時間交易量小。對於這樣的場景,如果始終維持高速的區塊產出,對於網路和儲存資源都是較大的浪費,而僅需要保證在網路高峰時段系統有較高的效能即可。因此,我們提出了 SCAR(Scalable Consensus Algorithm)可伸縮共識演算法。SCAR的思想是根據區塊鏈網路的負載,動態地調節引數,在高效能和低負載之間找到平衡,從而實現效能可伸縮。相關共識演算法介紹PoW,Bitcoin為代表。節點提供算力,透過大量的計算,產生新的block。算力越高,產生block的速度越快。計算難度每2016個block調整一次,保證在全網算力變化的情況下,block時間間隔保持在10分鐘左右。由於block間隔時間長,且每個block的大小限制在 1 MB,所以當交易量大的時候,網路會發生嚴重擁堵。
PoS,Qtum為代表。節點提供token,透過少量計算,產生新的block。token數額越大,產生block的速度越快。計算難度也會定期調整,保證block時間間隔在144秒左右。PoS相對PoW而言,降低了對算力的要求,節省了能源。但是由於block間隔和block大小限制仍然是固定的,網路的負載固定,無法避免交易量大時候的擁堵。雖然Qtum目前可以使用DGP [3](Decentralized Governance Protocol)協議手動地去調整block大小限制,但是這種方式略微繁瑣。PoW和PoS中,全網的所有節點都會參與到共識的競爭中來,所以區塊間隔不能設定得過小。如果過小,則很容易產生分叉。即,如果計算難度設定得過低,則很容易出現多個節點在同一時刻產出新的block的情況。DPoS、Tendermint等聯盟鏈共識演算法,則透過投票得到的超級節點來執行共識。由於參與共識的節點數較少,則區塊間隔可以設定得很小。比如EOS的block間隔就設定成了0.5s。過短的區塊間隔對頻寬和硬碟都是很大的壓力,在交易量少的時候也是一種資源浪費。EOS從今年6月9日上線以來,block數量至今已達1200萬,而9年前開始的Bitcoin至今也才50萬個block。SCAR 共識演算法描述以下將介紹SCAR演算法的一種實現方式。這種實現方式在聯盟鏈的基礎上,透過交易量來動態地更新區塊間隔,從而實現了區塊鏈效能的可升縮。需要注意的是,SCAR演算法的核心思想是根據負載動態地調整區塊鏈的效能,所以實現方式並不侷限於本文所提出的這種,更多的實現有待進一步地探索。SCAR共識演算法由三個步驟組成:
1. 統計投票得到所有超級節點。2. 根據網路負載計算block間隔。3. 間隔時間到後,超級節點按照優先順序產出block,一旦一個新的block產出,回到步驟1。SCAR共識演算法的優點在於:1. 由超級節點執行共識,block間隔可以極大程度縮短,交易確認快。2. block間隔根據網路負載動態調整,空閒時候間隔變長,降低頻寬和硬碟壓力。
3. 當低於半數的超級節點出現故障的時候,新的block仍然能夠產出,系統魯棒性強。以下將分別描述SCAR演算法的三個步驟。節點投票投票選出超級節點可以有多種設計。比如EOS是所有使用者都能參與投票,Aura是當前的超級節點可以投票選出下一輪的超級節點。這裡我們提出一種基於Qtum DGP協議的投票策略。區塊鏈初始化時在鏈上部署 DGP 的智慧合約,在合約內初始化了管理席位 admin 和治理席位 gov,均以地址的形式儲存。DGP 協議支援在鏈上透過管理席位 admin 和治理席位 gov的投票,來決定超級節點是否改變。首先我們對管理席位和治理席位的許可權和修改策略做個介紹。管理席位 admin 在決定許可權時具有最多的權力,它可以參與投票增加和刪除 admin,同時可以投票任命 gov;而 gov只能參與到超級節點的修改投票中。即所有提案只有具備管理席位的 admin地址才能設定,具有治理席位的 gov地址僅可參與超級節點投票。
投票的具體流程如下:1. 收集新的超級節點的提案,向社羣公佈並收集反饋;2. 根據社羣反饋調整超級節點列表,並透過智慧合約儲存到區塊鏈中,作為新的提案;3. 透過呼叫 DGP 合約的相應方法,將該提案設定為待投票的提案,此時即開啟投票;4. 擁有管理admin和治理gov許可權的地址透過向投票合約傳送一筆交易來對提案進行投票;5. 若提案未獲得足夠投票則被否決,不執行修改;
6. 若提案透過,新超級節點列表的儲存地址會記錄進DGP合約,並在一定數量的區塊後生效,以防止出現不必要的分叉。7. 節點可以透過 DGP 合約來獲取最新的超級節點列表。綜上所述,我們可以在鏈上設定 DGP 合約,透過 DGP 投票的方式來決定超級節點,並動態地儲存和更新授權礦工列表。block 間隔block的間隔需要根據網路的負載情況動態調整,網路空閒時候間隔變長,網路繁忙時候間隔變短,從而實現動態可伸縮。這裡我們提出一種block間隔的計算方法,根據近期的交易數量來進行計算,交易多則間隔變短,交易少則間隔變長。

block間隔的計算公式如下:

其中,min_interval 為最小的block時間間隔,max_interval 為最大的block時間間隔。transaction_num 為最近 m 個區塊內的平均交易數,這裡 m 可以為大於等於1的整數。 m、min_interval 以及 max_interval 透過共識演算法預先設定或者智慧合約設定。

這樣設計公式的意義在於:

1. 當交易量 transaction_num 為0時,block間隔將調整為 max_interval,此時將用系統設定的最長間隔時間來儘量在一個區塊內打包更多交易,避免了儲存空間的浪費;
2. 當鏈上交易量 transaction_num 趨向於無窮大時,block間隔將無限趨近於 min_interval,此時將用系統設定的最短間隔時間來儘可能緩解區塊鏈網路的交易擁塞,使得交易更快地被打包進區塊;
3. max_interval 和 min_interval 可以根據實際情況進行設定(例如使用者容忍的交易延遲、超級節點的網路環境和儲存效能等)。

採用這種根據網路狀態動態調節區塊出塊時間的共識演算法 SCAR,可以有效的避免在交易量小時浪費儲存空間,也可以在交易量大時增大區塊產生速率,及時將交易打包進區塊鏈上,保證交易更快地被確認。鏈上引數的動態調整也使得區塊鏈系統變得更加靈活,提高治理效率,降低治理難度和代價。

block 產出

當超級節點和block間隔都確定之後,節點就可以在間隔時間之後輪流產出新的block。

在某一區塊鏈高度上,若超級節點的數量為 n 個,則 SCAR 會為每個超級節點分配不同的出塊時間 block_time如下:

其中,parent_block_time 為上一個block的出塊時間,block_interval 為動態計算出的區塊間隔。timeout 為超時時間,用來防止某些超級節點出現故障長時間無法出塊,miner_index 為索引值,在同一區塊高度下,不同的授權節點miner_index 不同。下面將對具體的引數設定原因和用途做出解釋。

如下圖所示,假定有5個被授權的超級節點 A、B、C、D、E,他們的公鑰被儲存在有序列表中,即上文提及的由 DGP 投票選出並可動態維護的超級節點列表(也即礦工列表)。假定在區塊鏈高度h2時,有序礦工列表是 [pubkey_A, pubkey_B, pubkey_C, pubkey_D, pubkey_E] ,這五個超級節點會輪流建立新的區塊。

當建立新區塊時,礦工會透過加密演算法簽名這個區塊,然後將簽名結果附加到區塊中。透過這種方式,其他節點可以透過解密從區塊中恢復出礦工的公鑰來,從而透過和超級節點列表進行比對來驗證該礦工是否有權建立區塊。當一條鏈被大多數礦工簽名之後,這條鏈可以被視作為一條永久的鏈。例如在上圖中,從創世區塊到h3高度的鏈是一條永久的鏈,因為它已經被它接下來的幾位礦工D、E和A簽名了。如果任何礦工想要在高度h3下面製造分叉,這一分叉則無法被絕大多數礦工所認同。

共識演算法可以有效地避免分叉的發生,但至少需要 n/2+1 位超級節點保持公式演算法的正常執行(n 是超級節點數量,n/2 是整數除法)。共識演算法對允許建立下一個區塊的礦工做出了以下定義:

一個礦工在以下情況可以建立新的區塊:

1. 它當前是被授權的;
2. 最近的n/2個塊不是由它建立的。

由上述定義可得到真正被允許建立下一區塊的超級節點的方式:從當前礦工列表中去掉為最近 n/2 個塊簽名的節點即可。例如,在區塊高度 h2 上,下一區塊的礦工列表如圖計算得到。

由上圖過程選出了 B、C、D 三個可建立下一區塊的節點後,我們只需要將超級節點列表設定為有序列表,指定它們的優先順序先後,就可以避免它們為產出下一區塊而競爭。公式中的 miner_index 即為排序後的礦工列表的優先順序索引,排序更前的超級節點將被分配更早的 block_time,每個超級節點使用被分配的 block_time 建立新的區塊,並在 block_time 到來前保持等待狀態。

但超級節點模式的聯盟鏈也面臨著一個問題:部分節點的故障會導致網路效率驟降甚至癱瘓。為了避免部分節點的故障導致系統停止執行,共識加入以下策略來確保正常出塊。我們在系統引數中設定了 timeout ,若一個超級節點由於故障未能成功廣播新的區塊,則下一個超級節點會在 timeout 時間之後取代它並正常產出區塊。如下圖所示,在上述5個超級節點的情況下,礦工 B 在產出高度為 h2+1 的區塊時發生故障。隨後,B 在超級節點列表中的下一位C ,將會在其 parent_block_time 的 block_interval+timeout 時間之後,廣播其建立的新區塊。

實現

SCAR演算法在Unita的當前版本中已經實現。其策略是,只有當網路中有未確認交易的時候,才會產生新的block。我們計劃後續根據實際使用情況進行改進。

總結

SCAR在保證區塊鏈效能的同時,儘可能節省了頻寬和硬碟的消耗,並支援動態調整鏈上引數,相比其他共識演算法更加的高效和靈活,在大規模的商業應用中會有更大的優勢。

參考文獻

[1] EOS.IO Technical White Paper v2: Consensus Algorithm (BFT-DPOS). https://github.com/EOSIO/Documentation/blob/master/TechnicalWhitePaper.md, March 16, 2018
[2] Aura - Authority Round - Wiki. https://wiki.parity.io/Aura
[3] Qtum區塊鏈指南. https://docs.qtum.site/zh/Qtum-Blockchain-Guide.html

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;