第三章 共識演算法
3.3 T IMEOUT
3.2.4 Commit
Commit 階段是各節點根據上⼀個步驟的投票結果,判斷是否可以進⾏提交區塊的動 作。
對於節點 u 在第 H ⾼度、第 R 回合會遵守以下規則:
• 收集 Precommit 直到 LocksetPrecommit, H, R, u合法。
• 等待直到 TimeoutPrecommit的時間,讓 LocksetPrecommit, H, R, u蒐集更多
Precommit
。• 如果存在 Quorum(LocksetPrecommit, H, R, u
) = B
,則提交區塊 B ⾄區塊鏈上完成⾼度 H 的共識。
• 如果 Quorum(LocksetPrecommit, H, R, u
)
不存在,則進⼊第⼀階段 Propose 且令回 合為 R+1。3.3 Timeout
共識中的 Timeout 會隨著 R 的增加進⾏指數型成⾧其成⾧公式為:
Timeout
X, R= Timeout
X* TimeoutFactor
R其中 X 為 Propose、Prevote 或 PrecommitTimeoutX則為每個 timeout 在 R=0 的起始值。
此⽬的為讓整個網論在傳遞訊息時可能的延遲不會成⾧的⽐ Timeout 時間還快,讓整 體網路可以處於 partial synchrony 的環境。
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
假設網路中有 F 個節點為拜占庭錯誤節點且整個網路有 N = 3F+1 個節點。當某⼀
節點在第四步驟成功提交⼀個區塊 B 時代表他已經收到⾄少 2F+1 個 Precommit 投給
B,也代表⾄少 F+1 個誠實節點已經有 Quorum(LocksetPrevote
) = B
的共識。在這個狀況 下如果有令⼀個區塊 B’被提交成功代表有另外 F+1 個誠實節點有Quorum(Lockset
Prevote) = B’
,那整個網路就會與先前的假設 N = 3F+1 產⽣⽭盾。3.5 活性(Liveness)
假設有⅓ N 以上的節點存在不同的 Quorum(LocksetPrevote
)
,則 Proposer 所提出的Proposal
VotingInstruction, H, R, u(B)
會指⽰收到此訊息的節點投給其區塊,讓整個網路的Prevotes
收斂⾄其中該區塊。‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
第四章 系統架構
本論⽂透過詳盡研究以太坊提供的開放源碼與徹底理解 Hydrachain 共識演算法,採⽤
重構(Refactoring)的⼿法,就以太坊的架構與演算法的特性實作出模組化的共識引擎。
再依實作過程的發現,反饋與修正現有的共識演算法。並設計效能評估實驗,執⾏效 能評估實驗蒐集實驗數據,檢討實作或架構,進⾏必要的精進步驟以推出具 BFT-like 共識引擎的以太坊版本。⽬前以太坊有許多實作版本,本研究選擇 Golang 版本,稱為 Go Ethereum (geth),是⽬前實作最完善也最多⼈使⽤的版本 ,以下提到的以太坊即指 Go-Ethereum。
4.1 以太坊基本架構
‧
NetWork。其中 BlockChain 實作區塊鏈的核⼼技術包含區塊、區塊鏈、交易與它們的 驗證機制,以及狀態資料庫等實現區塊鏈主要功能的部份。
由於原本以太坊就是以 PoW 為主,包含其共識⽅法、驗證機制原本是分布在不同 的模組底下,包含 Blockchain 模組與 Miner 模組。在 1.6 版本以後,開發⼈員新增了⼀
個 Consensus 模組,讓開發⼈員可以實作不同的共識機制。此模組包含了⼀個共識機 制介⾯,開發⼈員透過實作該介⾯所定義的函式,可以與其他模組溝通。當區塊要進
⾏驗證,或是如何取得共識的內容皆會在此模組底下。 Blockchain 模組或是 Miner 模 組可以透過呼叫共識引擎的介⾯取得該共識機制的演算法。⽬前此模組包含⼯作量證 明機制(ethash)與 Clique。Clique 為⼀種透過授權⽅式進⾏的共識機制,主要⽤於以 太坊的公有測試網路。NetWork 處理節點與節點之間的訊息包括如何傳遞交易、區塊 如何與其他節點同步等。除了上述核⼼架構之外以太坊最重要的⼀項技術即是可以透 過 EVM(Ethereum Virtual Machine) 執⾏智能合約,以便鏈上每個節點執⾏相同程式得 到相同結果,提供使⽤者以智能合約建⽴去中⼼化的應⽤程式。
我們的主要⽬標在於取代以太坊中的⼯作量證明共識機制,改⽤⽐較適合聯盟鏈 需求的 BFT-like 共識演算法。但有鑒於不同類型(偏同步與⾮同步)的 BFT-like 算法 有不同的優缺點,我們透過將 BFT-like 共識演算法實作於 Consensus 模組,建⽴⼀個 新的共識引擎,最⼩化對其他模組的影響。
‧
的 BlockProposal Hash、Height、Round,也包含 Validator 的簽章。l PrecommitVote:當進⾏ Precommit 階段時需要傳遞的訊息結構,表⽰該節 點已經準備進⼊ Commit 階段,PrecommitVote 包含該節點所要提交的 Proposal Hash、Height、Round,也包含 Validator 的簽章。
l Lockset:儲存 Vote 的結構,包含多個 Vote,每個回合會有⼀個 Lockset 去
‧
l PrecommitLockset:儲存 PrecommitVote 的結構,包含多個 Vote,每個回合 會有⼀個 Lockset 去儲存 PrecommitVote。Lockset 也要負責判斷其是否包含 Quorum。
l BlockProposal:BlockProposal 包含⼀個要進⾏共識的區塊、當前進⾏的共 識 Height 與 Round。BlockProposal 可能會包含⼀個 Lockset 或
PrecommitLockset,以證明⾃⼰所提出的 BlockProposal 是合法的。
l VotingInstruction:VotingInstruction 包含⼀個要進⾏共識的區塊、當前進⾏
的共識 Height 與 Round,且也包含⼀個 Quorum 的 Lockset 以證明此區塊已 經經過超過 2/3 以上的節點⽀持。
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
共識,只收到新的區塊卻沒收到該區塊的證明,該節點必須向其他節點要求它看到的 區塊證明,如果的確收到該區塊的證明,則可以將之提交⾄區塊鏈,反之則驗證失 敗。
4.3 共識模組架構
本章節介紹我們實作拜占庭容錯共識的架構與機制。如圖 3.3,共識模組底下包含處理 訊息的 message handler、同步訊息的 synchronizer、與三個主要做共識的模組,
ConsensusManager、HeightManager 與 RoundManager。
‧
引擎需要交換彼此的資訊才能完成共識,所以在引擎中加⼊此 message handler。由於 以太坊在原本使⽤共式引擎的基礎上也有⾃⼰定義的通訊協定,所以此 message 執⾏共識,必須先與其他節點同步到最新狀態,所以需要 Synchronizer 進⾏這動作。透過來⾃其他節點的資訊,判斷⽬前共識進⾏到何階段,
每當有新的區塊需要共識時,區塊會經過三個主要結構完成共識,分別是
ConsensusManager、HeightManager、RoundManager,共識引擎在收到需要共識的區塊 與資訊後,會將區塊交給這三個模組進⾏共識。底下我們介紹這三個共識模組如何完 成共識與其流程,圖 3.3 描述上述幾個模組的互動流程。
• ConsensusManager:
主要功能是管理 HeightManager,以及區塊鏈本⾝與資料庫的各種資訊。
ConsensusManager也負責處理與其他節點交換的各種資訊,再將收到的資訊向下 交給 HeightManager 處理,同時也要將需要廣播的資訊交給 message handler。另外
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
需要傳遞的訊息需要簽章,也是交給 ConsensusManager 執⾏。ConsensusManager 也會判斷該節點的共識是否落後,如果有落後的情況發⽣,會呼叫 Synchronizer,
進⾏同步。
• HeightManager:
此模組主要功能是處理某⼀個⾼度的共識,透過管理⼀或多個 RoundManager 與 其他節點進⾏共識。HeightManager 也要處理來⾃於 ConsensusManager 的訊息,
將訊息交給對應的 RoundManager,或是蒐集各 RoundManager 的資訊,再交給
ConsensusManager廣播或簽章。每個 HeightManager 只負責⼀個⾼度的區塊共 識,當其負責的⾼度共識完成時,ConsensusManager 就會等下⼀個⾼度的共識開 始,在建⽴另⼀個 HeightManager。
• RoundManager:
每個⾼度會需要⼀到多個回合,HeightManager 會建⽴⼀到多個 RoundManager 來 進⾏共識。RoundManager 會蒐集來⾃ HeightManager 的訊息,經過判斷後再廣播 該回合的票 (詳細演算法會在第四章介紹)。
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
Figure 3.3 共識引擎模組關係
我們透過上⾯提到的幾個模組,完成整個引擎的架構。當到⼀個新的⾼度時,以 太坊會透過 miner 模組建⽴⼀個新的區塊,將其傳給 ConsensusManager 開始做共識。
Consensus建⽴該區塊的⾼度的 HeightManager 與 RoundManager 後就可以透過 message handler與其他節點溝通。如果在其間有節點落後,可以透過 Synchornizer 與 message
handler傳遞落後的訊息,讓該節點達到相同的⾼度,以繼續共識。當有共識完成時,
以太坊會發出通知告訴其他節點有新的區塊產⽣,以太坊會呼叫共識引擎判斷該區塊 是法合法,這時由於 BFT 共識引擎必須將該區塊的證明也廣播給其他節點,讓其他節 點也可以驗證該區塊,並將其提交到⾃⼰的區塊鏈上。
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
第五章 實驗結果
本章節包含對我們實作 BFT 共識版本的 geth 進⾏的初步測試。實驗測試皆是在
Amazon EC2 t2.medium實體上進⾏。t2.medium 的硬體規格為 2 個虛擬 CPU 與 4GB 的 記憶體。交易型態則是基本的以太坊轉帳交易。我們以交易的延遲性(latency)與交易的 吞吐量(throughput)來衡量共識的效率。這些指標值的計算要透過⼀些程式來完成。另
⼀⽅⾯我們量測共識演算的延展性 (scalability) 以瞭解當參與共識的節點數量變多的時 候,我們的共識機制的效能會受到怎樣的影響。
5.1 環境建置
⼀開始先將所有節點互相連接,即每個節點都會互相知道彼此的位置。在佈署所有節 點之後,我們先建⽴交易並將交易預先載⼊⾄各個節點,讓產⽣區塊的時候能夠包含 最⼤數⽬的交易。我們改變原本 Go-Ethereum 底下蒐集交易的 Txpool,使其可以蒐集 更多交易(原本交易最多為 4096,改成 12000)。
5.2 吞吐量與共識時間
對於測試基本的交易吞吐量與區塊共識時間的測試,我們預先載⼊ 12000 筆交易,並 且每個區塊都包含⼤約 1000 筆交易,總共進⾏ 12 個⾼度。選擇每個區塊 1000 筆交易 的原因在於 geth 本⾝在建⽴與提交區塊皆需要時間進⾏,在這限制之下我們測試結果
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
圖 5.1、圖 5.2 為此實驗結果。從圖四可以看出在我們的共識演算法之下吞吐量皆 會⾼於原本⼯作量證明機制的吞吐量。在 16 個節點以下的吞吐量都有每秒 600 個交易 以上的速度,但是到了 32 個節點的時候卻降低到每秒 400 個交易以下。
Figure 5.1 節點數 vs 吞吐量
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
Figure 5.2 節點數 vs 延遲時間
5.3 拜占庭容錯測試
除了進⾏效能測試,我們也針對拜占庭錯誤節點進⾏測試,檢視我們系統對於可能的 拜占庭攻擊有的容錯能⼒。
⾸先,我們參考 Tendermint 的測試,設計了幾種可能的攻擊模式:
l Proposer提出不同的候選區塊:當輪到拜占庭攻擊的節點當 Proposer 時,該節點 會提出兩個不同的候選區塊,並且將區塊分別傳給不同節點,意圖將兩個網路分 開。
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
l 不投出 Nil 的票:該節點不會投出任何 Nil 區塊。當有 Proposer 因為網路延遲⽽在 限制時間之後,都還沒提出區塊時,節點可投出 Nil 可以讓共識持續進⾏,保護 網路的持續性。當節點不投出 Nil 可能會阻礙共識進⾏,甚⾄引響活性。
l 贊成每個收到的候選區塊:此種模式下的節點會贊成每個收到的候選區塊,並在 收到候選區塊的當下就廣播該區塊的 Prevote 與 Precommit 給其他節點。
當⼀個節點有上⾯三種攻擊模式之⼀,即是拜占庭攻擊節點。此種節點如果超過 整個網路的 1/3 以上即會造成整個網路癱瘓,無法達成共識。對於此種攻擊測試,我 們在整個網路有 4 個節點,並且讓其中⼀個節點同時有上⾯三種攻擊⽅式,成為拜占 庭攻擊節點。同樣我們預先載⼊ 20000 筆交易,並且每個區塊都包含⼤約 1000 筆交 易,總共進⾏ 20 個⾼度。圖 Figure 5.3 是此實驗的結果,橫軸代表區塊⾼度,縱軸代 表該區塊共識的時間。從圖中可以看出,約每 4 個區塊會有⼀個區塊共識需要⽐較⾧
的時間,⽽造成那些區塊會需要較多時間的原因即是拜占庭節點為 Proposer 時,該節 點送出了兩個不同的區塊試圖分離網路,所以其他節點會需要更多的時間或是回合數
的時間,⽽造成那些區塊會需要較多時間的原因即是拜占庭節點為 Proposer 時,該節 點送出了兩個不同的區塊試圖分離網路,所以其他節點會需要更多的時間或是回合數