原文題目:《Tendermint: Byzantine Fault Tolerance in the Age of Blockchains》react
原文做者:Ethan Buchman算法
翻譯:杜滿想緩存
校對:饒雲坤安全
本文爲節選網絡
Tendermint子協議性能
上一章中對Tendermint共識的介紹省略了有關用於廣播區塊(blocks),投票(votes),交易(transactions)和其餘節點信息的gossip協議的一些細節。之因此這樣作是爲了聚焦在共識協議自己,而不讓工程實踐的細節分散注意力。本章講述一種特定的用來填充這些細節的方法,經過把這些組件實現爲相對獨立的反應器(reactors),在這些反應器中每一個對等鏈接(peer connection)是複用的。區塊鏈
P2P網絡優化
在啓動時,每一個Tendermint節點都會收到一份須要撥號的對等節點的初始列表(initial list)。對於每一個對等節點,節點會保持一個持久的TCP鏈接(persistent TCP connection),在該鏈接上以速率受限的方式複用了多個子協議(subprotocols)。消息被序列化爲緊湊的二進制表示,而且經過認證的加密協議對鏈接進行加密。加密
本章的其他部分的每一小節分別描述了一個獨立的反應器,該反應器在每個對等連接進行了複用。有一個額外的對等節點交換反應器(peer exchange reactor),該反應器容許節點彼此請求其餘對等節點地址,並跟蹤它們先前鏈接到的對等節點,以便保持鏈接其餘對等點的最小數量。.net
共識Gossip
共識反應器(consensus reactor)封裝了共識狀態機(consensus state machine),用來確保當每一個節點的狀態發生變化時都向其全部對等節點廣播其當前狀態。以這種方式,每一個節點跟蹤全部對等節點的共識狀態,只發送對等節點此刻須要的信息,或者對等節點沒有的信息,以此來優化消息的gossip過程。對於每一個對等節點,本地節點維護來兩個例程(routine)來不斷檢查發送給對其等節點的新信息,即提議(proposals)和投票(votes)。信息應該以「第一稀有」(ratest first)的原則來最大限度地提升gossip的效率,並儘可能減小某些信息變得不可用的機率。
區塊數據
在上一章節中,假設提議信息是包含區塊的。然而因爲區塊是從一個驗證節點發出的,而且能夠至關大,對於塊提議節點來講把數據上傳到全部其餘節點的方式壓力過大;若是把區塊分紅若干塊後再廣播出去會快不少。
一個經常使用來保證數據被安全廣播的方法,就是利用Merkle樹,此方法也被各類P2P協議所採用,具體方法就是容許每一段數據伴隨一個簡短的證實(原數據的對數級大小),用來證實該片斷是總體的一部分。爲了使用這種方法,根據區塊大小和驗證者的數量,區塊被序列化並分割成適當大小的塊(chunks),塊(chunks)被散列成Merkle樹。被簽名的提議(proposals)再也不包含整個區塊,而是隻包含Merkle的根哈希(root hash),容許網絡經過協做來廣播被分割後的塊(chunks)。節點每次收到塊(chunks)時都會通知它的對等節點,來避免把同一個塊對一個節點傳輸屢次,以此來節省帶寬。
一旦接收到全部塊,就對塊進行反序列化和驗證,以確保它正確地指向前一個塊,而且其各類校驗和(用Merkle樹實現)是正確的。雖然先前假定驗證者在接收到提案(包括塊)以前不預先投票,可是經過容許驗證者在收到提案以後,在接收到完整的塊數據以前進行投票,能夠提高性能。這意味着預先投票到最後證實是無效的塊也是能夠的。無論怎麼樣,對一個無效區塊進行預提交(pre-commit)被認爲是拜占庭行爲。
節點經過接受塊(chunks)的方式同步到最新的高度,以一次一個區塊的方式進行同步(progress one block at a time)。
投票
在共識狀態機中,一個塊被提議之後,節點就會開始等待投票(或者本地計時器過時)以往前推動。若是一個節點恰好進入了下一個區塊高度的狀態下收到一個對上一個塊的pre-commits投票,而這個節點若是同時是這輪區塊的提議者,它也許會把pre-commits投票看成下一個塊的中的LastCommit值存入區塊。若是一個對等節點(peer)已經預投票,但還沒有預先提交,或者已經預先提交,但還沒有進入下一輪,則其被分別發送預投票(pre-votes)或預提交(pre-commits)。若是一個節點是在同步區塊的狀況下,它將會收到在它當前的高度下預提交(pre-commits)。
內存池
交易獨立地在內存緩存中被管理,這個緩存沿用比特幣的叫法就是內存池。交易被業務邏輯驗證合法後加入內存池,並用有序組播算法發送給相鄰節點。一個節點會爲每一個相鄰節點維持一個例程(routine),用來確保發送交易的順序是和本身處理的順序是一致的。
塊提議者會把內存池的有序交易列表中的交易打包進新的區塊。一旦一個區塊被確認提交,區塊中的全部交易都會被從內存池中刪除,而留下來的交易會被業務邏輯從新驗證,由於帳戶中的其餘交易被確認提交,致使它們的有效性也許會改變。
區塊同步
共識反應器(consensus reactor)提供一種相對較慢的區塊同步方法,這是爲了實時共識而設計的,也就是說節點在處理下一個塊以前,會等待接受到全部的信息來確認當下的一個塊。爲了適應一個節點遠落後與當前高度的狀況,有一個區塊鏈反應器(blockchain reactor),這個反應器容許節點同時並行地下載多個區塊,使節點能夠百倍於共識反應器的速度來同步區塊數據。
當一個節點連接一個新的對等節點時,這個對等節點須要把它當前區塊高度發送給對方。節點並行的從全部比本身高度高的對等節點中循序的請求區塊,並下載區塊加入到本身的區塊池(block pool)。另外一個例程不斷嘗試從池中刪除塊並經過驗證和執行將它們添加到區塊鏈中,一次兩個塊,相對於區塊鏈的最新狀態。必須每次同時處理兩個區塊,由於一個區塊的提交確認被包含在下一個區塊的LastCommit字段中。
節點持續的查詢它全部對等節點的當前高度,同時不斷的並行請求區塊,直到同步到其全部對等節點的最高高度,一旦同步到最高高度就會中止請求區塊,並開啓共識反應器。
總結
實現Tendermint區塊鏈涉及不少子協議。這些子協議包括包括gossip區塊數據和交易的共識數據(投票和提議),和新節點快速同步區塊鏈狀態的方法。
相關閱讀: