日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Tendermint: Byzantine Fault Tolerance in the Age of Blockchains

發布時間:2023/12/31 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Tendermint: Byzantine Fault Tolerance in the Age of Blockchains 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Abstract

Tendermint 是一種在對抗條件下分布式網絡中的新事件排序協議,更常見地被認為是一致性算法或原子廣播。由于廣泛地成功解決了不需中央集權的公共設 置問題在比如比特幣、以太坊的虛擬貨幣領域,這個問題最近吸引了大量關注。 Tendermint 將為了提供一個有問責保障制度的安全一致性協議以及在一致性算 法之上建立任意應用的接口的經典學術工作現代化。Tendermint 是高性能的,每 秒可以在全球數十個節點上以大約一秒的延遲完成數千個交易,并且在面對對抗 攻擊時,性能受到適度降低。

Chapter 1

介紹
今天,計算機工程的殘酷事實是計算機是有缺點的,它們開始宕機,速度變慢,表現越來越差。更糟糕的是,我們傾向于關注把電腦連入網絡(比如互聯網), 然而網絡比計算機具有更高的不可預見性。這些挑戰首要任務是關注“可容錯的 分布式計算(fault tolerant distributed computing)”,來找到有原則的協議設計, 使得當被提供有用的服務時,在錯誤網絡中連接的錯誤計算機保持同步。本質上,就是在不可靠當中生產出一個可靠的系統。
然而,在這個迅速增長的數字化和全球化世界,系統不能僅僅在面對不可靠部分時可靠,還得在面對惡毒環境或“拜占庭(Byzantine)”情況可靠。在過去 十年間,大部分關鍵構造的組件已經被傳送到有網絡支持的系統中,就如同世界 經濟的大量組件。作為回應,則產生了網絡戰爭、經濟詐騙和一個徹底的金融和 政治原則的扭曲。

1.1 比特幣(Bitcoin)

在2009年,一個自稱Satoshi Nakamoto的匿名軟件開發者引介了一種解決這些
問題的方法,就是一個同時進行在計算機科學、金融和政治領域的實驗,一種叫 做比特幣的虛擬電子貨幣。比特幣是第一個用來解決在面對惡性對抗情況下環境 的容錯分布式計算問題的協議。用區塊鏈技術實現了一種數字貨幣,通過經濟激 勵解決哈希碰撞的人,交易(transactions)達成共識。實質上,交易是以區塊的 形式被那些發現數據交易中的部分哈希碰撞的人排序。通過這種方式,正確順序 就是使得碰撞有最高累計難度的那個。這個解決辦法被叫做Proof-of-Work (PoW)。
比特幣的精妙之處在于它發明了一種貨幣,一種加密貨幣,而且發給那些解 決哈希碰撞的人,交換他們做的解決部分哈希碰撞如此昂貴的事情。在精神上,可能假設解決這些問題的能力將會作為計算能力來分發,這樣使得每個人都可以 用一個CPU就能參與其中。不幸的是,比特幣網絡已經成長為這個星球上最大的 超級計算機實體,超過所有其他的總和,僅評估一個單獨的功能,通過幾個數據 中心分發運行主要由一小部分中國公司生產的專有集成電路(ASICs),就要大 概一天消耗兩百萬美元的電力。長遠地看,它的技術設計也有局限性:需要花費 高達一個小時的時間來確定交易,這樣就很難在頂層建立應用,而且無法以一種 維持安全保證的方式來衡量。這還沒有提及由于比特幣社區的不成熟管理機制導
致的內部政治斗爭。
放下這些問題,令人驚訝的是,比特幣和它的技術持續地攪動密碼學和分布式數據庫以及合作經濟,同樣也持續吸引著幾十億的資本投資,包括新公司和新 的加密貨幣,它們都以其獨特的方式從比特幣中分化出來。

1.2 Tendermint

在 2014 年,Jae Kwon 開始開發 Tendermint,一個通過使存在了數十年但是缺少社會背景,直到今天還需要廣泛部署的問題的解決辦法現代化的方法,尋找解 決排序和執行一系列在對抗環境下的交易的一致性問題的辦法。
在 2015 年年初,在一項由 Eris Industries 領導的項目中,把實際區塊鏈解決 方案應用在工業生產中,作者加入 Jae Kwon 開發 Tendermint 軟件和協議。
這次合作的產物就是 Tendermint 平臺,包含一份一致性協議,一個高性能的 Go 語言實現,一個靈活的可以在一致性基礎上建立任意應用的接口,以及一套 部署和管理工具。我們相信,對比之前的方法,Tendermint 完成了一份極好的設 計和實現。以前的方法包括那些經典學術文獻和比特幣及其通過組合每個正確元 素達到安全性、性能和簡單性平衡的衍生物。
Tendermint 平臺是開源的,可以在 https://github.com/tendermint/tendermint 獲得,以及相關的存儲庫在 https://github.com/tendermint。其核心是許可的 GPLv3,大部分的庫都是 Apache 2.0。

1.3 貢獻

這篇文章的主要貢獻參見第三章和第九章。一些重要的意義有: ·一份正式的 Tendermint 的 pi 演算說明書,一份非正式的關于其安全和義務
的正確性證明(第三章)。 ·一個使得其核心一致性狀態機更魯棒,更具確定性和更加易于理解的重構。 ·軟件在正常,錯誤及惡劣環境下大規模部署的性能和特征評估(第九章)。 ·無數的附加測試帶來的無數的 bug 修復和性能提升。 第四到第八章講述了一個完整系統中的很多其他的組件。其中一些,比如用來傳播數據的子協議(第四章)和各種底層軟件庫(第八章),是 Jae Kwon 在 作者加入之前設計并實現的。其余部分是在常規資訊作者和被作者啟發設計與實 現的。對于更多直接詳盡的解釋,請參見 Github。
盡管沒在文章里闡述,作者還在這段時間做了一些以太坊項目的貢獻,一個 比特幣的替代品,概括從貨幣到任意應用的技術的應用。另外,作者被邀請參加 數不清的場合,做關于以太坊和 Tendermint 私下的或公開的演講,包括以指導 人和演講者的身份。
最后一點,盡管第十章被放到了最后,但是如果在第三章之前讀它,它會提 供極其重要的內容并加固理解這篇文章。然而,為了不耽誤讀者認識 Tendermint, 它被放在了最后。

Chapter 2

背景
分布式一致性系統已經成為現代互聯網基礎設施的關鍵組件,在某些水平上, 為每一個互聯網應用提供動力。本章介紹了理解和討論這些系統的必要背景材料。 另外,還介紹了 pi 演算,一個描述并發進程的正式語言,它將在第三章中被用 來闡釋 Tendermint 算法。

2.1 復制狀態機(replicated state machine)

最常見的學習和實現分布式一致性的范例就是復制狀態機。在其中,一個決定性狀態機通過一系列進程被復制,為了使其以一個單狀態機運行,不去管那些 失敗的進程。狀態機由一組稱為交易的輸入驅動,每個交易根據其有效性可能會 或可能不會導致狀態轉換并返回結果。更正式地說,一個交易就是一個數據庫原 子操作,意味著它要么完成,要么就沒發生,不會出現中間狀態。狀態轉移邏輯 由狀態機的交易函數控制,映射一個交易和當前狀態到一個新的狀態和返回結果。 狀態轉移函數有時也會被指向為應用邏輯。
交易排序是一致性協議的職責,這樣,產生的交易日志剛好被每個進程復制 一遍。使用一個決定性的狀態轉移函數意味著每個進程將計算由相同交易日志提 供的相同狀態。
圖 2.1 給出了復制狀態機架構的總覽。
Tendermint 從渴望創造一個通用的,高性能的,安全的,以及魯棒的復制狀 態機中獲得激發。

2.2 異步性(asynchrony)

容錯復制狀態機的目的是協調一個計算機網絡,當提供有用的服務時保持同步,盡管存在那些錯誤。
保持同步相當于成功地復制交易日志;提供有用的服務相當于保持狀態機對于新交易可用。系統這兩方面在傳統上分別被認知為安全性(safety)和活性 (liveness)。通俗地講,安全性意味著沒有壞事情發生;活性意味著好事情終 將發生。違背安全性導致兩個或更多有效的相互矛盾的交易日志。違背活性導致 無響應的網絡。
通過接受所有交易可以很容易滿足活性。通過不接受任何交易可以很容易滿 足安全性。因此,狀態機復制算法可以被看見地操作在一個由這些極端條件定義 的范圍內。典型地,進程需要在提交新交易之前接受從其他進程得到的信息的閾值。在同步環境中,我們做出網絡消息延遲的最大值或者處理器速度的最大值的假設,那就足夠容易去輪流提出新交易,贊成得到大多數投票的提出者,跳過沒有在假設的限定內提議的提議者的回合。
在異步環境中,在沒有網絡延遲和處理器速度保障的情況下,交易變得特變 難于管理。實際上,所謂的 FLP 不可能結果(FLP impossibility result)論證了在 一個異步的分布式系統中,即是只是容忍一個進程的錯誤,也不存在一個一致性 算法可以保證正確性。因為進程可以失敗,證據相當于顯示了存在協議的有效執行,在恰好的時機進程失敗來阻止一致性。因此,我們不能保證一致性。
典型地,一個協議的同步性由使用超時反射來管理特定的轉變。在異步環境,消息可能會反復延遲,依賴同步(超時)安全會導致在交易日志中的分歧。依賴同步來確保活性會引起一致性停止和服務無響應。前一種情況通常被認為更嚴重, 因為調節沖突日志是令人頭疼甚至無法完成的任務。
實際上,同步的方法只應用在消息延遲極其好控制的情況下,比如在同一架 飛機上的控制員之間,或者利用同步原子鐘的數據中心之間。因此,雖然存在許 多有效的同步解決方案,但是計算機網絡的一般不可靠性對于在沒有顯著的額外 成本的實踐中來說,風險太大。
根本上,有兩個方法可以克服 FLP 不可能性結果。第一個是使用更有力的同步假 設,即使弱一點的假設已經很充分了。比如說,只有在最終的時候,崩潰的進程 會被懷疑會崩潰,正確的則不會。典型地,這種方法利用那些扮演特定協調角色 的,還有那些如果在超時后被懷疑會出錯被跳過的領導者們。實際上,這種領導者選舉機制很難正確。
第二種克服 FLP 的方法是使用非決定論,包含隨機因素,從人的直觀上來說, 可以克服 FLP,原因就是大概率上,是可以達成一致的。聰明地,依賴隨機會顯著降低速度,盡管某些高級的密碼編寫的技術最近幾年在速度上取得了極大的提升。

2.3 廣播和一致性

為了使一個進程可以在其他進程上復制自己的狀態,它必須有權限進入允許它傳播或者傳送信息的基本通信基元(primitives)。一個最有用的這種基元之一 就是可靠廣播(reliable broadcast)。可靠廣播(RBC)是一個基元,對于消息 m, 滿足:
·有效性(validity)-如果一個正確的進程廣播 m,它最終會傳送 m
·一致性(agreement)-如果一個正確的進程傳送 m,所有正確的進程最終都會傳送 m
·完整性(integrity)-m 只會被傳送一次,而且只在被自己的發送者廣播的時候
本質上,RBC 使得一條消息最終被所有的正確進程傳送一次。
另一種更有用的基元原子廣播(atomic broadcast – ABC),滿足所有 RBC 的屬性和一條額外的屬性:
·總序性(total order)-如果正確進程 p 和 q 傳送 m 和 m’,則如果 q 在傳送 m’前傳送 m,p 就在傳送 m’前傳送 m
當值在每個主機上以相同的順序傳送,原子廣播也是一個可靠廣播。注意這 一點恰好是復制一條交易日志的問題所在。通俗地說,這個問題會被歸諸于一致性(consensus),一致性基元的標準定義滿足一下要求:
·終止性(termination)-每個正確進程最終都會決定 ·完整性(integrity)-每個正確進程最多決定一次
·一致性(agreement)-如果一個正確進程決定 v1,另外一個決定 v2,則 v1 = v2
·有效性(validity)-如果一個正確進程決定 v,則至少是有一個進程提議了 v
直觀地看,consensus 和 ABC 驚人的相似,最不同的地方就在于 ABC 是連續的協議,而 consensus 需要有終止。也就是說,被人們所知的,它們都可以簡化成彼此。consensus 可以很容易地通過決定第一個值為原子廣播來簡化為 ABC。 ABC 可以依次地運行一致性協議的多個實例來簡化為 consensus,盡管某些微妙的事項一定要注意,尤其那些用來處理拜占庭錯誤的。圍繞 ABC 簡化為 consensus 的參數空間的一個完整描述依舊是一個開放的研究話題。
從歷史來看,盡管大部分用例實際上需求 ABC,但是最廣為被采納的是一個 用 Leslie Lamport 在 90 年代引入的,也被證實是正確的一致性算法,Paxos。Paxos 同時即允許又拒絕一致性科學(consensus science)的準則。一方面,它提供第一次真實世界(first real-world)、實際的、容錯的一致性算法,另一方面,卻又 十分的難以理解和解釋。該算法的每種實現都使用了自己的專門的技術包從 Paxos 建立 ABC,使得整個生態系統難以操縱、理解、利用。遺憾的是,盡管在針對不同困難去尋找解決方案付出了很多努力,但是想使其更容易被理解,幾乎 沒有取得任何進展。
2013 年,Ongaro 和 Ousterhout 發表了 Raft,一個激發設計目的非常易懂的 狀態機復制算法。Raft 的設計不是從一致性算法出發并試圖建立它所需的(ABC), 它最先也是最重要考慮的是交易日志,并尋找可以組合在一起最終能提供 ABC 的正交組件,雖然它不是被描述成這樣的。
Paxos 已經成為行業內主要的一致性算法,超過像 Amazon,Google 等公司, 其他也已經建立起了具有高可用性的全球互聯網服務。Paxos 一致性算法位于應 用棧的最底層,提供一個統一的資源管理和分配的接口,操作時間尺度比用戶面 對的具有高可用性的應用更慢。
然而,自問世以來,Raft 已經被廣泛采納,尤其是在開源社區,幾乎被每種 主流語言所實現,并且在主要項目作為骨干使用,包括 CoreOs 分布式 Linux 發行 版,以及開源時間序列數據庫,InfluxDB。
Raft 從 Paxos 來的主要不同的設計決策是要首先關注于交易日志,而不是一 個單獨的值,特別是要讓一個領導者堅持提交交易直到他傳下去,也就是領導選 舉開始生效的時候。在某種程度上,這和區塊鏈采取的方式很相似,雖熱區塊鏈 的最主要優勢在于它容忍不同錯誤的能力。

2.4 拜占庭容錯 Byzantine Fault Tolerance

由于區塊鏈通過在一個共享的數據庫上分發責任來降低交易對手風險的方式,它們已經被認為是“可信任的機器(trust machines)”。特別是比特幣,已經被 注意到它承受其他參與者攻擊和惡性行為的能力。習慣上,一致性協議對惡性行 為的容忍被作為拜占庭容錯(BFT)一致性協議。使用拜占庭一詞是因為與拜占庭將軍們面對的問題很相似,當將軍之中有一個可能是叛徒的時候,他們嘗試只用信使來協作攻打羅馬。
在一個宕機故障中,一個進程很簡單地終止掉。在拜占庭故障中,它可能反 復出現。宕機故障比較容易處理,因為沒有進程會對其它進程撒謊。只容忍宕機故障的系統可以通過簡單的多數原則來處理,因此通常容忍高至半個系統的同步 失敗。如果系統能容忍錯誤的數量是 f,這樣的系統必須至少有 2f + 1 個進程。
拜占庭故障更復雜一些,在一個有 2f + 1 個進程的系統里,如果有 f 個進程是 拜占庭,它們可以協作對其他 f + 1 個進程說任意的事情。舉個例子,假設我們 要試著在一個單獨的比特的值上面達成一致,f = 1,所以我們一共有 N = 3 個進 程,A,B,C,其中 C 是拜占庭,如圖 2.2 所示。C 可以告訴 A 值為 0,告訴 B 是 1。如果 A 同意是,B 同意是 1 的話,它們就都會認為自己得到多數答案,并 且提交它們,至此,就違背了安全條件。因此,拜占庭系統的容錯邊界要嚴格 地比非拜占庭系統低。
實際上,可以看得出來拜占庭故障 f 的上限應該是非 f < N/3。因此,容忍一 個單獨的拜占庭進程,我們需要至少 N = 4 個進程。這樣,故障進程就不會把它 的票以不同的答案分給所有其他進程,如圖 N = 3 那樣。
在 1999 年,Castro 和 Liskov 發表了 Practical Byzantine Fault Tolerance,也稱作 PBFT,它提出了第一個實際使用中的拜占庭容錯優化算法。它為工業上處理以每秒上萬條為度量的交易量的系統的拜占庭容錯在實際應用上開創了先例。放下這些成就不說,拜占庭容錯仍然被認為是昂貴的并且很大程度上是不必要的,而且最受歡迎的實現方法是很難建立在頂層上的。因此,盡管在學術興趣上有所復興,包括大量改進過的變種,在實現和部署上,并沒有很大的進展。此外,PBFT 不會提供任何保證是否有三分之一或更多的網絡協調者違反了安全性原則。

2.5 密碼學,信任,經濟學

根本上,容錯是一個源自信任(trust)缺失的問題—一個掌握其他進程如何
表現的能力。正式地,信任可以由信息理論定義為一種降低某個人的世界模型的 熵的方法—信任某人就是樂觀地降低這個人對這個世界的不確定性,使其把更多 的注意力放在更高的組織形式的秩序上。
加密原語(Cryptographic primitives)同樣也是在根本上與信任問題相關聯,而且也可以類似地被定義為一種允許大幅降低熵的機制—成功驗證一個加密的函數會把一個分布式可能產生的結果瓦解成單個,在某些情況也可能會變成一小部分數量的結果。
眾所周知,一個有著更高形式制度信任的文明,比如法律制度,有更高的生產力和更有生氣的經濟。這個結果給出直觀的感覺就是可以更容易的協調,比如更多地信任一個互動可以降低需要被積極建模的可能輸出結果的空間。遺憾的是,評估現代機構的可信度變得越來越難,因為在最近幾十年來它們的復雜度飛速增長,也增加了它們所提供的確定性是一種假象的可能性。
幸運的是,密碼學可以形成新的社會信任機構的基礎,這可能會因為欺詐和/或不負責任的活動的風險降低,而在全球范圍內大大提高人力協調能力。特別感興趣的是加密原語在 BFT 算法中的重要性,既用于認證也用于播種非確定性。
最有趣的是,經濟機制也可以作為減少熵的手段,只要經濟主體能被激勵 - 這就是說更有可能執行某種特定的行為。事實上,比特幣的深刻見解是,加密原 語可以與經濟激勵一起使用,以便能夠有效地減少公共一致性網絡的熵來實現狀 態的安全復制。
一個對信息理論的信任,密碼學,一致性,經濟,尤其是它們的內部關系的更正式探索,仍然是未來需要做的工作。

2.6 區塊鏈

一個區塊鏈的核心是一個以拜占庭容錯原子廣播為基礎的專注完整性的方法。比如比特幣區塊鏈,使用經濟學和加密隨機化的組合來提供強烈的概率保證不會違反安全性,給出一個弱同步假設,區塊據說比通過部分哈希碰撞彩票找到的數據塊快得多。然而,實際上,眾所周知,比特幣的安全保障容易受到一些微妙的攻擊。
區塊鏈是從其在解決 ABC 中使用的兩個關鍵優化獲得的名稱。第一個是它把交易分成區塊(blocks)以便在許多交易中分攤延遲(大約十分鐘)。第二個是將區塊通過加密哈希鏈接到一個不可變的鏈,這樣可以很容易驗證歷史記錄。這兩個優化都是對原始 BFT-ABC 的天然改進,前者改進了性能,后者改善了某些難以建模的拜占庭故障的容忍度。
在過去幾年中,“區塊鏈化”一致性算法已經變得很普遍,也就是使用哈希鏈接交易批次的區塊鏈模型來適應 ABC。 據作者所知,Tendermint 是第一個這樣的提案,從 80 年代后期升級了一個眾所周知的 BFT 算法,盡管它已經演變成了一個自己的一致性算法。隨后,IBM 將 PBFT 升級成為一個區塊鏈,然后摩根大通升級了一個 Raft 的 BFT 版本。

2.7 進程演算

那些部分系統要同時和其他系統一起執行的分布式系統一直因為它們難于設計,構建,調試而被人詬病。因為大部分需要被正式認證的技術和計算機科學的基礎已經由順序計算特定開發,所以它們很難被正式認證。
進程演算是被引入提供并發式計算正式基礎的一系列模型。最流行的演算,通信順序進程 Communicating Sequential Processes (CSP) 為許多現代編程語言提供了理論基礎,比如 Go,在設計語言時就包含了并發原語。
在 80 年代,Robin Milner 推出了通信系統演算 Calculus of Communicating Systems (CCS),被設計為順序 lambda 演算的并發類似物,成為大部分函數式編 程語言的基礎。雖然 lambda 演算有功能應用程序作為其基本計算單位,但 CCS 使用共享通道上的兩個并發進程之間的通信作為其基本操作原語。CCS 的更一般形式是 pi 演算,使得進程之間的通信圖中的移動性能夠使得通信信道本身可以 沿其它信道傳遞,從而模糊數據,變量和信道之間的區別。這個結果是一個比前任更強大的連貫簡約的計算模型。
Pi 演算已被證明是研究并發系統的高效工具,其應用從業務流程管理到細胞 生物學。非常簡單的注解簡化了并發協議的描述。此外,眾所周知的計算和邏輯 之間的等價性使得可以將邏輯系統定義為與各種進程演算的補充,提供正式的方 式來討論和驗證在適當的演算中指定的系統的屬性。
我們對 pi 演算的描述只能指定 Tendermint 算法。 一個簡單的 pi 演算以 Backus-Naur 形式的語法如下表示:

每個語法規則都以其功能意義的參考為標記。一個進程可能是空的進程,0。 它可能是兩個進程的并行組合,P | P 表示同時運行的兩個進程。一個被保護的 進程,α.P,只允許進程 P 在動作α發生后執行。這個動作可以是空動作,τ, 或者是 y 沿 x 的發送,x!(y),或接收,x?(y)。保護的選擇將非確定性注入到演算 的運算中,使得進程α.P + β.Q 將不確定地執行α或β,然后分別運行 P 或 Q。
可以通過(vx)P 創建一個新的通道 x,這樣 x 只能在 P 中訪問。函數形式 Fs(y)允許我們將變量 s 和 y 傳遞到一個可能導致自身執行遞歸的 F 進程中。通常,我們讓 s 是像狀態一樣的變量,而 y 是演算中的通道。最后,由于我們感興趣的是異步網絡的一致性,我們采用被認為是不可靠的故障檢測器的超時的抽象,并將其建模為非確定性動作。當進程 i 被懷疑失敗(即在一些超時后),suspi 動作就被觸發了。
注意一點,我們可以使用ΣP 表示超過兩個進程的守衛選擇,ΠP 表示兩個以 上進程的并行組合。我們也承認發送和接收的多種形式,比如,x?(v, w) | x!(y,z) 等同于 x?(d).d?(v).d?(w) | (vc)x!?.c!(y).c!(z)。
操作語義定義了進程可能執行的實際不可逆的計算步驟。有效的是,唯一相 關的操作是通信,稱為 comm 規則:
(x?(y).P | x!(z)) → P{z/y} (2.1)
符號 P{z/y}表示 P 中所有出現的 y 都被替換為 z。換句話說,z 被發送到 x 上,以 y 的形式接收,并被饋送到 P。
給定一個 pi 演算過程,我們可以通過應用 comm 規則來執行它。舉個例子,
(x?(y).y!(x) | x!(z)) → z!(x) (2.2)
現在,我們可以使用一個形式的邏輯來表達進程可能滿足的屬性。例如,模 態的 Hennessy - Milner 邏輯可以表示一個過程將在一些或所有形式的行動發生之 后滿足一些其他邏輯表達。通過將更復雜的運算符添加到邏輯中,可以構建形式 化的系統,其可以容易地描述分布式系統的重要屬性,例如安全性、活性和本地
化。用 pi 演算寫的系統之后可以被正式驗證來用模型檢查軟件滿足相關屬性。 雖然我們使用 pi 演算來指定 Tendermint 算法,但是我們仍將使用相關的形式邏輯,以及相應的屬性驗證,以供將來使用。

2.8 Tendermint 的需求

比特幣及其衍生物尤其是以太坊的成功,還有它們對任意代碼的安全、自主、分布式、容錯執行的承諾,使得這個星球上幾乎所有的主要金融機構都對區塊鏈 現象產生了興趣。特別是對兩種形式的技術有了一種了解:一方面是公共區塊鏈, 被親切地稱為大壞的公共區塊鏈或 BBPBs,后者的協議以原生貨幣為基礎的經濟 激勵為主。另一方面是所謂的私有區塊鏈,或者可能應該更準確地被稱為“財團 區塊鏈”,通過使用哈希樹,數字簽名,P2P 網絡和增強功能有效地改進了傳統 的一致性算法和 BFT 算法。
隨著我們社會的基礎設施越來越分散,隨著業務的性質變得更加組織化,越 來越需要一個透明,負責任,高性能的 BFT 系統,可以支持從融資到域名注冊到 電子投票的應用,并配備先進的治理機制和未來的演變機制。Tendermint 是針 對財團或組織間邏輯進行優化的解決方案,但足夠靈活,可以容納任何從私營企 業到全球貨幣的解決方案,以及足以與當今主要的非 BFT 一致性算法解決方案例 如 etcd,consul 以及 zookeeper 進行競爭的高性能,同時為應用程序開發人員提 供更大的彈性,安全保證和靈活性。

Chapter 3

Tendermint 一致性算法(共識算法)
這章講解了 Tendermint 一致性算法和一個相關的原子廣播區塊鏈。詳細描述了 BFT 一致性問題,在 pi 演算中給出了 Tendermint 一致性算法的正式規范。 Tendermint 區塊鏈被非正式地證明可以滿足原子廣播。我們將其留在將來的工作中,以便在進程演算中捕獲完整的區塊鏈協議并驗證其屬性。

3.1 Tendermint 總覽

Tendermint 是區塊鏈模型中的安全狀態機復制算法。它提供了一種 BFT-ABC的形式,使得更加負責任—如果安全性被違反,總是可以驗證出是誰的惡意行為。 Tendermint 從一組驗證者開始,通過其公鑰識別,每個驗證者負責維護復制 狀態的完整副本,并提出新的區塊(交易批次),并對其進行表決。每個區塊被分配一個增量索引或高度,使得有效的區塊鏈在每個高度只有一個有效的區塊。 在每個高度,驗證者輪流提出新的區塊,這樣在任何輪的時候最多只有一個有效的提議者。由于網絡的不同步,可能會花費多輪來提交給定高度的區塊,如果三分之一或更多的驗證者離線或分區,則網絡可能完全停止。驗證者在區塊提交之 前進行兩個階段的投票,并遵循一個簡單的鎖機制,防止不到三分之一的驗證者 的任何共同惡意損害安全性的行為。
要注意的是,輪流投票機制的核心是一致性算法,它是捆綁一起組成區塊來 產生原子廣播。每個塊都包含一些元數據,稱為它的頭,其中包含前一個高度的 區塊的散列,產生一個哈希鏈。頭里還包括區塊高度,區塊被提出的當地時間, 以及包含在區塊中的交易的 Merkle 跟散列。
3.2 一致性算法
一致性算法可以大致分為以下幾種幾何正交組件: ·提議(proposals):每個輪次必須由正確的提議者提出一個新的區塊,并
向另一個驗證者進行傳播。 如果沒有在足夠的時間內收到提案,則應跳過該提 案者。
·投票(votes):必須進行兩個階段的投票,以確保拜占庭的最佳容錯能力。 他們被稱為預投票(pre-vote)和預提交(pre-commit)。 在同一輪中,來自同 一區塊的三分之二以上驗證者的一組預提交是一次提交。
·鎖(locks):Tendermint 確保沒有兩個驗證者在相同的高度處提交不同的 區塊,假設不到三分之一的驗證者是惡意的。這是通過一種鎖機制實現的,該機 制決定驗證者如何根據在同一高度上先前的預投票和預提交來預投票和預提交。 要注意的是,這種鎖機制必須仔細設計使其不損害活性。
為了給單獨的拜占庭故障提供容忍,一個 Tendermint 網絡必須包含最少四個 驗證者。每個驗證者必須具有用于產生數字簽名的非對稱加密密鑰對。驗證者從 共同的初始狀態開始,其中包含驗證器的有序列表 L。每個驗證者都通過其公鑰 進行識別,所有提案和投票必須由相應的私鑰簽名。這可以確保任何觀察者總是 能夠對提案和投票進行驗證。假設多達三分之一的驗證者是惡意的,以任意方式 合作顛覆系統安全或活性的,是非常有幫助的。
一致性算法始于第零輪,第一個提議者就是 L 中第一個驗證者。一輪的結果 是做出提交,或決定轉入下一輪。新一輪是下一個提議者。使用多輪可以給驗證 者多次機會在網絡異步或驗證失敗的情況中達成一致。與需要一種領導選舉形式 的算法相反,Tendermint 在每一輪都有一個新的領導者(提議者)。驗證者與投 票接受該提議相同的方式跳到下一輪,提供給協議一個統一的,在明確的領導選 舉程序算法中缺席的機制。
每一輪的開始對同步性的依賴性很弱,因為它利用本地時鐘來決定何時跳過 提議者。 也就是說,如果驗證者沒有在本地估量的進入新一輪的“超時提議 (ProposalTimeout)”中收到提議,則可以投票以跳過提議者。在這種機制中固 有的是一個弱同步的假設,即該提議最終將在“超時提議(ProposalTimeout)” 中傳達,該延遲本身可能會隨著每一輪的進行而增加。這個假設將在第十章中有 更全面的討論。
在提案之后,回合以完全異步的方式進行 - 驗證者只有在至少三分之二的驗 證者聽取之后才能繼續進行。這減輕了對同步時鐘或有界網絡延遲的任何種類的 依賴,但是這意味著如果有三分之一或更多的驗證者無響應,網絡就將停止。異 步投票緊接著這個弱同步提議的流程,如圖 3.1 所示。
為了安全地跳過回合,引入了一些鎖的規則,迫使驗證者證明他們的投票是 合理的。 雖然我們并不一定要求他們實時廣播其理由,但我們希望他們保留數 據,以便在安全受到足夠的拜占庭故障的影響的情況下將其作為證據。這種問責 機制使得 Tendermint 能夠在面臨這種失敗的情況下提供比例如,如果第三個或 更多的驗證者是拜占庭的話就不會提供保證的 PBFT,更有力的保證。
驗證者使用不同的消息集進行通信,以管理區塊鏈,應用狀態,對等網絡和 一致性。 然而,一致性算法的核心只包含兩條消息:
·提議消息(ProposalMsg):由提議者簽字的給定高度和回合的區塊的提議。 ·投票消息(VoteMsg):一個簽過字的提議的投票。 實際上,我們使用額外的消息來優化區塊數據和投票的傳播,這會在第四章
進行討論。

3.2.1 提議(Proposals)

每一輪都以提案開始。給定輪次的提議者從本地緩存中(Mempool,參見第四章)拿到一批最近收到的交易,組成一個區塊,并廣播包含該塊的簽名的 ProposalMsg。 如果提議者是拜占庭,則可能會向不同的驗證者廣播不同的提議。
提議者通過一個簡單的,確定性的輪次排序,所以只有一個提議者對于給定 的回合是有效的,每個驗證者都知道誰是正確的提議者。如果收到低輪次的提議 或錯誤的提議者的提議,它將被拒絕。
對于拜占庭容忍來說,循環提出建議是必要的。比如在 Raft 中,如果當選的 領導者是拜占庭,并且與其他節點保持強大的網絡連接,則它可以完全破壞系統, 破壞所有的安全性和活性的保證。Tendermint 通過投票和鎖機制保證安全性,并 通過循環提議保證活性,所以如果一個提議者不處理任何交易,其他的也可以繼續。也許更有趣的是,驗證者可以通過治理模塊(參見第 6 章)投票去除或替換 拜占庭驗證者。

3.2.2 投票(votes)

一旦驗證者收到一份完整的提議,它就會為該提議進行預投票并將其廣播到網絡。 如果驗證者在 ProposalTimeout 中沒有收到正確的提案,則會投 nil 票。 在與拜占庭驗證者的異步環境中,單個投票階段每個驗證者只投一票,是不足以 確保安全性的。實質上,由于驗證者可以說謊,而且對消息傳送時間沒有保障, 一個流氓驗證者可以協同一些別的驗證者提交一個值,而其他驗證者并沒有看到 這次提交就進入下一回合,在這個回合它們會提交不同的值。
單一的投票階段允許驗證者告訴對方他們對提案的了解。但是,為了容忍拜 占庭故障(其實質上是謊言,欺詐,欺騙等),他們還必須告訴對方他們知道哪 些其他驗證者已經宣稱對提議的了解。也就是說,第二階段確保足夠的驗證者見 證了第一階段的結果。(*這個就是為什么需要三步提交的原因。per-vote 階段: 請求投票,并收集起他人的投票。commit 階段,每個人收集到其他三分之二的 人的投票,就認為自己已經見證了這次投票,發送 pre-commit 消息,然后,收 集到足夠的 per-commit 的消息,就認為 commit 成功了。也就是一次是發起投票, 一次是足夠的人見證了這次投票。)
因此,區塊的預投票也是網絡準備提交區塊的投票。為 nil 的預投票是網絡準 備進入下一輪的投票。在一個在線提議者的理想回合中,超過三分之二的驗證者 將會為提議預投票。在給定回合的單獨區塊的一組超過三分之二的預投票被稱作 polka。單獨區塊的一組超過三分之二的為 nil 的預投票被稱作了 nil-polka。
當一個驗證者接收到一個 polka(也就是一個單獨區塊的超過三分之二的預投 票)時,它已經收到一個網絡已經準備好提交區塊的信號,它作為驗證者對該區 塊進行簽名和廣播預提交投票的理由。有時,由于網絡異步,驗證者可能不會接 收到 polka,或者可能就沒有。在這種情況下,驗證者在為該區塊簽字預提交是 不合理的,因此必須為 nil 簽署并發布預提交的投票。也就是說,在沒有 polka 的理由的情況下簽署預提交是一種惡意行為。
一次預提交實際上是提交一個區塊的投票。一次對 nil 的預提交實際上是進入 到下一輪的投票。如果一個驗證者接收到一個區塊的超過三分之二的預提交,它 將提交該塊,計算結果狀態,并在下一個高度移動到回合 0。如果驗證者收到超 過三分之二的 nil 預提交,則轉到下一輪。

3.2.3 鎖(locks)

確保輪次的安全性可能是棘手的,因為必須避免將為同一高度的兩個不同輪次的兩個不同的區塊提供合理性這種情況。在 Tendermint 中,這個問題是通過 圍繞 polka(即相同的區塊的三分之二以上的預投票)的鎖機制來解決的。實質 上,一次預提交必須由 polka 證明,而且一個驗證者會被認為在上一個它提交的 區塊上鎖住。鎖有兩條規則:
·Prevote-the-Lock:驗證者必須對他們被鎖定的塊進行預投票,如果它們是 提議者,則提出它。這防止驗證者在一輪中預先提交一個區塊,然后在下一輪中 為一個不同的區塊提供 polka,從而危及安全性。
·Unlock-on-Polka:一個驗證者只可以在一輪看到的 polka 比它鎖定的那輪的 polka 大之后才可以釋放鎖。如果驗證者預提交那些網絡其余部分不想提交的東西,這允許它們釋放鎖,從而保護活性,但是不損害安全性。如果有一個在驗證 者鎖定那輪之后的一輪的 polka,只允許解鎖。
為了簡單起見,驗證者被認為在每個高度的回合-1 處都被鎖定在 nil,所以 Unlock-on-Polka 意味著驗證者直到看到 polka 才能在新的高度預提交。
通過實例可以更直觀地理解這些規則。考慮四個驗證者 A,B,C,D,并且假 設在第 R 輪有一個對區塊 X 的提議。假設有一個區塊 X 的 polka,但是 A 沒有看 到它,并且預提交為 nil,而其他的則預提交區塊 X。現在假設唯一一個看到所有 預提交的是 D,而其它則說沒有看到 D 的預提交(它們只看到它們的兩個預提交, 和 A 的 nil 預提交)。D 現在將提交區塊,而其它的則進入 R + 1 回合。因為任何 驗證者都可能是新的提議者,如果他們可以提出并投票支持任何新的區塊,比如 區塊 Y,那么他們可能提交它并連累安全性,因為 D 已經提交了區塊 X。請注意,這里甚至沒有拜占庭行為,只是因為異步性!
鎖機制通過強制驗證者堅持使用它們預提交的區塊來解決問題,因為其他驗 證者可能已經基于它們所預提交的提交了(如本例中 D 所示)。實質上,在一個回合中一旦超過三分之二預提交一個區塊,網絡就被鎖定在該區塊上,也就是說,在更高的輪次上一定不可能為一個不同的區塊生成一個有效的 polka。這是 Prevote-lock 的直接動機。
然而,Prevote-the-Lock 是不夠的。必須要有一種方式來解鎖,以免我們犧牲 活性。考慮這樣的一個回合,其中A和B預提交區塊X,而C和D預提交nil- 分立投票。他們都轉到下一輪,并且提出了 C 和 D 所預投票的區塊 Y。假設 A 是拜 占庭,并且為 Y 塊預投票(盡管被鎖在區塊 X 上),從而得到一個 polka。假設 當 A 離線,C 和 D 預提交區塊 Y 時,B 沒有看到 polka 并且預提交 nil。他們移動 到下一輪,但 B 仍然鎖定在區塊 X 上,而 C 和 D 現在被鎖定在區塊 Y 上,并且 由于 A 離線,它們永遠不會得到 polka。因此,我們以不到三分之一的拜占庭驗 證者(這里只有一個)連累了活性。
解鎖的明顯理由是 polka。一旦 B 看到區塊 Y 的 polka(C 和 D 之前為區塊 Y 驗證的它們的預提交),它就應該可以解鎖,因此提交區塊 Y。這是 Unlock-on-Polka 的動機,如果他們在一輪中看到一個比他們鎖定的那輪更大的 polka,它則允許 驗證者解鎖(并預提交一個新的區塊)。

3.2.4 正式規范

既然我們已經詳細解釋了這個協議,我們現在提出 pi 演算的正式規范。 使得 ∏ 表示一組 N 個驗證者的一致性協議,每個都互相
執行互不相容的一組進程中的一個,Yi。內部狀態 S = {r, p, v}由一個嚴格增加的 回合,r,一個提議,p,組成,包含這輪提議的區塊;和一組包含所有輪的所有 的投票組成。我們在第 r 輪分別用 和 表示一組預投票和預提交,我們讓 vote :: v 表示集合{vote}和 v(即,添加到 v 的 vote)的并集。我們定義 proposer? = r mod N 作為第 r 輪提議者的索引。 我們在協議的特定點表示一個對等體為 。在PRi,PVi,PCi 范圍內的進程 Yi,分別表示提議(proposal),預投票(prevote), 預提交(precommit)的縮寫。我們引入 PV 和 PC 的附加子功能來捕獲 PV1,PV2 等的遞歸。
對等體使用廣播信道連接每個消息類型,即,proposei,prevotei 和 precommiti, 以及用于決定或提交值 di 的渠道。通過大量用這些符號,可以通過 xxxi 上的每個 進程接收廣播頻道 xxxi 上的單個發送。
我們只使用兩種信息類型:提議和投票。每個都包含一個回合號,區塊(哈 希)和簽名,表示為 msg.round,msg.block,msg.sig。注意,我們可以將簽名吸 收到廣播頻道本身,但是我們需要使用它作為拜占庭行為的證據。
該規范分為兩部分,即圖 3.2 和 3.3。

3.3 區塊鏈(Blockchain)

Tendermint 一次性操作交易的批次或區塊。通過將每個區塊通過其加密哈希明確地鏈接到它之前的一個區塊,從而將一個區塊維持到下一個區塊,從而形成區塊鏈。區塊鏈包含有序交易日志和驗證者提交區塊的證據。

3.3.1 為什么用區塊?

一致性算法通常通過設計一次提交交易,并在其發生之后實現批處理。正如第二章中提到過的,從批量原子廣播的角度解決問題,主要得到兩個優化方式,這給我們提供了更多的吞吐量和容錯能力:
·帶寬優化(bandwidth optimization):由于每次提交都需要所有驗證者之 間進行兩輪通信,所以區塊中的批次交易會分攤區塊中的所有交易的提交成本。
·整體性優化(integrity optimization):區塊的哈希鏈形成一個不可變的數 據結構,很像 Git 倉庫,可以在歷史記錄中的任何一個位置對子狀態進行確定性檢查。
區塊也產生另一個效果,這是更微妙但可能更重要。它們將交易的最小延遲 增加到整個區塊的最小等待時間,對于 Tendermint 來說約為數百毫秒到幾秒。 而傳統的可序列化數據庫系統提供了大概幾毫秒到幾十毫秒的提交延遲。他們能 夠做到這一點,是因為它們不是拜占庭容錯的,只需要一輪通信(而不是兩次), 并且需要超過一半的副本(而不是三分之二)的響應。然而,與其他算法中的領 導選舉中斷的快速提交時間不同,Tendermint 提供了一種更為規則的脈沖,可以 在節點故障和異步方面更好地響應網絡的整體運行狀況。
盡管有目的地引發的延遲在金融市場上顯示出希望,這類脈沖在互聯網通信自治系統的一致性中所起的作用還有待確定。

3.3.2 區塊結構

區塊的目的是包含一批交易并鏈接上到之前的區塊。鏈接以這兩種形式呈現:
前一個區塊的哈希,和導致前一個區塊提交的一組預提交,或者也可以稱之為 LastCommit。因此,塊由三個部分組成:區塊頭,交易列表和 LastCommit。

3.4 安全性(safety)

在這里,我們草擬了一個簡短的證明,即 Tendermint 滿足原子廣播,滿足:
·有效性(validity)-如果一個正確的進程廣播 m,它最終會傳送 m ·一致性(agreement)-如果一個正確的進程傳送 m,所有正確的進程最終
都會傳送 m
·整體性(integrity)-m 只被傳送一次,而且只當它被自己的發送者廣播的
時候
·總序性(total order)-如果正確的進程 p 和 q 傳送 m 和 m’,則如果 q 在傳
送 m’之前傳送 m,p 就在傳送 m’之前傳送 m
請注意,如果我們將 m 作為一個塊,Tendermint 不能滿足有效性,因為不能保證提議的區塊最終被提交,因為驗證者可能移動到新一輪并提交不同的區塊。 如果我們將 m 作為區塊中的一批交易,那么我們可以通過讓驗證者不斷重新提 出相同的批次直到它被提交,來滿足有效性。然而,為了滿足前一半的完整性, 我們必須引入一個額外的規則,禁止一個正確的驗證者提出一個區,或者提交一 個包含一批已經提交過的交易的區塊。幸運的是,批次可以由它們的根目錄來索 引,并且在提案和預提交之前進行查找。
或者,如果我們將消息 m 作為一個交易,那么我們可以通過在 mempool 上 斷言一個持久性(persistence)屬性來滿足有效性,即一個交易在 mempool 中一 直存在,直到它被提交。然而,為了滿足前一半的完整性,我們必須依靠應用狀 態來對交易執行一系列規則,使得給定的交易只有效一次。舉個例子,這可以通 過在帳戶上使用序列號來完成,就像在以太坊中所做的一樣,或通過保留一個未 使用的資源的列表,每個資源只能使用一次,就像比特幣中使用的一樣。由于有 多種方法,Tendermint 本身不能確保一個消息只被傳遞一個消息一次,而是允許 應用開發人員指定。請注意,完整性的后半部分是很好滿足的,因為只有正確提 議者提出的區塊中的交易才能被提交。
為了表明 Tendermint 滿足其余的屬性,我們引入了一個新的屬性,狀態機安 全性,并表明滿足狀態機安全性的協議也滿足一致性和總序性。狀態機安全說明, 如果一個正確的驗證者在某個高度 H 處提交一個區塊,則不會有其他的正確的 驗證者將在 H 處提交不同的區塊。假設所有消息最終都會被接收到,這就馬上 可以證明一致性,因為如果一個正確的驗證者在包含交易 m 的高度 H 處提交區 塊 B,所有其他正確的驗證者將不能提交任何其他區塊,因此最終必須提交 B, 從而傳送 m。
現在,需要做的就是證明狀態機安全性滿足總序性,Tendermint 滿足狀態機 安全性。先看前者,考慮由驗證者 p 和 q 傳遞的兩個消息 m 和 m’。狀態機安全 性確保當且僅當 q 在高度 Hm 傳送 m 時,p 在高度在高度 Hm 傳送 m。并且當且 僅當 q 在高度 Hm’傳送 m’時,p 在高度在高度 Hm’傳送 m’。不失一般性,由于高度嚴格上升,所以 Hm < Hm’。這樣,我們就得到了當且僅當 q 在 m’之前傳送 m 時,p 在 m’之前傳送 m,這也正好是總序性的聲明。
最后,為了證明當少于三分之一的驗證者是拜占庭的時候,Tendermint 滿足 狀態機安全性,我們以反證的方式進行。假設 Tendermint 不滿足狀態機安全性, 允許在同一高度提交多個區塊。那么我們表明,這種情況至少有三分之一的驗證 者必須是拜占庭才能發生,與我們的假設相矛盾。
考慮一個正確的驗證者已經在高度 H 和回合 R 提交區塊 B。提交一個區塊意 味著驗證者在回合 R 從超過三分之二的驗證者的情況下見證了區塊 B 的預提交。 假設另一個區塊 C 在高度 H 處被提交。我們有兩個選擇:它在回合 R 被提交, 或在回合 S > R 被提交。
如果是在第 R 回合提交的,那么超過三分之二的驗證者必須在第 R 回合中預 提交,這就意味著至少有三分之一的驗證者在第 R 回合中即預提交了區塊 B 也預 提交了區塊 C,顯然這是拜占庭,假設區塊 C 在回合 S > R 中被提交。由于超過 三分之二的驗證者預提交了 B,他們被鎖定在第 S 輪鎖定了 B,因此必須為 B 預 投票。為了預提交區塊 C,他們必須為 C 證明一個 polka,這需要超過 三分之二 的驗證者為 C 預投票。然而,由于超過三分之二驗證者被鎖定在區塊 B 并需要對 B 進行預投票,C 的 polka 將要求至少三分之一的驗證者違反 Prevote-the-Lock, 這很顯然是拜占庭。因此,為了違反狀態機安全性,至少要有三分之一的驗證者 必須是拜占庭。因此,當不到三分之一的驗證者是拜占庭時,Tendermint 滿足狀態機安全性。
鑒于上述,Tendermint 滿足原子廣播。 在未來的工作中,我們的目標是提供一個更正式的 Tendermint 安全性證明。

3.5 問責制(accountability)

一旦安全性被違反,一個負責的 BFT 算法可以識別出所有的拜占庭驗證者。
傳統的 BFT 算法沒有這個屬性,在事件安全性上沒有提供任何保證。當然,問責 制只適用于三分之一到三分之二的驗證者是拜占庭的時候。如果拜占庭超過三分 之二,他們可以完全控制協議,我們不能保證正確的驗證者會收到任何不當行為 的證據。
此外,問責制可以在異步網絡中最大限度地發揮作用—在違反安全性之后,關鍵信息的延遲交付可能直到檢測到安全違規之后的某個時間,才能確定哪些驗 證者是拜占庭。事實上,如果正確的進程可以接收拜占庭行為的證據但是在它們 可以傳播下去之前不可逆轉地失敗,那么可能會導致問責制受到永久性損害的情況,盡管在實踐中,這種情況應該是可以以高級的備份解決方案克服的。
通過列舉可能發生違反安全性的可能方式,并在每種情況下展現,拜占庭式驗證器都是可識別的,協議可以被證明是有責任的。Tendermint 的簡單性使其比 管理領導選舉的協議更簡單。
在 Tendermint 中只有兩種違反安全規定的方式,兩者都是負責任的。第一種, 拜占庭提議者在一輪中提出兩個沖突的提案,然后拜占庭的驗證者對兩者都投票。 第二種,拜占庭驗證者在一些驗證者已經提交之后違反鎖定規則,導致其他驗證 者在稍后的一輪中提交了一個不同的區塊。請注意,不可能通過三分之二或更少 的拜占庭驗證者僅使用違反 Unlock-on-Polka 規則來違背安全性—超過三分之一 的驗證者必須違反 Prevote-the-Lock,因為應該有一個 Polka 證明剩下的誠實節點 的提交。
在沖突提議和沖突投票的情況下,通過接收兩個消息來檢測這個沖突,并通過他們的簽名來識別元兇并不重要。
在違反鎖定規則的情況下,違反安全性,正確的驗證者必須廣播在該高度所看到的所有投票,以便將證據拼合在一起。數量不足三分之二的正確的驗證者, 是產生兩個區塊提交的的全體投票。在這些投票中,如果沒有三分之一或更多的 驗證者簽名沖突的投票,則有三分之一以上驗證者違反 Prevote-the-Lock。
如果預投票或預提交影響到提交,則必須由正確的驗證者看到。因此,通過收集所有投票,可以通過匹配每個預投票和被同一個驗證者最近的預提交來檢測 違反 Prevote-the-Lock 的行為,除非不存在。
相似地,對 Unlock-on-Polka 的違法可以通過匹配每個預提交和被證明的 Polka 來檢測出來。這意味著拜占庭驗證者可以在看到 Polka 之前就可以預提交,而且 如果一個恰當的 Polka 最終到來的話,它可以逃避問責。然而,如果不管怎樣 Polka 都會產生的話,這種情況實際上并不會對安全性的違反做出什么貢獻。
目前的設計在 post-crisis 廣播協議中提供了問責制,但可以進一步改進以便實 時問責。也就是說,一次提交可以被改變成不僅包含預提交,而且還包含所有證明預提交的投票,一路回到該高度的開始。這樣一來,如果安全性被違反,可以立即檢查出不合理的投票。

3.6 故障和可用性

作為一個 BFT 一致性算法,Tendermint 可以忍受最多至(但不包括)三分之
一的驗證者的拜占庭故障。這意味著節點會崩潰,向不同的對等點發送不同且相 互矛盾的消息,拒絕中繼消息,或者在不損害安全性和活性的情況下隨意做出行為(伴有活性的通常 FLP 警告)。
在協議中有兩個地方可以通過利用基于本地時鐘的超時來優化異步:在收到 三分之二或更多的預投票后,但不是單個區塊或 nil,和在收到三分之二或更多的預提交后,而不是單個區塊或 nil。在每種情況中,我們可以睡眠一段時間, 給予較慢或延遲的投票被接收的機會,從而減少沒提交一個區塊就進入新一輪的 可能性。時鐘不需要在驗證者上同步,因為每當驗證者觀察三分之二或更多其他 驗證者的投票時,時鐘就將被重置。
如果三分之一或更多驗證者崩潰,網絡就會停止,因為沒有驗證者可以在沒 有聽到其他超過三分之二驗證集的情況下取得進展。該網絡仍然可用于讀取,但不能進行新的提交。驗證者一旦恢復在線,就可以從它們離開的地方繼續下去。 一致性狀態機應該使用預先記錄日志,以便恢復的驗證者可以快速返回到其崩潰 時的步驟,確保它不會意外違反某項規則。
如果三分之一或更多的驗證者是拜占庭,則他們可以通過多種方式來危及安全性,例如通過在同一輪中提出兩個區塊,并且通過將這兩個都提交進行投票, 或者通過違反鎖規則來預提交兩個在相同的高度的區塊。在每種情況下,都有明 確可靠的證據表明某些驗證者的行為不當。在第一個例子中,他們在同一輪簽署 了兩項提議,這明顯違反了規則。在第二個例子中,他們可能已經在第 R 輪中預 投票了與在 R-1 輪中鎖定的不同的區塊,這違反了 Prevote-the-Lock 規則。
當使用經濟和治理組件來激勵和管理一致性(第 6 章)時,這些額外的問責 保障變得至關重要。

3.7 結論

Tendermint 是一種弱同步的拜占庭容錯狀態機復制協議,在違反 BFT 假設的 情況下,具有最佳的拜占庭容錯能力和額外的問責制保障。協議對提議者使用輪流的方法,并使用相同的機制來跳過提議一個已經提交的區塊的提議者。通過一個簡單的鎖定機制,可以保持安全。
本章中介紹的協議忽略了許多重要的細節,例如塊的高效傳播,緩沖交易,驗證集的更改以及與應用邏輯接口。這些重要課題將在后續章節中討論。

Chapter 4

Tendermint 子協議
前一章中的 Tendermint 一致性的介紹,忽略了一些關于用于傳播區塊,投票,交易和其他對等信息的流言協議的細節。這樣做是為了將注意力集中在一致性協議本身上,排除實用軟件工程的干擾。本章介紹了通過將組件實現為在每個對等連接上進行復用的相對獨立的反應器來實現這些細節的一種特定方法。

4.1 點對點網絡(P2P-Networking)

在啟動時,每個 Tendermint 節點接收要撥打的對等點的初始列表。對于每個對等點,一個節點維護一個持久的 TCP 連接,其中多個子協議以一種速率限制的 方式進行多路復用。消息被序列化成緊湊的二進制表示,以在線上發送,并且通 過經認證的加密協議對連接進行加密。
本章的其余部分描述了在每個對等連接上復用的單獨反應器。可以運行一個 額外的對等點交換反應器,允許節點請求彼此的其他對等地址,并跟蹤它們之前 連接到的對等點,以便保持與其他最小數量的對等點的連接。

4.2 一致性傳播(consensus gossip)

一致反應器包裝一致狀態機,并確保每個節點每次更改時間的時候向所有對等點廣播其當前狀態。以這種方式,每個節點跟蹤所有對等點的一致性狀態,允許它優化消息的傳播,以便僅在非常時刻發送他們需要的對等點信息,以及它們不具有的信息。對于每個對等點,節點維護兩個連續檢查新信息以發送對等體的例程,即提議和投票。信息應該以“rarest first”方式傳播,以最大限度地提高傳播效率,并盡量降低一些信息不可用的機會。

4.2.1 區塊數據(block data)

在第三章中,假設提案消息包括區塊。然而,由于區塊從單一來源出現并且可能相當大,這給區塊提議者帶來了不必要的壓力將數據上傳到所有其他節點;
如果將它們分成幾部分傳播,則可以更快地傳播區塊。
通過各種 p2p 協議普及的安全傳播數據的常見方法是使用 Merkle 樹,允許每個數據片段伴隨有一個簡短的證據(數據對數大小),該片段是整體的一部分。為了使用這種方法,塊被序列化并且被分割成適當尺寸的塊,用于期望的塊大小和驗證器的數量,并且塊被散列到 Merkle 樹中。為了使用這種方法,對于期望的區塊大小和驗證者的數量,區塊被序列化并且被分割成適當尺寸的塊,并且塊被散列到一個 Merkle 樹中。已簽署的提議,不是包括整個區塊,而是只包括 Merkle 根哈希,允許網絡在傳播塊上合作。一個節點在每次接收到一個塊時通 知它的對等點,以便通過多次發送相同的塊到一個節點來最小化浪費帶寬。
一旦接收到所有的塊,區塊被反序列化和驗證,以確保它正確地引用到前面 的區塊,并且其各種被 Merkle 樹實現的校驗也是正確的。雖然以前假定驗證者 在收到提議(包括區塊)之前不會預投票,但可以通過允許驗證者在收到提議之 后,在收到完整的區塊之前進行預投票,可以獲得一些性能收益。這就意味著預 投票那些最終是無效的票也是可以的。但是,無效區塊的預提交必須始終被視為 拜占庭。
被趕上的對等點(即處于較早高度的)會被發送區塊到它們所在的高度。一
次只處理一個區塊。

4.2.2 投票(votes)

在一致性狀態機的每個步驟中,在提案之后,節點需要等待投票(或本地超時)來往下進行。如果一個對等點剛進入一個新的高度,它將被從上一個區塊預 提交,所以如果它是一個提議者,它可能會在下一個區塊的 LastCommit 中包含它們。如果一個對等點已經預投票但尚未預提交,或已經預提交,但尚未到下一輪,則分別發送預投票或預提交。如果一個對等點趕上來,那么它會將已提交區 塊的預提交發送到當前的高度。

4.3 內存池(mempool)

第 3 章幾乎沒有提到交易,因為 Tendermint 在每次交易的區塊上運行,并且不關心單獨的交易,只要它們的校驗和在區塊中是正確的。 交易在內存中的緩存中獨立管理,而在比特幣之后,它被稱為 mempool。交
易在接收時被應用程序邏輯驗證,如果有效,則添加到 mempool,并使用有序 的多播算法來傳播。節點為每個對等點維護一個例程,以確保 mempool 中的交易以相同的順序被發送到對等點,在該順序中,它們由節點處理。
提議者從 mempool 中的有序列表中獲取交易,以獲取新的區塊建議。一旦某 個區塊被提交,塊中的所有交易將從內存池中刪除,剩余的交易由應用程序邏輯 重新驗證,因為它們的有效性可能由于提交的其他交易而改變,節點可能已經不 在其內存池中。

4.4 同步區塊鏈

一致性反應器提供了與最新的區塊鏈狀態同步的相對較慢的方式,因為它被設計為實時一致性,意味著對等點等待接收所有信息以提交單個區塊,然后再擔 心下一個區塊。為了適應可能不止幾個區塊的對等體,一個附加的反應器,區塊鏈反應器允許對等點并行下載多個區塊,使對等點能夠比使用一致性反應器同步 快幾百倍。
當節點連接到新的對等點時,對等點發送其當前高度。節點將從其當前高度 順序地向所有自發報告更高高度的對等點請求區塊,同時下載區塊,并將其添加 到區塊池中。另一個例程連續地嘗試從池中移除區塊,并通過驗證和執行它們, 一次兩個區塊,違反區塊鏈的最新狀態,將其添加到區塊鏈。區塊必須一次被兩個區塊驗證,因為一個區塊的提交作為 LastCommit 數據包含在下一個區塊中。
節點連續查詢其對等點的當前高度,并繼續同時請求區塊,直到其已經達到其對等點中的最高高度,此時它停止請求對等點高度并啟動一致性反應器。

4.5 結論

對于 Tendermint 區塊鏈的實際實現,需要許多子協議。這些包括對一致性數 據(投票和提議),區塊數據和交易的傳播,以及一些新對等點可以快速趕上最 新的區塊鏈狀態的方法。

Chapter 5

建立應用
Tendermint 被設計為一個用于復制一個確定性狀態機的通用目的算法。它使用 Tendermint Socket Protocol (TMSP)來標準化一致性引擎和狀態機之間的通信, 使應用程序開發人員能夠以任何編程語言構建其狀態機,并通過 Tendermint 的 BFT 算法自動復制它們。(*可以參考 etcd 的設計,實際上,完全沒有必要這樣 深度耦合日志和邏輯,日志歸日志,邏輯歸邏輯,這個部分的設計并不是非常的 好。從這個角度來說,比特幣的設計還是非常不錯的。)

5.1 背景

互聯網上的應用一般可以體現為包含兩個基本要素: ·引擎(engine):處理核心安全,網絡,復制。當為一個 web 應用供電(powering)時,它通常是一個網絡服務器,比如 Apache 或 Nginx,或者當它為一個分布式應 用供電(powering)時,它就是一個一致性算法。
·狀態機(state-machine):處理從引擎接收的交易并更新內部狀態的實際 應用程序邏輯。
這種關注點的分離使得應用的開發者可以以任何編程語言任意應用程序的形 式編寫狀態機,位于可能專門用于其性能,安全性,可用性,支持和其他考慮因 素的引擎之上。
與 Web 服務器及其應用程序不同,Web 服務器及其應用程序通常采用通過公 共網關接口(CGI)協議在 socket 上進行通信的形式,但一致性算法傳統上具有 少得多的可用或通用接口來構建應用程序。一些像 zookeeper,etcd,consul 和 其他分布式鍵值存儲為一個簡單的鍵值對應用的一個特定實例提供 HTTP 接口, 和一些更有趣的特性比如原子比較交換(compare-and-swap)操作和通知推送。 但是它們不提供給應用開發者狀態機代碼本身的控制。
對于在一致性引擎上運行的狀態機的高水平控制的需求主要是由于比特幣的 成功以及隨之而來的對區塊鏈技術的興趣驅引的。通過將更高級的應用程序直接 構建到一致性算法,用戶,開發人員,監管機構等之中,可以在任意狀態機上實 現更大的安全保障,遠遠超過諸如貨幣,交易所,供應鏈管理,治理等鍵值對存 儲之上。是允許集體實施代碼的執行的系統的潛力吸引了如此多的注意力。它實 際上是法律制度的許多方面的重新發明,使用分布式一致性算法和確定性可執行 的合同,而不是警察,律師,法官,陪審團等。人類社會發展的影響力是爆炸式 的,就像民主法治的引入一樣。
Tendermint 旨在提供可能構建此類應用程序的基本界面和一致性引擎。

5.2 Tendermint Socket Protocol

Tendermint Socket Protocol (TMSP)定義了一致性引擎與應用狀態機通信的核心接口。接口定義由許多使用 Google 協議緩沖區指定的消息類型組成,這些消息類型通過 socket 進行長度預定義和傳輸。圖 5.1 給出了消息類型,參數,返回 值和目的的列表,并且圖 5.2 中顯示了體系結構和消息流的概述。
TMSP 被實現為有序的異步服務器,其中消息類型為請求和響應的對,特殊消 息類型 Flush 通過連接推送任何緩沖的消息并等待所有響應。
TMSP 的核心是兩個消息:AppendTx 和 Commit。


一旦一致性決定了一個區塊,引擎將在區塊中的每個交易上調用 AppendTx, 將其傳遞給要處理的應用程序狀態機。 如果交易有效,將導致應用程序中的狀 態轉換。
一旦所有的 AppendTx 調用都返回,一致性引擎調用 Commit,導致應用程序 提交最新狀態,并將其持續到磁盤上。

5.3 分離協議和執行

使用 TMSP 可以讓我們明確分離出一致性,或一致的交易順序,和在狀態機上的實際執行情況。具體來說,我們首先在順序上達到一致性,然后執行有序的 交易。這種分離實際上提高了系統的容錯能力:盡管 3f + 1 個副本仍然需要同意 以容忍 f 個拜占庭故障,但執行只需要 2f + 1 個副本。也就是說,我們仍然需要 三分之二的多數來排序(ordering),但是我們只需要二分之一的多數來執行 (execution)。
但是另一方面,交易在排序后再執行可能導致無效的交易,這樣就會浪費系統資源。這可以通過使用由內存池調用的附加 TMSP 消息 CheckTx 來解決,允許 它檢查交易是否對最新狀態有效。但是要注意,區塊的一次提交會引起 CheckTx 消息處理的復雜性。特別地,應用需要維護另一個僅執行與交易有效性相關的主 狀態機規則的狀態機。第二個狀態機由 CheckTx 消息更新,并在每次提交后重置 為最新的提交狀態。 實質上,第二個狀態機描述了交易池的過濾器規則。
在一定程度上,CheckTx 可以用 optimistic execution,將結果返回給交易發送 方,并注意到,如果在提交感興趣的交易之前在區塊中提交了一個沖突的交易, 則結果可能會出錯。這種 optimistic execution 是可擴展 BFT 系統的一個方法的重 點,對于特殊的應用程序,在很少有交易之間的沖突的情況下,這種方法可以很有效率。同時,由于需要處理可能的無效結果,它增加了客戶端的額外復雜性。 該方法在第 10 章進一步討論。

5.4 微服務架構(Microservice Architecture)

將應用程序設計中的關心點分離為一個策略是非常明智的做法。特別地,今天許多大規模應用的部署都采用微服務架構,其中每個功能組件被實現為獨立的 網絡服務,并且通常封裝在 Linux 容器中(例如使用 Docker)以實現有效的部署, 可擴展性和可升級性。
運行在 Tendermint 一致性算法之上的應用程序通常可以分解成微服務。舉個 例子,許多應用程序利用鍵值對存儲來存儲狀態。作為獨立服務運行鍵值對存儲 非常常見,以便利用數據存儲的特性,如高性能數據類型或 Merkle 樹。
應用程序的另一個重要的微服務是一個治理模塊,它管理 TMSP 消息的某個 子集,使應用程序能夠控制驗證集的更改。這樣一個模塊可以成為 BFT 系統治理 的強大范例。
一些應用程序可能會為用戶使用本地貨幣或帳戶結構。 因此,提供支持例如 處理數字簽名和管理帳戶動態的基本元素的模塊可能是有用的。
組合復雜 TMSP 應用程序的可能的微服務列表繼續進行。實際上,甚至可以 構建一個可以使用交易中發送的數據啟動子應用程序的應用程序。例如,在交易 中包括 docker 圖像的哈希,使得圖像可以從一些文件存儲后端被拉出,并作為 在一致性算法的未來交易中可能導致其執行的子應用程序運行。這就是以太坊 (ethereum)的方法,它允許開發人員將一些代碼部署到網絡中,可以通過未來 的交易以及 IBM 最近的 OpenBlockChain(OBC)項目觸發在 Ethereum 虛擬機中 運行,從而允許開發人員發送完整的 Docker 交易中的內容,定義運行任意代碼 的容器,以響應發往它們的交易。

5.5 決定論(Determinism)

關于使用 TMSP 構建應用程序的最關鍵的注意事項是它們必須是確定性的。也就是說,對于復制的狀態機來說,在不損害安全性的情況下,每個節點在同一 狀態下執行相同的事務時必須得到相同的結果。
這不是 Tendermint 自己特有的要求。比特幣、Raft、以太坊、任何其他分布 式一致性算法,以及如同 lock-step multi-player 這樣的游戲等應用,都必須有嚴 格地確定性,以免出現一致性失敗的情況。
編程語言中有許多非確定性的來源,最明顯是通過隨機數和時間,但也可以 通過浮點精度的使用,以及通過哈希表的迭代(一些語言,比如 Go,在哈希表 上強制執行隨機迭代,以強制程序員明確地了解何時需要有序數據結構)。決定 論的嚴格限制,以及它每一個主要編程語言的明顯缺陷,都促使以太坊開發自己 的圖靈完整的完全確定性的虛擬機,這些虛擬機構成了應用程序開發人員構建位 于以太坊區塊鏈之上的應用程序的平臺。但是決定性有很多怪癖,比如 32 字節 堆棧字,存儲鍵和存儲值,并且不支持字節移位操作—一切都是大數算術。
確定性編程在實時(real-time),鎖步(lock-step),多方游戲(multi-party gaming) 世界中得到了很好的研究。這樣的游戲構成復制狀態機的另一個例子,并且在許 多方面與一致性算法非常相似。使用 TMSP 構建應用的開發者被鼓勵去研究他們 的方法,并且小心的實現一個應用。一方面,使用功能編程語言和驗證方法可以實現正確程序的構建。另一方面,將非確定性程序轉化為規范確定性程序的編譯 器來正在被開發。

5.6 終止(Termination)

如果決定論對于保護安全性至關重要,則交易執行終止對于保持活性至關重要。然而,一般來說,確定一個給定的程序是否停止,即使只是單個輸入,更不 用說所有輸入,一個稱為“停止問題(Halting Problem)”的問題,通常是不可能的。
以太坊虛擬機通過計量(metering)來解決問題,即對執行中的每個操作進 行計費。這樣一來,當發送者用盡資金時,交易就保證會被終止。通過將程序編 譯為自己的計量版本(metered version)的編譯器,這種 metering 可以在更一般 的情況下是可行的。
沒有顯著的開銷是難以解決這個問題的。實質上,驗證者不能夠判斷一個執 行到底是在一個無限循環中,還是只是慢但是幾乎是完成的。使用 Tendermint 一致性協議來決定交易超時是可行的,這樣超過三分之二的驗證者必須同意一個 交易超時,因此被認為是無效的(即對狀態沒有任何影響)。然而,我們不在這 里繼續糾纏這個想法,而是把它留在今后的工作中。與此同時,預計應用程序將 在部署到任何一致性系統之前進行徹底的測試,并且在一致性算法失敗的情況下, 將使用監控和治理機制來重啟系統。

5.7 例子

在本節中,將介紹和討論越來越復雜的 TMSP 應用程序的示例,特別關注CheckTx 和管理內存池。

5.7.1 Merkleeyes

TMSP 應用程序的一個簡單示例是基于 Merkle 樹的鍵值對存儲。Tendermint 提供 Merkleeyes,一個 TMSP 應用程序,它封裝了一個自平衡的,Merkle 二叉搜 索樹。交易的第一個字節決定交易是 get、set 還是 remove 操作。對于 get 和 remove 操作,剩下的字節是鍵(key)。對于 set 操作,剩下的字節是包含鍵(key)和 值(value)的序列化列表。Merkleeyes 可以使用一個簡單的 CheckTx 實現,只對 交易進行解碼,以確保它的格式正確。我們還可以做一個更高級的 CheckTx,在 那里 get 和 remove 未知鍵的操作是無效的。一旦調用 Commit,最新的更新被添 加到 Merkle 樹中,所有的散列都被計算出來,并且樹的最新狀態被提交到磁盤。
請注意,Merkleeyes 旨在成為其他 TMSP 應用程序使用的模塊,用于基于 Merkle 樹的鍵值對存儲,而不是獨立的 TMSP 應用程序,盡管 TMSP 接口的簡單 性使其適用于兩者。

5.7.2 Basecoin

一個更完整的例子是一個簡單的貨幣,使用由以太坊開發的帳戶結構,其中 每個用戶都有一個公鑰和一個公共密鑰的余額帳戶。該帳戶還包含一個序列號, 該序列號等于該帳戶發送的交易的數字。如果交易包含正確的序列號,并由正確 的私鑰簽名,則可以從帳戶中發送資金。沒有序列號,系統將容易發生重播攻擊 (replay attack),即可以重播記錄帳戶的簽名交易借記,導致借記發生多次。
此外,為了防止多鏈環境中的重放攻擊,交易簽名應該包括一個網絡或區塊鏈標識符。
支持貨幣的應用程序自然比簡單的鍵值對存儲有更多的邏輯。特別地,某些 交易明顯無效,例如簽名無效,序列號不正確或發送量大于發送者賬戶余額的交易。這些條件可以在 CheckTx 中檢查。
此外,為了更新序列號和帳戶余額,補充應用程序狀態必須被維護,以便一 次在內存池中涉及相同帳戶的多個交易時更新序列號和帳戶余額。當 commit 被 調用時,補充應用狀態被重置為最新的提交狀態。任何仍然在內存池中的交易都 可以通過 CheckTx 以最新的狀態重播。

5.7.3 以太坊(Ethereum)

Ethereum 使用已經描述的機制將交易從 mempool 中刪除,但它也會在虛擬機中運行一些交易,從而更新狀態并返回結果。CheckTx 中沒有完成虛擬機的執行,因為它代價更昂貴,并且在很大程度上取決于交易包含在區塊中的最終順序。

5.8 結論

TMSP 提供了一種簡單而靈活的手段,以任何編程語言構建任意應用程序,從 Tendermint 一致性算法繼承 BFT 狀態機復制。對于一個一致性引擎和一個應用程 序來說,它扮演著更多同樣的角色,例如,CGI 扮演 Apache 和 Wordpress。然而, 應用程序開發人員必須特別注意確保其應用程序是確定性的,并且交易執行是結 束的。

Chapter 6

管理(Governance)
到目前為止,本文已經回顧了 Tendermint 一致性協議和應用環境的基本要素。
在現實世界中操作系統的關鍵要素,如管理驗證集的變更和從危機中恢復,還沒有討論。
本章提出了一種解決這些問題的方法,以使治理在協商一致系統中發揮作用。 當驗證集包含更多分散的代理集時,維護網絡的有效治理系統將對網絡的成功變 得越來越重要。

6.1 Governmint

治理的基本功能是通過一種投票方式來刪除行動建議。治理作為軟件最基本 的實現是使用戶能夠提出提議,投票并統計投票的模塊。提議可能是程序性的, 在這種情況下,他們可以在成功投票后自動執行,或者它可能是非程序性的,在 這種情況下,其執行是一個手動練習。
為了在 Tendermint 中啟用某些操作,例如更改驗證集或升級軟件,實施了一個稱為 Governmint 的治理模塊。Governmint 是一個最低限度的可行治理應用, 支持多組實體,每個實體可以在內部對提議進行投票,其中一些可能導致程序性 執行操作,例如更改驗證集,或升級 Governmint 本身(例如添加新提議類型或其他投票機制)。
該系統利用數字簽名認證投票者,并可能使用各種可能的投票方案。特別感興趣的是二次投票方案,其中投票的成本是投票權的二次方,這已被證明具有滿 足投票者偏好的優越能力。

6.2 驗證集變更

驗證集變更是現實世界一致性算法的關鍵組成部分,以前的許多方法都未能明確定義或被遺留為黑色藝術(black art)。Raft 艱難地闡明了驗證集變更的良好協議,這需要使用新的消息類型通過一致性。Tendermint 采用了類似的方法,盡管它通過使用 EndBlock 消息的 TMSP 接口進行標準化,該消息在所有 AppendTx 消息之后運行,但在 Commit 之前運行。如果交易或一組交易被包括在具有更新 驗證集的預期效果的區塊中,則應用程序可以通過響應 EndBlock 消息指定其公 鑰和新的投票權力來返回驗證者列表以進行更新。可以通過將其投票權設置為零 來刪除驗證者。這為應用程序提供了更新驗證集而不必指定交易類型的通用方法。
如果在高度 H 處的區塊返回已更新的驗證集,則高度 H + 1 處的區塊將反射 更新。但是請注意,H + 1 區塊中的 LastCommit 必須使用與 H 處一樣的驗證集, 因為它可能包含已被刪除的驗證器的簽名。
投票權的更改適用于 H + 1,以便下一個提議者可以受到更新的影響。否則的 話,應該是下一個提議者的驗證者可能會被刪除。輪流算法應該優雅地直接地轉 到下一個提議者來處理。由于相同的區塊在至少三分之二的驗證者上被復制,并 且輪流是確定性的,所以它們將全部都進行相同的更新,并期望同一個下輪提議者。

6.3 懲罰拜占庭驗證者

比特幣設計的一個顯著特點是它的激勵結構,目前為止,協議的目標是通過獎勵驗證者來激勵驗證者的正確行為。雖然這在比特幣一致性協議的背景下是有 道理的,但優越的激勵可能會提供強烈的抑制效果,使得驗證者具有真正的 skin-in-the-game,而不是一個軟機會成本(soft opportunity cost)。
在 Tendermint 中可以使用 Vitalik Buterin 提出的方法作為所謂的 Proof-of-Stake 協議來實現消除負面效果。實質上,驗證者必須提供保證金(“他們必須保證一 定的賭注”)才能參與一致性。如果他們被發現簽署雙重提議或投票,其他驗證 者可以以交易形式發布違規的證據,應用程序狀態可以通過刪除違規者來修改驗 證集,從而燒毀其存款。這具有將明確的經濟成本與拜占庭行為聯系起來的效果, 并且能夠通過將三分之一或更多的驗證者賄賂為拜占庭來估計違反安全性的成本。
請注意,一致性協議可以指定懲罰更多的行為,而不僅僅是雙重簽名。特別是,我們有興趣懲罰不公正的任何強烈的信號行為—通常為任何不是基于其他人報告的狀態報告的狀態變化。舉個例子,在 Tendermint 的一個版本中,所有預提交必須伴隨 polka 來證明它們,驗證者可能會因廣播為被裁定的預提交而受到懲罰。但要注意的是,我們不能懲罰所有未預期到的行為—比如說,一個驗證者在不是它提議的回合做出提議可能是優先考慮異步和節點崩潰優化的基礎。
實際上,沿著這兩條線概況 Tendermint,1)更為寬松的判定形式,2)允許 驗證者在其任期之前提出建議,從而產生一個性質與 Vlad Zamfir 所提出的相似 的協議族,以 guise Casper 作為未來以太坊版本的一致性機制。關于協議之間的 關系和反拜占庭判定的特征的更正式的說明仍然是未來的工作。

6.4 軟件更新(Software Upgrades)

Governmint 也可以作為在可能分散的網絡上協商軟件升級的自然手段。在公共互聯網上的軟件升級是一個非常具有挑戰性的操作,需要仔細規劃來維護不再 升級的用戶的向后兼容性,并且不會通過引入漏洞,刪除功能,增加復雜性,或 者可能最糟糕的,未經許可自動更新來使軟件的忠實用戶沮喪。
比特幣尤其明顯地提高了分散式一致性系統的更新難度。以太坊由于其強大的領導力和統一的社區已經管理了一個成功的非向后兼容的升級版本,而 Bitcoin, 放下軟件工程中過多的弊病不說,由于一個惡性分裂的社區和缺乏強有力的領導, 而無法進行一些必要的升級。
就變更的范圍而言,區塊鏈的更新一般分為 soft forks 和 hard forks。Soft forks 旨在向后兼容,并且使用協議中可能被尚未升級的用戶忽略的自由度,為用戶提 供新功能。另一方面,hard forks 是非向后兼容的升級,在比特幣的例子中,可 能會導致違背安全性,而在 Tendermint 的例子中,會導致系統終止。
為了應對,比特幣軟件的開發人員推出了一系列 soft forks,驗證者可以通過 在新的區塊中發信號來投票。一旦驗證器的某個閾值是更新的信號,至少對于支 持更新的軟件版本的用戶,它將自動在網絡上生效。由于這些 soft forks,比特幣 系統的效用大大增加,預計在未來將而繼續這樣做。有趣的是,社區未能成功地 hard fork 軟件,一方面引起了人們對該系統長期穩定性的擔憂,另一方面引發了人們對該系統對腐敗治理—它的不可治理性—的恢復力的興奮和鼓舞。
鑒于今天世界上過多的政府腐敗,有很多理由采取后一種立場。然而,密碼 學和分布式一致性算法提供了一套新的缺乏強大的身份驗證系統的工具,可以在 現代政府的“紙、筆、握手”的世界中甚至是傳統網絡的數字世界中產生不可想 象的一定程度的透明度和責任感。
在使用 Governmint 的系統中,開發人員將是區塊鏈上的標識實體,可以提交 軟件升級提議。該機制與 Github 的 Pull Request 非常相似,只有它被集成到現場 運行系統中,共識通過一致性協議傳遞。客戶端應寫入可配置的更新參數,這樣 他們可以指定是自動更新還是更新前需要通知。
當然,任何未經徹底審查的軟件升級都可能對系統構成危險,所以通常應該采取保守的方式升級。

6.5 危機恢復(Crisis Recovery)

在發生危機的情況下,比如交易日志中的 fork,或者系統陷入停頓,傳統的一致性系統很少甚至沒有提供保證,通常需要人工來干預。
Tendermint 保證,違反安全性責任的可以被識別,使得任何可以訪問至少一個誠實的驗證者的客戶端都可以識別不誠實的驗證者的加密確定性,從而選擇將 誠實的驗證者跟蹤到具有一個不包括拜占庭的驗證集的新鏈上。
舉個例子,假設三分之一或更多的驗證者違反鎖規則,導致在高度 H 處有兩 個區塊要被提交。誠實的驗證者可以通過傳播所以投票來確定是誰雙重簽名的。 在這一點上,由于基本的錯誤假設被違反,它們不能使用一致性協議。注意,能 夠在這一點上為 H 累積所有的投票意味著關于在危機期間網絡連接和可用性的 重要假設,如果他不能由 p2p 網絡提供,它可能需要驗證者們使用替代方案,比 如社交媒體和高可用性的服務來交流證據。一旦其中至少有三分之二收集了所有 的證據,全套的余留誠實節點可以啟動一個新的區塊鏈。
或者,修改 Tendermint 協議,以便預提交要求 polka 將確保負責 fork 的可以 立即受到懲罰,并且不需要額外的發布期。這個更改工作留給以后來做。
使用更復雜的 Governmint 來適應各種特定的危機是可行的,比如永久性崩潰 故障和私鑰的危害。但是,這些方法必須仔細考慮,因為它們可能會破壞基礎協 議的安全性保障。我們以后將對這些方法進行調查,但是要注意,理解其從危機 中恢復的能力的嵌入區塊鏈的社會經濟背景的重要性。
不管危機如何恢復,其成功取決于與客戶端的整合。如果客戶端不接受新的 區塊鏈,則該服務實際上處于脫機狀態。因此,客戶端必須了解特定區塊鏈所用 的恢復規則。在上述違背安全性的情況下,他們還必須收集證據,確定要刪除哪 些驗證者,并用剩余的驗證者計算新的狀態。在違反活性的情況下,必須保持 Governmint。

6.6 結論

治理是分布式一致性系統的一個關鍵因素,盡管有關治理系統仍然知之甚少。
Tendermint 以一種叫做 Governmint 的 TMSP 提供治理,旨在促進在分布式系統的基于軟件的治理中的增強實驗。

Chapter 7

客戶端注意事項(Client Considerations)
本章回顧了與托管在 Tendermint 上的應用程序交互的客戶端的一些注意事項。

7.1 發現

網絡發現只需通過 TCP 連接一些種子節點即可。p2p 網絡使用經過身份驗證的加密,但是驗證者的公鑰必須以某種方式從 band 中驗證,即通過一種替代的 媒介,而不是在協議的范圍內。實際上,在這些系統中,起源狀態本身必須要被 傳出 band 以外,理想情況下,也是唯一必須要被通信出去的東西,因為它還應 該包含驗證者使用的用來驗證加密的公鑰,與在一致性中用于簽署投票的方式是 不同的。
對于可能隨時間變化的驗證集,通過 DNS 注冊所有驗證者以及在新的驗證者 實際成為驗證者之前注冊它們是有用的,并在其以驗證者身份被刪除后將其刪除。 或者,驗證者位置可以注冊在另一個容錯分布式數據存儲中,可能包括另一個 Tendermint 集群本身。

7.2 廣播交易

作為通用應用平臺,Tendermint 僅為廣播交易的客戶端(clients)提供簡單
的接口(interface)。一般范例是客戶端通過代理連接到 Tendermint 的一致性網 絡,該代理可以在其本地機器上運行,也可以托管在其他提供商。代理功能作為 網絡上的非驗證者節點,這意味著它可以跟上一致性并處理交易,但不會簽署投 票。該代理使客戶端交易能夠通過傳播層快速廣播到整個網絡中。
節點只需要連接到網絡上的另一個節點來廣播交易,但默認情況下會連接到 許多節點,從而最小化交易不會被接收的機會。交易被傳遞到內存池,并通過要在所有節點的內存池中被緩存的內存池反應器傳播,以便最終它們其中的一個可以將它包含在一個區塊中。
請注意,交易在進入一個區塊之后才會執行它的狀態,所以客戶端不會馬上 得到結果,而不是確認它被接受到 mempool 并廣播給其他對等點。客戶端應該 在一個區塊的提交過程中計算出來的時候對代理進行注冊,以接收其作為推送通 知的結果。
客戶端連接到當前提議者并不是必需的,因為最終任何在其內存池中具有交 易的驗證者都可以提出它。然而,在網絡處于高負荷下的某些情況下,對下一個提案的優先廣播可能會降低交易的延遲。不然的話,交易應該迅速被傳播到每個驗證器。

7.3 內存池(Mempool)

內存池負責在內存被包含在區塊中之前緩存交易。它的行為很微妙,對整個系統架構構成了一系列的挑戰。首先,在內存池中緩存任意數量的交易可以直接 拒絕可能會使網絡癱瘓服務攻擊。大多數區塊鏈使用其原生貨幣來解決這個問題, 并且只允許花費一定費用的交易留在內存池中。
在一個更廣泛的,不必須一種貨幣支付的系統中,比如 Tendermint,系統必 須建立更嚴格的過濾規則,并依靠更智能的客戶端重新提交被丟棄的交易。然而, 這種情況更為微妙,因為在 mempool 中過濾交易的規則集必須是應用程序本身 的一個功能。因此,TMSP 的 CheckTx 消息,mempool 可以使用來針對應用程序 的瞬態狀態(transient state)運行交易,以確定是否應該保留或丟棄。
盡管在許多示例應用程序中提供了例子,但處理瞬態是不重要的,并且可以 把它留給應用程序開發人員。在任何情況下,客戶端必須監視內存池的狀態(即 未確認的交易),以確定他們是否需要重新廣播他們的交易,這可能發生在高度 并發的,其中一個交易的有效性取決于已處理的另一個交易的設置中。

7.4 語義(Semantics)

Tendermint 的核心一致性算法只提供至少一次(at-least-once)的語義,也就是說系統常受到重放攻擊(replay attacks)的影響,即同一個交易可以被多次提交。然而,許多用戶和應用程序期望能從數據庫系統得到一個更強的保證。 Tendermint 系統的靈活性把這些語義的嚴格性留給應用程序開發人員。通過利用 CheckTx 消息,和充分管理應用程序中的狀態,應用程序開發人員可以提供適合 他們和他們的用戶的需求的數據庫語義。比如說,如第 5 章所述,使用基于具有 序列號的帳戶系統可以減輕重放攻擊,并將語義從至少一次(at-least-once)更 改為恰好一次(exactly-once)。

7.5 讀取(Reads)

客戶端將讀請求發送到用于廣播交易(寫入)的同一個代理節點。即使網絡
停止了,代理始終都可用于讀取。然而,在分區的情況下,代理可以與網絡的其余部分分開,繼續制造區塊。在這種情況下,代理的讀取可能會過時。
為了避免過時的讀取,讀取請求可以作為交易發送,假定應用程序允許這樣 的查詢。通過使用交易,保證讀取返回最新的提交狀態,即在下一個區塊中提交讀取交易時。這當然比查詢狀態的代理更昂貴。可以使用啟發式方法來確定讀取 是否過期,例如代理與其對等點是否良好連接,并且正在制作區塊;或者是否它 被卡在有三分之一或以上的驗證者的投票的回合中,但沒有替換執行實際的交 易。

7.6 Light Client Proofs

在傳統數據庫中,區塊鏈的主要創新之一是他們有意識地使用 Merkle 哈希樹來支持系統子狀態的緊湊證明的成果,即所謂的 light-client 證明。一個 light client proof 是一個允許客戶端驗證一些鍵值對是在有一個給定跟哈希的 Merkle 樹中的 Merkle 樹的路徑。狀態的 Merkle 根哈希包含在區塊的頭(header)中,這樣就 足以讓客戶端只有最新的頭來驗證狀態的任何組件。當然,要知道 header 本身 是有效的,它們必須已經驗證了整個鏈,或者只保持最新的驗證集更改,并且依 賴于狀態轉換是正確的經濟保證。

7.7 結論

Tendermint 網絡功能的客戶端與任何其他分布式數據庫的相似,盡管必須要考慮到基于區塊的提交的性質以及內存池的行為。另外,客戶端必須考慮到以特 定的應用設計。 雖然這增加了一些復雜性,但是它具有極大的靈活性。

Chapter 8

實現
Tendermint 的參考實現是由 Go 編寫的,托管在 Github 上。Go 是一種具有豐富標準庫的,輕量級大規模并發執行的并發原語,以及為簡化和高效率優化的開 發環境的,類似 C 的語言。
代碼使用了大量足夠模塊化來隔離成自己的庫的包。這些包大部分是由 Jae Kwon 編寫的,包括漏洞修復,測試,以及一些作者貢獻的偶然特性。這些包中 最重要的部分在下面的小節中描述。

8.1 二進制序列號(Binary Serialization)

Tendermint 使用了一種為簡單性和決定性優化的二進制序列化算法。它支持所有整數類型(包括使用一個字節長度的前綴編碼的變體),字符串,字節數組 和時間(毫秒精度的 unix 時間)。它還支持任何類型和結構體的數組(編碼為 有序值的列表,忽略鍵)。在某種程度上,它靈感來自 Go 的類型系統,特別是 它使用的接口類型,可以實現為許多具體類型之一。可以注冊接口,并且每個具 體實現都在其編碼中給出了一個領先的類型字節。
詳情參見 https://github.com/tendermint/go-wire。

8.2 密碼學

一致性算法,如 Tendermint 使用三個主要加密原語:數字簽名,哈希函數和驗證加密。雖然存在這些原語的許多實現,但為企業軟件選擇加密庫亦不是輕松 的任務,特別是世界上最常用的安全庫 OpenSSL 的深刻的不安全性。
導致加密系統不安全的原因是,有像與 NIST 合作,設計并標準化了當今使用 的許多最流行的加密算法的 NSA,這樣的政府機構有意的破壞其安全屬性。鑒于 這些機構明顯不合法,例如愛德華斯諾登(Edward Snowden),以及試圖破壞公 共密碼標準的歷史,許多密碼學社區更傾向于使用在開放的學術環境中設計的算 法。同樣,Tendermint 也只使用這種算法。
Tendermint 使用了 RIPEMD160 作為它的加密哈希函數,它產生 20 字節的輸 出。它用于交易和驗證簽名的 Merkle 樹,并用于計算塊散列。Go 在其擴展庫中 提供了一個實現。在從公鑰派生的地址中,比特幣也使用 RIPEMD160 作為兩種 哈希函數中的一種。
作為其數字簽名方案,Tendermint 在 ED25519 橢圓曲線上使用 Schnorr 簽名。 ED25519 是由丹伯恩斯坦(Dan Bernstein)開源設計的,其目的是高性能,易于 實現,但不引入漏洞。伯恩斯坦還引入了 NaCl,一個高級庫,用于使用 ED25519 曲線進行經過身份驗證的加密。Tendermint 使用其擴展庫中提供的實現。

8.3 Merkle 哈希樹

Merkle 樹的功能非常類似于其他基于樹的數據結構,還有額外的功能,它可以生成樹中一個鍵的成員身份證明,而樹的大小是對數的。這是由遞歸地連接和 哈希鍵組合完成的,直到只剩下一個哈希,樹的根哈希。對于樹上的任何葉子, 從它到根的一條哈希的痕跡作為它的成員的證明。這使得 Merkle 樹特別適用于 p2p 文件共享應用程序,在該應用程序中,可以將大型文件的片段作為屬于文件 的內容進行驗證,而不需要所有的片段。Tendermint 將此機制用于網絡上的傳播 塊,其中根哈希被包含在區塊提議中。
Tendermint 還提供了一個自我平衡的 Merkle 二叉樹,以 AVL 樹為模型,作為 一個名為 Merkleeyes 的 TMSP 服務。IAVL 樹可以用于存儲動態大小的狀態,允 許在對數時間內查找、插入和刪除。

8.4 RPC

Tendermint 公開了 HTTP API,用于查詢區塊鏈、網絡信息、一致性狀態以及廣播交易。同樣的 API 可以通過三種方法獲得:使用 URI 編碼參數的 GET 請求, 使用 JSONRPC 標準的 POST 請求,以及使用 JSONRPC 標準的 websockets。 Websockets 是高交易吞吐量的首選方法,也是接收事件的必要條件。

8.5 P2P 網絡

第 4 章更詳細地描述了 Tendermint 使用的 P2P 子協議。

8.6 反應器(Reactor)

Tendermint 節點由多個并發反應堆組成,每一個都管理一個狀態機在網絡上給對等點發送和接收消息,如第 4 章所述。反應器通過鎖定共享數據結構來同步, 但是同步的點被保持在最小值,這樣每個反應器就會和其他反應器同時運行。

8.6.1 內存池(Mempool)

Mempool 反應器管理 mempool,在它們被打包在區塊上并提交之前緩存交易。
Mempool 使用應用程序狀態機的一個子集來檢查交易的有效性。交易保存在一 個并發鏈表結構中,允許安全寫入和許多并發讀取。新的、有效的交易被添加到 列表的末尾。每個對等點遍歷列表,將每個交易只需要一次有序地發送到對等點。 該列表還被掃描為一個新的提議收集交易,并在每次提交一個區塊時更新:提交 了的交易被刪除,未被提交的交易通過 CheckTx 被重新運行,以及那些已經失效 的交易被刪除。

8.6.2 共識(Consensus)

一致性反應器管理一致性狀態機,它處理提議、投票、鎖和實際提交區塊。
狀態機使用一些持久化的例行程序(go-routines)來管理,這些例行程序接收到 消息,并使它們能夠確定地回放,以調試狀態。這些例行程序包括 readLoop,用于讀取接收到的消息隊列和 timeoutLoop,用于注冊和觸發超時事件。
在一致性狀態機中,當收到完整的提議和區塊時,或者在給定的回合中收到 超過三分之二的預投票或預提交時,則會進行轉換。轉換導致了建議、區塊數據 或投票的廣播,這些數據在內部隊列(internalReqQueue)上排隊,由 readLoop 在串行上處理從對等點接收到的消息。這將內部消息和對等消息放在平等的基礎 上,并將其輸入到一致性狀態機中,但允許內部消息被更快地處理,因為它們不 像來自對等點那樣處于相同的隊列中。

8.6.3 區塊鏈(Blockchain)

區塊鏈反應器采用比一致性反應器更快的技術來同步區塊鏈。也就是說,驗證者請求區塊的遞增高度,直到他們的對等點沒有任何更高的高度的區塊。區塊被收集在一個區塊池(blockpool)中,并通過一個工作例程同步到區塊鏈,它周 期性地從池中取區塊,并對當前鏈進行驗證。
一旦區塊鏈反應器完成同步,它就會啟動一個一致性反應器來接管。

8.7 結論

Tendermint 的 Go 語言實現充分利用了語言的并發原語、垃圾回收和類型安全性,以提供一個清晰的、模塊化的、易于閱讀的,包含許多可重用組件的代碼。 如第 9 章所示,該實現獲得高性能,并對許多不同類型的錯誤具有強大的魯棒性。

Chapter 9

性能和容錯
Tendermint 被設計為一種拜占庭容錯的狀態機復制算法。只要不到三分之一的驗證者是拜占庭,它就保證安全性,類似地,只要網絡信息最終和用來傳播協 議的有關網絡同步的弱假設被傳送,它就保證了活性。在本節中,我們通過注入 宕機故障和拜占庭故障來經驗性地評估 Tendermint 的容錯能力。目標是,表明 在發生這種故障的情況下,Tendermint 一致性的實現并不會影響安全性,因此可 以最小化性能受到的影響,并且可以很快地恢復。
Tendermint 算法的性能可以通過幾種關鍵方式進行評估。最明顯的措施是區 塊提交時間,它是最終延遲的度量,以及衡量網絡容量的交易吞吐量。我們為每 個分布在全球范圍內的驗證者收集數據,驗證者的數量范圍都是 2 從 2 到 64 的 倍數。

9.1 總覽

本章的實驗用例存儲在 https://github.com/tendermint/network_testing 數據倉庫。所有的實驗都在 docker 容器中進行,這些容器運行在 t2.medium 或 c3.8xlarge 類型的 Amazon EC2 實例上。t2.medium 有 2 個 vCPU 和 4 GB 的 RAM,c3.8xlarge 有 32 個 vCPUs 和 60 GB 的 RAM。實例分布在橫跨五大洲 的 7 個數據中心。另一個負責生成交易的 docker 容器在每個實例上運行。交易的大小是 250 字節(一個包括 32 或 64 字節的哈希和簽名的合理的大小),并被 構造成可調試的,可以快速生成的,并包含一些隨機性的。因此,前面的字節是 表示該實例的交易號和驗證者索引的 Big-Endian 編碼整數,后面的 16 個字節是 從操作系統中隨機生成的,中間的字節全是零。
使用網絡監視工具來維護每個驗證者的 Tendermint RPC 服務器的活動的 websocket 連接,并且在第一次接收到新的提交的區塊作為該區塊的官方提交時 間時,使用其本地時間。實驗首先在沒有監視器的情況下運行,通過復制驗證者 中的所有數據來進行分析,并使用 2/3th 驗證者提交區塊的本地時間作為提交時 間。使用監視器的速度要快得多,能夠在線監測,而且被發現只要區塊頭信息(不 是整個區塊)通過 websockets,就不會影響結果。
遠程機器上的 Docker 容器很容易使用 Docker-machine 工具進行管理,而網絡 測試存儲庫提供了一些工具,可以利用 Go 的并發特性,同時在許多遠程機器上 執行 Docker 容器上的操作。
每個驗證者都直接連接彼此,以避免網絡拓撲的混淆效應。
對于涉及宕機故障或拜占庭行為的實驗,故障節點的數量由 Nfault = [(N - 1) / 3] 給出,其中 N 是驗證者的總數。

9.2 吞吐量和延遲(Throughput and Latency)

本節描述了在非對抗性條件下測試 Tendermint 的原始性能的實驗,其中所有節點都在線并同步,并且不為異步提供任何設施。也就是說,使用了一個人為的 高的 TimeoutPropose(10 秒),所有其他超時參數均設置為 1 毫秒。此外,所 有的 mempool 活動都是禁用的(在提交之后不會傳播交易或重新檢查它們), 而在進程內的 nil 應用程序則用于繞過 TMSP。這可以作為一個控制場景,用于評 估在故障和/或異步的情況下的性能下降。
實驗運行在大小為 2 的從 2 到 64 倍的驗證集和大小為 2 的從 128 到 32768 被的區塊上。交易被預先加載到每個驗證器上。每個實驗運行 16 個區塊。
從圖 9.1 可以看出,Tendermint 可以輕松在大約一秒鐘的區塊延遲里處理每 秒數千個交易,盡管每秒大約有一萬個交易的容量限制。16384 個交易的區塊的 大小約為 4 MB,網絡帶寬分析顯示每個連接很容易達到 20MB / s 以上,盡管日 志分析表明,在高的區塊大小時,驗證者可以花費高至兩秒鐘時間等待區塊部分。 此外,如圖 9.2 所示,在單個數據中心進行的實驗表明,在更大的機器上進行的 實驗可以得到更高的吞吐量的可能,而在更大的機器上的實驗顯示出更一致的性 能,從而消除了容量限制,如圖 9.3 所示。我們將在未來進一步進行調查這一容 量限制的工作。
在隨后的實驗中,注入了各種形式的故障,并給出了延遲的統計數據。每個 實驗都是在大小為 2 的從 4 到 32 倍的驗證集,不同的 TimeoutPropose 值,和大 小為 2048 個交易的區塊上運行的。

9.3 宕機故障(Crash Failure)

為了評估一個常遭受宕機故障的網絡的性能,每 3 秒鐘 Nfault 個驗證者被隨機選擇,停止,并在三秒鐘后重新啟動。
在表 9.1 中的結果表明,在這個宕機故障場景下的性能下降了大約 50%,而更大的 TimeoutPropose 值有助于調節延遲。當平均延遲時間增加到大約 2 秒時, 中間值接近 1 秒,延遲可能高達 10 到 20 秒,但在一個情況下,它高達 70 秒。
很有可能修改時間的提議是稍微不確定的,這可能會降低這種極端的延遲的可能 性。將 TimeoutPropose 修改為稍微不確定可能會降低這種極端延遲的可能性。



9.4 隨機網絡延遲(Random Network Delay)

可能歸因于拜占庭行為或網絡異步的另一種形式的故障是在每次讀取和寫入網絡連接時注入隨機延遲。在這個實驗中,在每個網絡連接讀取和寫入之前, Nfault 個驗證者睡眠 X 毫秒,其中 X 被均勻地繪制在(0,3000)上。 從表 9.2 可 以看出,延遲與宕機故障的情況類似,盡管 TimeoutPropose 的增加有相反的效 果。由于并非所有驗證者都有故障,所以小 TimeoutPropose 值可以允許快速地 跳過錯誤的驗證者。如果所有驗證者都受到網絡延遲的影響,因為不會有無故障 的驗證者跳過,則較大的 TimeoutPropose 值會減少延遲,并且將會提供更多的 時間來接收延遲的消息。

9.5 拜占庭故障(Byzantine Failures)

通過以下修改可以將更明確的拜占庭故障注入狀態機:
·沖突提議(conflicting proposals):在提議時,拜占庭驗證者會簽署兩個沖
突的提議并且廣播兩者,并附上預投票和預提交,以將其連接的對等點分為兩半。
·無 nil 投票(no nil votes):一個拜占庭驗證者從不簽署一個 nil 投票。
·簽署每個提議(sign every proposal):一旦一個拜占庭驗證者看到一次提
議,它就為每個它看到的提議提交一個預投票和一個預提交。
綜上所述,這些行為明確地違反了雙簽名和鎖規則。然而,請注意,這種行 為主要是由相互矛盾的建議的傳播和最終它們其中之一的提交所主導的。更復雜的拜占庭戰略安排留給未來的工作。
從表 9.3 可以看出,盡管被注入了將導致許多系統立即徹底失敗的拜占庭故 障,但是,Tendermint 仍然保持著令人預期的延遲。由于這些故障與異步無關, 所以在 TimeoutPropose 上沒有實際的影響。性能也會隨著更大的驗證集而消失, 這可能是處理拜占庭投票的簡單算法的結果。

9.6 相關工作

本章中的吞吐量實驗建模在[67]中,其基準是 PBFT 實現的性能和稱為
HoneyBadgerBFT 的新的隨機 BFT 協議。在其結果中,PBFT 在四個節點上實現了 每秒超過 15000 次交易,但隨著節點數量的增加而呈指數下降,而 HoneyBadgerBFT 每秒大概達到 10000 到 15000 次交易。然而,HoneyBadgerBFT 中的區塊延遲要高得多,對于大小為 8,16 和 32 的驗證器集,更接近 10 秒,對 于更大的驗證集延遲甚至可能更大。
Jepsen 是研究一致性實現的一個著名工具,它通過模擬多種形式的網絡分區 來測試數據庫的一致性保證。用 Jepsen 測試 Tendermint 是留給未來的一個令人 興奮的領域的工作。
面對持續的拜占庭故障,作者并沒不了解任何的吞吐量實驗,就像其他在這里描述的那樣。

9.7 結論

由作者和 Jae Kwon 編寫的 Tendermint 的實現輕松地在分布在全球范圍內機器上的多至 64 個節點上達到了每秒數千筆的交易,延遲主要在 1 到 2 秒范圍內。 這比其他解決方案更具競爭力,尤其是在區塊鏈的目前狀態,例如,比特幣的上 限為每秒 7 筆交易。此外,我們的實現被證明對崩潰故障、消息延遲和故意的拜 占庭故障都很魯棒,能夠在每個場景中保持每秒超過 1000 個交易。

Chapter 10

相關工作
拜占庭一致性算法有著豐富的歷史,包括密碼學、分布式計算和經濟學,但其部署在工業上的產品的社會經濟背景直到最近才出現,至少在傳統的關鍵實時 系統之外,比如飛行器控制。一方面,比特幣的發明和“區塊鏈”一詞的產生, 使一種不受單一實體控制的分布式分類帳的概念得到普及,使用密碼學和一致的經濟激勵措施來保護面對拜占庭故障的安全性。另一方面,服務器的持續商品化, 以“云(The Cloud)”的形式,以及 Raft 的發明,在主流開發者文化中推廣了 分布式計算,并再次把關注點引向分布式一致性算法使得成為在大規模部署中的協調中心。
在這個十字路口,有一系列的解決方案,通常適用于銀行和金融應用,也適用于治理,物流和其他一般的協調形式,借鑒經典學術 BFT 修改的和現代化的各種方式。本章回顧了這些想法的歷史和多樣性,目的是提供一個豐富的背景來理 解區塊鏈現象。

10.1 開始

分布式算法首先出現在 19 世紀后期的電信和鐵路行業,試圖有效地處理傳輸中的多個并發消息流,或者是同一組軌道上的多個列車。 關于這個問題的學術研究似乎是由 Edsger Dijkstra 在互斥問題上的開創性工作和 Tony Hoare 在描述通信進程的模型發起的。 在這段時間里,一系列有好記名字的并發性問題都得到了推廣,其中包括吸煙者的問題,吸煙者圍坐在一張桌子周圍,每個人都有不同的原料,并且必須成 功地卷一支完整的香煙;哲學家就餐問題,坐在桌子周圍的哲學家必須輪流吃飯 和思考,但每個人只能在他的鄰居都在思考時才能吃飯;兩軍問題或協同攻擊問 題,兩名將軍必須同時從遠處協調進攻一個敵人的城市。
這些問題將重點放在如如信號量、互斥和通信信道的同步原語上,并將為未來幾十年的許多改進打下基礎。

10.1.1 故障(Faulty Things)

在 70 年代末,容錯分布式計算有效地出現在了利用微處理器進行飛機控制的努力中,從而產生了許多早期的系統。今天,它成為為了 NASA 對 BFT 研究的標 準和商用飛機對 BFT 系統,如 SAFEbus,的使用。
然而,許多系統不需要容忍拜占庭故障,因為它們在受控環境中運行時,可 能不存在惡意行為,而且代碼是正確編寫的。在這種情況下,在像谷歌或 Amazon 這樣的大公司管理的數據中心中,容錯計算被用來防御無論是網絡鏈接中斷,還 是服務器機架的電源故障,亦或是是硬盤報廢的各種錯誤是很常見的。

10.1.2 時鐘(Clocks)

然而,在 Leslie Lamport 在他的“時間、時鐘和分布式系統中的事件排序”中引入了分布式一致性的問題時,才正式出現。在那項工作中,Lamport 演示了如 何從基于通信的因果關系的定義中產生局部的事件排序。也就是說,發生在在通 信事件之間的并發進程中的事件,實際上發生在同一時間,因為它們不能相互影 響。因此,一個邏輯時鐘系統可以根據個人的順序進程和消息在接收前發送的事 實來定義。然后,可以通過在局部排序之上分配任意但一致的總排序來完全排序 事件,例如,通過為系統中的每個進程分配一個索引和排序事件,這些事件發生 在同一邏輯時間內,由它們所發生的進程的索引進行。該算法相當簡單,要求每 個進程從彼此的進程中獲得消息,以確定事件的順序。
Lamport 的工作確立了時間作為設計容錯分布式系統的主要障礙,因為在地 理位置上同步時鐘需要信息的通信,而這些信息最終受到光的速度的限制。這個問題的形成與現代物理學的相對論有密切的聯系,其中參考系和觀察者相關,而 光的速度限制了信息傳播。

10.1.3 FLP

如第 2 章所述,設計一致性算法的主要因素之一是關于網絡和/或處理器同步的假設。同步網絡是指在固定的已知時間內傳遞消息的網絡。類似地,同步處理 器的時鐘是保持在某些固定的、已知的相互運轉數目之間的。在早期的一致性研 究中,盡管在異步和宕機故障之間的密切關系是很明顯的,這一區別并沒有被很 好的定義。Lamport 最初的協商一致算法能夠在異步環境中運行,只要所有的消 息最終都可以從每個進程中傳遞。然而,該算法顯然不是容錯的,因為僅僅一個 進程的失敗就可以永久地終止該算法。
由 Fischer、Lynch 和證明了在異步環境中即使有個單獨的進程失敗,決定性 分布式一致性的都是不可行的 Patterson,正式地提出了在一個單獨故障阻撓的 一致性協議基礎上的直覺。結果并不適用于同步上下文,因為關于網絡同步的假 設允許處理器使用超時來檢測故障,這樣如果某個進程在給定的時間內沒有響應, 則假定它已經崩潰。此外,這個結果只適用于決定性一致性協議,因為它的證明 依賴于網絡從一個二價狀態,即不是所有的進程都持有相同的值,到一種單價的 狀態,即它們都持有相同的值,變成決定性的時刻。由于轉換點是時間上的一個 決定性的點,如果一個單獨的進程恰好在那個時刻崩潰,那么一致性就會失敗。

10.1.4 常見幣(Common Coin)

FLP 的結果成為了分布式系統科學家的警鐘,在新興領域的心臟地帶建立了一個明顯的不可能的結果。之后,這種方法將推廣到更多不可能的結果,并將花 費大量的學術研究來放松同步或決定論假設,以推導出繞過結果的算法。
特別地,在簡短的說明中,Ben Or 演示了包含簡單量的非確定性的算法可以 如何規避 FLP 結果。該算法容忍異步環境中多達一半進程的故障。從本質上說, 為了在單個比特的值上達成一致,如果一個進程沒有從同一個價值的多數獲得投 票,那么它會隨機地改變它下一輪投票的值。隨著每個人都在改變價值觀,最終 一半以上都會投同樣值的票。由于與公有地翻轉硬幣以獲得一個共享的值的過程 相似,這種方法被認為是一種常見幣(common coin)。
Ben Or 的 common coin 的問題在于,在異步情況下,算法需要在驗證者數量 上以指數形式來表示。這被 Rabin 的后續行動迅速糾正,Rabin 表示,如 Shamir 首創的,common coin 可以用秘密共享的方式構建。該方法對于 BFT 也是有用的, 并且在后面的章節中將更詳細地討論。

10.1.5 交易處理(Transaction Processing)

同步開發容錯一致性算法是第一個商業數據庫系統的出現形式。雖然他們沒有首先使用正在開發的一致性協議,但他們是在分布式計算和并發的不斷增長的 工作體之上構建的。特別是 Jim Gray 的開創性工作,他將這個術語,交易 (transaction),作為一個數據庫系統中的原子工作單元引入。也就是說,一個 交易要么完全應用,要么根本不應用。
Grey 還介紹了其他現代數據庫的經典特征,如原子性(Atomicity)、一致性 (Consistency)、隔離性(Isolation)和持久性(Durability)的原則,也是交易
(transaction)概念的一部分和包裝,以及為了在被執行前把交易日志記錄到磁 盤上以便從在交易執行時才是的錯誤中恢復而使用的 write-ahead-logs。
在分布式數據庫設置中,這種處理交易、原子性和一致性的工作導致了一系 列以原子提交(atomic commit)的概念為中心的數據庫復制的方法,其中交易 在所有機器上都以原子方式復制。這些方法被稱為兩階段提交 (two-phase-commit),以及它的非區塊替代,三階段提交(three-phase-commit)。
兩階段提交和三階段提交協議都只在同步設置中工作,在那里可以檢測到宕機故障,并利用協調進程作為協議的領導者。

10.1.6 廣播協議(Broadcast Protocols)

第 2 章介紹了兩個最重要的廣播協議,RBC 和 ABC。在[27]中提供了對該問題解決方案的分類和調查。

10.2 拜占庭(Byzantine)

許多容錯協議只關注宕機故障,因為它們是最常見的,而對于潛在的任意的問題,包括惡意軟件的行為,卻很少關注。這個更普遍的問題被稱為拜占庭容錯。

10.2.1 拜占庭將軍(Byzantine Generals)

Lamport 在[78]中引入了拜占庭容錯問題,但是在后來的論文中,因為面對拜占庭軍隊協調攻擊敵方城市的問題做出分析,才給它起了名字。軍隊由多個部門 組成,每個部門由一個將軍領導。將軍之間的交流只能通過信使進行。如果一名 或幾名將軍是叛徒,那么將軍如何達成共同的行動計劃?
原始論文提供了能夠容忍 f 個拜占庭的故障的第一種證明,系統必須具有至 少 3f + 1 個節點。這一結果基礎上的直覺如圖 2.2 所示,并在第 2 章和第 3 章中 進行了討論。這兩篇論文中提供了許多算法作為問題的第一個解決方案,盡管它 們被設計為僅在同步情況下工作,其中可以檢測到不存在消息。

10.2.2 隨機共識(Randomized Consensus)

異步拜占庭式一致性以 Ben Or 和 Rabin 介紹的 common coins 的形式出現了第一個解決方案。然而,這兩種解決方案都不能達到3f +1個機器中有f個故障的 最佳拜占庭容錯能力。Ben Or 的解決方案需要 5f + 1 臺機器,而 Rabin 需要 10f + 1 臺機器。該解決方案被迭代地改進,以達到以低的開銷優化拜占庭。

10.2.3 局部同步(Partial Synchrony)

BFT 的下一個重大進展是所謂的 DLS 一致性算法的形式,是以作者 Dwork,Lynch 和 Stockmeyer 命名的。DLS 的創新是定義稱為局部同步(partial synchrony) 的在同步和異步之間的中間地帶(middle ground)。局部同步的秘訣是假設以下 之一:
·消息保證在一定固定但未知的時間內傳送。
·從未來的某未知的時間開始,消息保證在一段已知的時間內交付。
DLS 算法通過一系列回合進行,每一回合分為嘗試(trying)和鎖定釋放
(lock-release)階段。每一回合都有一個相應的提議者,如果他們認為提議者會 提出這個值,進程可以在這一輪鎖定這個值。一回合開始于進程廣播它們可以接 受的值。如果提議者從至少 N – f 個可接受該值的進程中收到來信,它即可以提出這個值。任何接收提議值的進程都應該鎖定它,并發送一個確認消息表示它已 經這樣做了。如果提議者接收到 f + 1 個進程的確認,它就會提交該值。
對基本協議的變化進行了不同的假設組合的討論,并提供了許多證明。然而,盡管它取得了成功,但 DLS 算法從未被廣泛用于 BFT。Tendermint 最初的設計是基于 DLS 的,更確切的說采用的是假設一個局部同步網絡但是全部同步處理器時 鐘的版本。實際上,由于使用了像網絡時間協議 Network Time Protocol (NTP)這 樣的協議,同步時鐘可能是一個合理的假設。然而,NTP 很容易受到一系列攻擊, 而且假設同步時鐘的協議從宕機故障中恢復得很慢。在 2015 年夏天,核心的 Tendermint 一致性協議被重新設計為更加完全的異步,如第 3 章所描述的,因此 它變得更加接近于另一種 BFT 算法,即實用拜占庭容錯 Practical Byzantine Fault Tolerance (PBFT)。

10.2.4 PBFT

PBFT 在 1999 年被引入,被廣泛認為是第一個實用的 BFT 算法,適合在異步網絡中使用,盡管它實際上會產生微弱的可能會被一個謹慎的對手所違背的同步假設。PBFT 通過一系列視圖進行,每個視圖都有一個提議者,稱為主視圖 (primary),它是按回合順序選擇的。主視圖從客戶端接收請求,分配它們一個序列號,然后廣播一個簽署過的預準備(pre-prepare)消息到其他包含視圖和 序列號的進程。如果副本還沒有接受相同的視圖和序列號,它們就接受預準備消 息,假設消息是針對當前視圖并由正確的主視圖簽名的。
一旦一個 pre-prepare 被接受,一個副本廣播一個簽署過的準備消息(prepare message)。當一個副本收到一個給定客戶端的具有相同視圖和序列號的請求的 2f 個 prepare messages 時,這個副本就可以說是準備好的了(prepared)。預準備(pre-prepare)和準備(prepare)的組合根據其序列號確保單個視圖中的請求的總序性(total order)。一旦一個副本已經準備好(prepared),它會廣播一個簽署過的提交消息(commit message),只要它被正確簽名并且視圖是正確的,它就被接受。當一個副本接受提交消息時,它會針對狀態機運行客戶端請求,并將結果返回給客戶端。
PBFT 采用了一種額外的機制,以方便在主視圖故障時幫助視圖更改。副本維持一個超時,每次接收新客戶端請求時重新啟動,并在收到該請求的 pre-prepare 時終止。如果沒有收到 pre-prepare,則副本超時,并觸發視圖更改協議。視圖 的變化是微妙的,而且有些復雜,因為它需要視圖應該進行更改的一致性,并且自從上次提交的所有客戶端請求都必須被引入新的視圖。
Tendermint 通過使用區塊并更換每個區塊的提議者來回避了這些問題,允許 使用與提交提議的區塊相同的機制來跳過一個提議者。此外,區塊的使用允許 Tendermint 在下一個區塊中包含上一個區塊預提交的消息集,消除了顯式提交消息的需要。

10.2.5 BFT 改進

自從 PBFT 被發表以來,許多改進方案已經被提出來。其中一些關注在所謂的樂觀執行(optimistic execution)上,這樣交易可以在它們被提交以前執行以便 為客戶端提供低延遲和樂觀的回復。這些方法的問題在于,管理不一致性的責任 被轉移到客戶端,然而可能他們在一開始使用一致一致性協議(consistent consensus protocol)的原因就是為了避免這種責任。或者,在低故障情況下,這可能是一種有用的方法。這種現象在比特幣中被稱為 zero-conf 交易,并受到廣泛的警告,鑒于接受交易的不安全性已經在它們之前提交了足夠的工作。
其他人則專注于同時運行獨立交易的可能性,以實現更高的吞吐量。這是在區塊鏈社區中開始研究的方法,尤其是以太坊,以便產生可擴展的區塊鏈結構。

10.3 非拜占庭

與 BFT 算法并行,出現了一些非 BFT 算法,并且已經建立了一些重要的高可用性互聯網服務。

10.3.1 Paxos

在一致性科學中,人們通常認為,只有一種一致性算法,即 Paxos。這一方面說明了 Paxos 算法對該領域的重要性,另一方面是對共識一致性協議的普遍基礎的反射,這在每種情況下都是“類似 Paxos(Paxos-like)”的。
Lamport 在九十年代初期引入了 Paxos,盡管那篇文章直到將近十年以后才被 接受發表。許多人已經指出,該算法實際上與上世紀八十年代末期出版的 Viewstamped Replication 極為相似,并且兩者都代表了相同協議的獨立發現。
這些協議與之前的 PBFT 非常相似,但只需要 2f + 1 臺機器就能夠容忍 f 個故障,如同它們不是 BFT。另一個類似的協議,Zookeeper 原子廣播協議(ZAB)是 為 Apache Zookeeper 分布式鍵值存儲開發的。在[99]中,每個算法的相似性和差 異性都有所闡釋。

10.3.2 Raft

引進 Raft 后,非 BFT 一致性科學得到了重大改進,這一設計是從根本上可以理解的,通過用戶調查證明了它甚至比 Paxos 更容易理解。
Raft 在精神上類似于 Paxos 和 Viewstamped Replication,但它強調復制一個交易日志,而不是一個單個的比特,并引入隨機化來進行更有效的領導者選舉。此 外,Raft 的安全性保障已經使用 Coq 證明助手(Coq proof assistant)和一個在 Coq 上面構建的以正式驗證分布式系統的框架,Verdi,正式地證明過了。Verdi 將如何與基于過程演算的方法進行比較還有待觀察。

10.4 區塊鏈(Blockchain)

本文的主要動機是介紹以比特幣形式出現的區塊鏈技術,和從此看到的許多迭代。 直到最近才有人成功地將區塊鏈置于經典一致性科學的背景下。

10.4.1 比特幣(Bitcoin)

在[71]中介紹的,比特幣是第一個區塊鏈。它通過巧妙地利用經濟學在公開的對抗設置中解決了原子廣播問題。特別地,交易順序是由解決部分哈希沖突的人 提出的,其中被散列的數據是交易的區塊。由于計算部分哈希沖突是昂貴的,需要在大空間中進行強力搜索,所以這種努力通過每個區塊的發行貨幣,比特幣,進行補貼。該協議已經非常成功,貨幣已經達到十億美元市值,原有的克隆產品市值也達數百萬。
然而,比特幣并非沒有問題。一些設計缺陷使應用程序開發人員很麻煩也很難使用它。此外,一些學術著作也闡明了協議中的激勵不相容問題,削弱了人們對該協議的安全性的普遍假設。
很多方法被提出以改善比特幣,包括那些對部分哈希碰撞函數性質的改變, 那些為了改善許多經濟學和潛在性能的特征而對協議中領導者選舉的性質的改 變以及那些旨在實現可伸縮性對協議進行的討論。

10.4.2 以太坊(Ethereum)

以太坊由 Vitalik Buterin 引出,作為 Bitcoin 之后的一種加密貨幣的擴散的解決方案,具有不同的功能。以太坊尋求更純粹的任務:沒有功能。 相反,以太坊 提供了一個圖靈完整虛擬機(Turing complete virtual machine),即以太坊虛擬 機 Ethereum Virtual Machine (EVM),用于在一致性之上執行交易,并為用戶上傳 代碼到可以在將來的交易處理中執行的 EVM 上提供了一種手段。所謂的智能合 同(smart contracts)使用強大的密碼學和 BFT 復制提供了在公共設置中自動執 行代碼的承諾。以太坊項目在迄今為止規模最大的眾基金(crowd-funds)之一 中取得了成功,超過了 1800 萬美元,而它的本地 token(用于支付交易執行和 代碼上傳的費用)的市值已經達到 10 億美元。
Ethereum 目前使用一種叫做貪婪最終觀察子樹 Greedy Heaviest Observed Sub Tree (GHOST)的 Proof-of-Work 的修改形式,但正計劃轉向圍繞 Proof of Stake 建 模的更安全的經濟一致性算法。

10.4.3 Proof-of-Stake

Proof-of-Stake (PoS)最開始作為在 PPCoin 中使用 Proo-of-Work 的一種替代方案被提出來。在 PoS,提議由那些可以證明網絡中硬幣獎金的所有權的人提出并 投票。雖然消除了 PoW 的過高成本,但對于 PoS 的樸素實現很容易受到所謂的 “nothing-at-stake”的攻擊,在給定的高度,驗證者可以在多個區塊上提議和投 票,從而導致了嚴重的安全性的違背,沒有任何激勵以收斂。雖然樸素 PoS 的問 題眾所周知,但許多流行的加密貨幣仍在使用它。
Nothing-at-stake 問題可以通過一個名為 slasher 的機制進行糾正,即驗證者必 須交一個安全保證金,以便有資格驗證塊,這樣可以在發現驗證者提議或投票支 持沖突區塊時削減它的押金。Tendermint 是這種方法的第一個實現,盡管其他的 BFT 算法也可以發揮作用。
10.4.4 超級賬本(HyperLedger) 比特幣、以太坊和其他加密貨幣的成功激發了社會越來越多元化的領域,包括監管機構、銀行家、企業高管、審計人員、客戶經理、物流師等等。尤其是, Linux 基金會(Linux Foundation)最近發起的一個項目,由 IBM 和一家名為“數 字資產控股”(Digital Asset Holdings, DAH)的新成立的以區塊鏈為基礎的新公司, 旨在為工業應用提供一個統一的區塊鏈架構。這個項目被稱為“超級賬本” (HyperLedger),以一個同名的公司命名,該公司提供了一個基于 PBFT 的區塊 鏈的基本實現,已經被 DAH 收購。
對 HyperLedger 倡議的兩項貢獻尤為相關。第一個是 JP Morgan 團隊運作的 Juno 和 Hopper 的合并。Juno 是 Tangaroa(一個 BFT 版本的 Raft)的實現。Hopper 是一個新的虛擬機設計,基于線性邏輯(linear logic)和依賴類型系統(dependent type system),它的目標是為對于得出和證明關于系統狀態的陳述或者合同行為 而配備的一個正式的邏輯的智能合同系統提供一個執行環境。Juno 和 Hopper 都 是用 Haskell 寫的。
另一個項目是 IBM 的 OpenBlockchain,一個由 Go 編寫的基于 PBFT 的區塊鏈,它的應用程序狀態支持任意 docker 容器的部署。由于任意 docker 容器可能包含非決定性,它們的 PBFT 實現用在可能的非決定性執行的情況下保護安全性的額 外步驟來修改。
IBM 的另一個相關貢獻是最近的一篇評論文章,類似于本章。

10.4.5 HoneyBadgerBFT

盡管在異步環境中運行良好,所有與 Paxos-like 的一致性協議,包括 Raft、PBFT 和 Tendermint,都不是完全異步的。這是因為每個協議都在協議的某個地方使用超時,通常是為了檢測故障領導者。另一方面,像 common coin 這樣的隨機一致 性協議提供了在完全異步環境中,沒有超時的解決方案。
所有一致性協議都以某種方式依賴于最終消息的傳遞。異步的假設簡單地指 出,沒有消息被傳遞的上限。大多數時候,網絡行為是同步的,在某種意義上,大多數消息是在一定范圍內傳遞的。完全異步協議與有超時協議之間的差異在于, 當網絡同步運行時,異步協議總能取得進展。這一點在[67]中清楚地顯示,其中引 入了 HoneyBadgerBFT,第一個完全異步區塊鏈設計,基于 common coin 一致性。
對網絡進行任意控制的對手以及一次可以使得任何一個節點崩潰的能力可能導致 PBFT 任意長時間停止。這可以通過在網絡同步時崩潰當前的主視圖/提議者 /領導者,并將其恢復為異步的時間段來完成。網絡仍然最終傳遞消息,具有一 些平均的同步性,但是精確的時序可以停止所有的系統進程。在 PBFT 的直接實 驗在[67]中,并且與 Tendermint 工作類似。
HoneyBadgerBFT 利用一系列加密技術,包括秘密共享,擦除編碼和閾值簽名, 以設計出高性能異步 BFT 一致性協議來克服這種困難,因為它是完全無領導的而 導致的沒有任何同步的假設。然而,它需要一個受信任的經銷商(dealer)進行 初始設置和驗證者變更,并且它依賴于尚未經得起時間考驗的某些問題的難度的 相對新的加密假設。

10.5 結論

Tendermint 出現并補充了豐富的一致性科學的歷史,涵蓋了同步和容錯假設的范圍。 區塊鏈和 Raft 的發明重新啟動了一致性的研究,并產生了新一代通過 互聯網協調的協議和軟件。

Chapter 11

總結
拜占庭容錯一致性提供了一個豐富的基礎,用來構建不依賴于集中式、可信任方的以及可能被社會用來管理社會經濟基礎設施的關鍵組成部分的服務。本文中提出的 Tendermint,旨在滿足這些系統的需求,并以可理解的安全性和易于高 性能的方式以及允許任意系統按一致性協議和最少的無關事進行交易來進行設計。
在部署分布式一致性系統時,需要謹慎考慮,尤其是在沒有中央授權的情況下,在危機發生時調解潛在的爭端并重置系統。Tendermint 試圖通過明確的治理 模塊和問責保障制度來解決這些問題,使 Tendermint 部署融入到現代法律和經 濟基礎設施中。
現在仍然有許多工作要做。這其中包含算法保證的正式驗證,性能優化,以及架構變更以使得系統用額外的機器增加容量。而且,當然,還有許多許多 TMSP 的應用要構建。
我們希望本文更好的解釋了在分布式一致性算法和區塊鏈架構中的問題,并且啟發其他人建立一些更好的東西。

總結

以上是生活随笔為你收集整理的Tendermint: Byzantine Fault Tolerance in the Age of Blockchains的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。