讀懂區塊鏈共識機制 :PoW、PoS、PAXOS、RAFT、PBFT

BSN研習社發表於2023-01-28
所謂“共識機制”,是透過特殊節點的投票,在很短的時間內完成對交易的驗證和確認; 對一筆交易,如果利益不相干的若干個節點能夠達成共識,我們就可以 認為全網對此也能夠達成共識。 再通俗一點來講,如果中國一名微博大V、美國一名虛擬幣玩家、一名非洲留學生和一名歐洲旅行者互不相識,但他們都一致認為你是個好人,那麼基本上就可以斷定你這人還不壞。

百度百科

Consensus

當談及分散式環境中的共識時,一般涉及到兩種型別的節點:

  • Legitimate nodes:誠實節點,覺得你是好人,就投票你為好人

  • Malicious nodes:惡意節點,行為“惡劣”,顛倒黑白

此外,即使發生任何故障,我們的系統也必須正常執行。有兩種型別的故障會發生:

  • Crash failure:誠實節點發生的故障(訊息延遲、不可送達)

  • Byzantine failure:惡意節點造成的故障(篡改訊息、不按套路執行協議)

因此,區塊鏈共識協議的主要責任有:

  • 保持賬本(區塊鏈)中的資料的有序性、安全性

  • 在區塊鏈網路中的節點之間達成協議,即提供拜占庭協議(即使出現拜占庭式的失敗,也不會造成太大影響)

拜占庭協議(Byzantine Agreement)採用的方法是確保可以透過分散式的方法達成共識,即使出現了拜占庭式的失敗也不會影響。“拜占庭失敗”可以理解為惡意節點造成的故障。

下面列出一些著名的DLT(分散式賬本)以及它們所使用的共識演算法:

DLT Consensus Algorithm Used Description
Bitcoin PoW 應用 PoW 來生產新的貨幣
Ethereum PoW 首次收到傳入操作的賬戶
Hyperledger PBFT 如果 2/3 的成員對新的區塊達成共識,那麼該區塊就成為區塊鏈的一部分
Parity PoS 要求礦工提供一定數量加密貨幣的所有權,而不要求其算力
Hashgraph Virtual voting-based consensus algorithm
Tezos PoS

Proof of Work(PoW)

比特幣區塊鏈的共識機制,PoW是為公共區塊鏈設計的。在PoW中,共識能否最終達成是不被保證的。在PoW中,礦工既是leader node又是validator node。

節點透過計算隨機雜湊雜湊的數值解爭奪記賬權,求得正確的數值解以生成區塊的能力是節點算力的具體表現,算力越高,就越有可能解得數值。計算出雜湊值的節點才能夠向區塊鏈中新增區塊,並獲得獎勵。某個節點獲勝的機率為

undefined

其中,i代表每個參與節點,N是節點的總數量,φi 代表節點i的算力。

PoW存在的問題:

  • 如果某兩個礦工同時解出了PoW puzzle,就會造成所謂的fork

  • 達成共識所需週期長

  • 耗費大量計算資源

  • 雙花問題(double spending)

假如我們微信錢包裡有 100 塊錢的龐大資產,我們先去飯店吃了頓飯,結果微信出了 bug,這一筆錢並沒有被銀行同步,還留在錢包裡,於是我們又能拿著同樣的 100 塊錢去看場電影,這就屬於雙花問題。在區塊鏈系統中,由於共識機制導致區塊確認時間長,用一個數字貨幣去進行一次交易,可以在這筆交易還未被確認完成前,進行第二筆交易,這就會造成雙花問題。

PoW的容錯能力:

  • PoW可能會遭到51%算力攻擊。當系統中有合作關係的惡意節點所控制的算力,超過誠實節點所控制的算力,系統就有被攻擊的風險。

  • 可以容忍拜占庭失敗

  • 可以有效抵禦“女巫攻擊”(Sybil Attack),即少數惡意節點構造多個虛假身份,並利用這些身份控制或影響網路的大量正常節點。

Proof of Stake(PoS)

在權益證明(PoS)類共識協議中,礦工的選擇取決於每個節點攜帶的“權益”(如加密貨幣)數量,而不是其計算能力。

PoS 相比 PoW 會消耗更少的資源,縮短達成共識所需的時間。當然,PoS 也存在自己的一些問題,例如,在 PoS 中,獎勵的授予方式應該是使所有節點都有平等的機會參與到採礦過程中。否則,每次獲勝的都為權益較高的礦工,每次得到獎勵的也是它。而且如果有任何延遲或連結的連線問題,節點可能沒有賬本的最新副本,因此會導致同步問題。

下面這張圖總結了PoS相比PoW的一些區別:

undefined

PAXOS

最基本的分散式共識(一致性)演算法,允許在不可靠的通訊條件下(資訊可以延遲、丟失或者重複,但沒有出錯)對一個值達成共識。

PAXOS的核心idea是,如果有一半以上的程式選擇了一個值,那麼依據多數人代表整體的原則,這個值就是共識。

PAXOS中的節點:

  • Proposer:提出要達成一致的值。某個選取的Proposer作為一個單的的 leader,提出一個新的決議,它處理客戶的請求。

  • Acceptor:Acceptor根據若干規則和條件對決議進行評估,並決定接受還是拒絕Proposer提出的建議。

  • Learner:獲取Acceptor達成一致的值

Phases in PAXOS

Prepare Phase

  1. Proposer收到客戶提出的就某個值達成共識的請求;

  2. Proposer向大多數或所有接受者傳送一個訊息prepare(n);

  3. Acceptor接收到prepare(n) 訊息,並進行回應。

在第二步中,n代表proposal number,它必須是全域性唯一的,且要大於該Proposer之前使用過的proposal number。如果Proposer沒有收到來自大多數Acceptor的響應,那麼它需要增大n,重新傳送。

在第三步中,如果Acceptor之前沒有做出過任何響應,那麼它會回覆 promise(n) 訊息,並承諾會忽略之後任何小於n的proposal number。而如果Acceptor之前有做出過回應,即對某個小於n的proposal number回覆了promise(n) 訊息,那麼進一步可分為兩種情況:

  • 如果它還沒有收到來自之前Proposer的accept訊息,那麼它會儲存現在更高的proposal number n,回覆promise(n) 訊息;

  • 如果它已經收到了來自之前Proposer的accept訊息,那麼它一定已經相應的回覆了accepted訊息,在這種情況下,它會把之前這個full proposal連同 promise(n) 訊息一起回覆,表明我之前已經接收過值了。

Accept Phase

  1. Proposer等待,直到得到大多數Acceptor對該proposal number n的回應;

  2. 評估應該在accept訊息中傳送什麼v值;

  3. 給Acceptor傳送accept(n, v) 訊息,v值是實際要達成一致的值;

  4. Acceptor接收到accept(n, v) 訊息後,要麼回覆accepted(n, v) 訊息並將該訊息發給所有learners,要麼直接忽略;

  5. 如果大多數Acceptor都接受了v值這個提議,那麼就達成共識了。

第二步細節:如果Proposer收到的promise訊息中有帶有full proposal 的,那麼它會將v值增大,如果都沒有full proposal的話,v值可以隨便選取。

第四步細節:Acceptor接收到accept(n, v) 訊息後:

  • 如果它之前已經承諾過不接受這個proposal number,它就會忽略這個訊息;

  • 如果它之前回復過promise(n) 了,那麼它就回復accepted(n, v) 訊息並將該訊息發給所有learners。

Replicated And Fault Tolerant(RAFT)

RAFT允許叢集的重新配置,這使得叢集成員的改變不需要中斷服務。它還允許日誌壓縮,以緩解節點崩潰後緩慢重建的問題並減少消耗的儲存。

一個RAFT叢集中的節點可分為以下三種:

  • Leader:接收客戶請求,組織日誌複製給其它節點,並管理與Follower的通訊

  • Follower:節點在本質上是被動的,只對遠端過程呼叫(RPC)做出響應。它們從不主動發起任何通訊,只會接受leader的複製日誌,對leader言聽計從

  • Candidate:嘗試成為leader的節點,會發起投票請求

RAFT主要包括兩個階段:

  • leader election

  • log replication

這裡先將三個節點之間的狀態轉換圖給出,具體過程可以往下看。

undefined

Leader Election

Leader Election會基於一個心跳(heartbeat)機制來觸發leader的選舉過程:

  1. 所有的節點一開始都是Follower;

  2. 如果Follower持續收到來自leader或者candidate的遠端過程呼叫,那麼它們只會保持自己Follower的身份;

  3. 如果特定時間內某個Follower沒有收到來自leader的心跳包,表明leader可能已經失效了,那麼該Follower就會變為Candidate,發起新的選舉,嘗試變為leader。

  4. 如果Candidate 收到了大多數的選票,那麼它就“競選”成功,成為leader。但如果多個Follower同時變為Candidate,且它們的選票不相上下,那麼此時就無法決出勝者,RAFT為每輪選舉都設定了超時時間,如果在這段時間內還沒有選出新的leader(election timeout),那麼就會開啟新一輪的選舉過程。

不管是在Follower變為Candidate時的等待時間,還是選舉時的timeout時間,都可能會傳送這樣的情況:不同Follower設定的等待時間或者不同Candidate的timeout時間相同,那麼這一輪選舉超時了,下一輪同樣的Follower又變為了Candidate,相同的timeout時間內還是沒有從這些Candidate中還是沒有選出leader,又進入下一輪…

因此我們在實際中會將Candidate的timeout時間以及Follower的等待時間隨機化,每輪選舉後,每個Candidate都會讓自己的任期號+= 1,這樣我們每輪就可以選擇任期號最大的那個Candidate,減小衝突的機率。此外,發生衝突的選舉後,Candidate間隔下一次選舉的時間也要隨機化。

undefined

上圖中還缺少一點,如果candidate收到了來自leader的心跳包,那麼說明選舉結束了,它會變為follower。

Log Replication

  1. 客戶給leader傳送請求;

  2. leader會給該請求新增一個任期號(term)以及索引(index),使得該請求或命令在日誌中能夠被唯一識別,然後將該請求新增到自己的日誌中;

  3. 並行地給follower傳送AppendEntries RPC,將新的日誌項傳遞給follower。

  4. 當叢集中的大多數follower都追加了該請求後,leader會提交該日誌, 並執行指令改變狀態機的狀態,並返回結果給客戶。它也會透過AppendEntries RPC告訴follower日誌已經被提交,以便讓follower也開始執行指令改變它們自己狀態機的狀態

上述過程的日誌追加可看下圖:

undefined

Practical Byzantine Fault Tolerance (PBFT)

從名字中也可以看出,PBFT被設計用來在有拜占庭錯誤的情況下提供共識。

PBFT包含三個子協議:

  • normal operation:該協議在一切正常,無錯發生的情況下執行

  • view change:在leader節點出錯的情況下執行

  • checkpointing:丟棄系統中的舊資料

PBFT同樣也有三種節點:

  • replicas:每個PBFT協議中的參與者(包括leader和backup)

  • leader:也叫primary,每個輪次都會有一個leader來與客戶通訊,leader不變,則一直為同一個view

  • backup:除去leader外的其它所有節點

如果想要容忍拜占庭錯誤,那麼節點的最小數量應為n=3f+1,也就是說,如果要容忍f個故障,那麼這個系統必須要有n個節點。只要系統中的節點數量保持n≥3f+1,PBFT就可以提供拜占庭容錯。

PBFT協議的執行分為3個階段:

  • Pre-prepare

  • Prepare

  • Commit

Pre-prepare Phases

  1. leader從客戶端接收一個請求;

  2. 為該請求分配對應的序列號,序列號代表著請求被執行的順序;

  3. 將該請求資訊(pre-prepare message)廣播到所有backups備份。

Prepare Phase

  1. backups只會接收之前未接收過的序列號或者不同view對應的pre-prepare訊息;

  2. 將prepare訊息發給所有節點。

Commit Phases

  1. 收到prepare訊息的replica對訊息進行驗證(是否為相同的請求、view以及序列號),直到集齊2f+1個驗證好的訊息;

  2. 廣播commit訊息給所有replica;

  3. 如果集齊2f+1個到達的有效commit訊息,說明決議透過;

  4. 執行該請求/決議

  5. 返回給客戶reply訊息,包含處理結果

下圖為一個在normal operation協議下執行的PBFT基本過程,這是最簡單過程,因為為了達到n≥3f+1的要求,系統中至少需要4個節點。

undefined

關於RAFT演算法的最大容錯節點數量是(n-1)/2,而PBFT演算法的最大容錯節點數量是(n-1)/3 的補充說明: (《深入剖析區塊鏈的共識演算法Raft&PBFT》)

對於RAFT演算法,它只支援容錯故障節點,不支援容錯作惡節點。故障節點就是節點因為系統繁忙、當機或者網路問題等其它異常情況導致的無響應,出現這種情況的節點就是故障節點(也就是我們開頭提到過的誠實節點的故障,Crash failure)。作惡節點除了可以故意對叢集的其它節點的請求無響應之外,還可以故意傳送錯誤的資料,或者給不同的其它節點傳送不同的資料,使整個叢集的節點最終無法達成共識,這種節點就是作惡節點(也就是我們開頭提到過的惡意節點造成的故障,Byzantine failure)。

RAFT演算法只支援容錯故障節點,假設叢集總節點數為n,故障節點數為f,根據小數服從多數的原則,叢集裡正常節點只需要比f個節點再多一個節點,即f+1個節點,正確節點的數量就會比故障節點數量多,那麼叢集就能達成共識。因此RAFT演算法支援的最大容錯節點數量是(n-1)/2。

對於PBFT演算法,因為PBFT演算法的除了需要支援容錯故障節點之外,還需要支援容錯作惡節點。假設叢集節點數為n,有問題的節點為f。有問題的節點中,可以既是故障節點,也可以是作惡節點,或者只是故障節點或者只是作惡節點。如果故障節點和作惡節點都是不同的節點,那麼就會有f個作惡節點和f個故障節點。當發現節點是作惡節點後,會被叢集排除在外,剩下f個故障節點,那麼根據小數服從多數的原則,叢集裡正常節點只需要比f個節點再多一個節點,即f+1個節點,正確節點的數量就會比故障節點數量多,那麼叢集就能達成共識。所以,所有型別的節點數量加起來就是f+1個正確節點,f個故障節點和f個問題節點,即至少需要3f+1個節點。

Metrics of Consensus

IT系統的效能和可擴充套件性一直是用來衡量區塊鏈共識演算法的關鍵非功能性指標。

Performance

Transaction Throughput:

交易吞吐量被定義為區塊鏈網路每秒鐘可以處理的交易(Tx)數量。它可以透過如下公式進行計算:

undefined

其中,Block Time為將一個區塊新增到區塊鏈中所花費的平均時間。

顯然,區塊尺寸越大,吞吐量就越高,而Block Time或者交易規模越大,吞吐量就越小。(固定其餘兩個量)

當交易大小為500 Bytes,Block Time為10s時,吞吐量隨區塊大小變化如下圖所示:

undefined

版權宣告: 本文為CSDN博主「如松茂矣」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。

原文連結:

https://blog.csdn.net/myDarling_/article/details/128142020


文章來源: CSDN博主「如松茂矣」
文章原標題:《 區塊鏈共識機制 (Consensus)(PoW,PoS,PAXOS,RAFT,PBFT)

如有侵權請與我們聯絡刪除。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70012206/viewspace-2933092/,如需轉載,請註明出處,否則將追究法律責任。

相關文章