Tendermint共識算法和用于原子廣播( atomic broadcast)的相關(guān)區(qū)塊鏈。拜占庭容錯共識問題將被詳細討論,并且Tendermint共識的一個正式說明將以π-calculus的形式給出。Tendermint區(qū)塊鏈已經(jīng)被非正式地證明為滿足原子廣播。將來我們將以進程演進的方式來描述完整的區(qū)塊鏈協(xié)議,并證明相關(guān)特性。區(qū)塊鏈時代的拜占庭容錯:Tendermint(一)
Tendermint綜述
Tendermint是區(qū)塊鏈范式中的一個安全的狀態(tài)機復(fù)制算法。其算法形態(tài)為BFT-ABC,并且附加責任制,便于驗證拜占庭節(jié)點的不誠實行為。
Tendermint算法給每個區(qū)塊賦予一個增量索引或者高度(height),在某一高度中只存在一個有效的區(qū)塊,區(qū)塊鏈從高度為0的創(chuàng)世紀塊開始,由一個驗證者集合投票產(chǎn)生下一個區(qū)塊,其中每一個驗證者由各自的公鑰標識。每一個驗證者需要維護一份完整的復(fù)制狀態(tài)的拷貝。在投票產(chǎn)生某一高度的區(qū)塊的過程中,在正式提交(commit)某一高度的區(qū)塊之前,至少需要經(jīng)過一輪(round)投票(vote)來達成共識。每一輪都會通過round robin的方法產(chǎn)生一個提議者(proposer),該提議者在當輪以廣播的形式提出一個提議(proposal),提議經(jīng)過驗證者的集體投票,來決定是否最終提交該區(qū)塊或者進入下一輪。在提議的區(qū)塊真正被提交(commit)之前,驗證者們需要進行兩輪投票(pre-vote & pre-commit), 通過一個簡單的鎖機制用來阻止少于總數(shù)1/3的拜占庭節(jié)點攻擊。由于Tendermint網(wǎng)絡(luò)的不同時性(asynchrony),當拜占庭節(jié)點超過總數(shù)的1/3,網(wǎng)絡(luò)存在癱瘓的可能性。
注意到,tendermint的多輪投票機制的核心是共識算法。每一個區(qū)塊包含一些元數(shù)據(jù)(metadata),稱作區(qū)塊頭(header)。區(qū)塊頭里包含本區(qū)塊的高度,提議時間,本區(qū)塊所有交易的梅克爾根哈希值。
共識
共識算法可以大致分為以下幾部分:
提議(Proposals):在每一輪(round)中,新區(qū)塊的提議者必須是有效的,并且告訴(gossiped)其他驗證者。如果在一定時間內(nèi)沒有收到當輪提議(proposal),當前提議者將被后面的提議者接替。
投票(Votes):兩階段的投票基于優(yōu)化的拜占庭容錯。它們分別被稱作預(yù)投票(pre-vote)和預(yù)提交(pre-commit)。對于同一個區(qū)塊同一輪如果存在超過2/3的預(yù)提交(pre-commit)則對應(yīng)產(chǎn)生一個提交(commit)。
鎖(Locks):在拜占庭節(jié)點數(shù)少于節(jié)點總數(shù)的1/3的情況下,Tendermint中的鎖機制可以確保沒有兩個驗證者在同一高度提交(commit)了兩個不同的區(qū)塊。鎖機制確保了在當前高度驗證者的下一輪預(yù)投票或者預(yù)提交依賴于這一輪的預(yù)投票或者預(yù)提交。
為了應(yīng)對單個拜占庭故障節(jié)點,Tendermint網(wǎng)絡(luò)至少需要包括4個驗證者。每個驗證者擁有一對非對稱密鑰,其中私鑰用來進行數(shù)字簽名,公鑰用來標識自己的身份ID。驗證者們從公共的初始狀態(tài)開始,初始狀態(tài)包含了一份驗證者列表。所有的提議和投票都需要各自的私鑰簽名,便于其他驗證者進行公鑰驗證。
驗證人在發(fā)起提議(proposal)步驟之后,當且僅當收到其它驗證人超過三分之二(+2/3)的投票后才會進一步推進流程。虛線箭頭表示進入下一個區(qū)塊高度共識流程的原子廣播。
共識開始于第0輪,第一個提議者(proposer)是區(qū)塊鏈頭里驗證者列表里的第一個驗證者。每一輪最終要么完成了一個提交(commit),要么直接進入當前高度的下一輪,每一輪都會產(chǎn)生一個新的提議者。
與其他選舉(leader election )算法不同,Tendermint每一輪都會產(chǎn)生一個新的提議者(proposer),驗證者投票決定是否進入下一輪,這與接受提議的流程類似。
每輪的開始對同步有弱的依賴性。每一輪開始期間,存在一個用來計時的本地同步時鐘,如果驗證者在TimeoutPropose時間內(nèi)沒有收到提議,驗證者將參與投票來決定是否跳過當前提交者。TimeoutPropose會隨著輪數(shù)的增加而增加。
每輪收到提議以后,進入完全異步模式。之后驗證者的每一個網(wǎng)絡(luò)決定需要得到2/3驗證者以上的同意。這樣降低了對同步時鐘的依賴或者網(wǎng)絡(luò)的延遲。但是這也意味著如果得不到1/3以上驗證者的響應(yīng),整個網(wǎng)絡(luò)將癱瘓。
簡言之,每輪,開始提議弱同步,之后投票完全異步。
為了增強Tendermint共識網(wǎng)絡(luò)的安全性,引入了少量的鎖定規(guī)則(locking rules)來迫使驗證者自證其投票的合法性。盡管我們不需要實時廣播他們的合法證明,但是我們確實期望驗證者們保存相關(guān)數(shù)據(jù)。這樣當網(wǎng)絡(luò)被拜占庭故障節(jié)點癱瘓時,其可以存留為相關(guān)證據(jù)。這個問責機制確保在網(wǎng)絡(luò)故障(例如PBFT)的時候Tendermint具有一個更健壯的擔保(guarantees)。
驗證者使用一組不同的消息(messages)來管理區(qū)塊鏈,應(yīng)用程序狀態(tài),p2p網(wǎng)絡(luò)和共識。其中,核心的共識算法包含兩類消息:
ProposalMsg: 對應(yīng)某一高度及某一輪數(shù)的區(qū)塊的提議(proposal),該提議已經(jīng)由提議者簽名
VoteMsg: 對某一提議的簽名投票
一。 提議
每輪開始于一個提議(proposal),提議者從內(nèi)存池(Mempool)選取一批交易進而構(gòu)成了一個區(qū)塊,該區(qū)塊隨后被嵌套在ProposalMsg中,最后提議者廣播(broadcast)ProposalMsg。如果這個提議者是拜占庭節(jié)點,他可能向不同的驗證者廣播不同的ProposalMsg。
提議者通過一個簡單并且相對固定的的roubd robin輪流坐莊,所以每一輪只有一個有效且被所有驗證者公認的提議者。如果驗證者收到了之前更低輪次的提議或者提議來自于非法的提議者,該提議將被拒絕。
提議者的輪流坐莊對于拜占庭容錯是必要的。比如,對于raft算法,如果選舉出來的leader是拜占庭,并且leader與其他節(jié)點網(wǎng)絡(luò)連接狀態(tài)良好,該leader可以完全控制整個網(wǎng)絡(luò),網(wǎng)絡(luò)節(jié)點的安全和正常運轉(zhuǎn)將無從得到保障。Tendermint通過投票和鎖的機制(voting and locking mechanisms )確保了系統(tǒng)的安全性。如果一個提議者在限定時間內(nèi)沒有處理任何交易,排在其后的提議者將會接替他。更有趣的是驗證者能通過治理模塊投票來移出或者替換拜占庭驗證者。
二。 投票
一旦驗證者從網(wǎng)絡(luò)中收到了一份完整的提議(proposal ),他對該提議進行預(yù)投票(pre-vote)簽名,并且廣播到網(wǎng)絡(luò)中。如果驗證者在ProposalTimeout時間內(nèi)沒有接收到一個有效的提議,其對該提議的預(yù)投票為空(nil)。
在存在拜占庭節(jié)點的異步環(huán)境中,單階投票,即每個驗證者對每個提議只投一次,不能足以確保整個系統(tǒng)的安全。本質(zhì)上,因為驗證者可能做出一些不誠實的行為,并且消息的到達時間沒有任何保障,一個不誠實的驗證者可以與其他驗證者進行協(xié)作來提交(commit)一個區(qū)塊,然而其他沒有看到這個提交區(qū)塊的驗證者進入了新的一輪,并提交(commit)了一個不同的區(qū)塊。
一個單階的投票允許驗證者互相溝通他們知道的關(guān)于該提議的信息。但是為了容忍拜占庭故障,他們也需要互相告訴對方他們自己了解到的其他驗證者聲稱了解到的關(guān)于該提交的信息。換句話說,二階段提交確保了足夠的驗證者見證了第一階段的結(jié)果。
對于某個區(qū)塊的非空預(yù)投票是為網(wǎng)絡(luò)提交(commit)區(qū)塊已做好準備的投票??疹A(yù)投票是為網(wǎng)絡(luò)直接進入下一輪的投票。在理想的一輪中,超過2/3的驗證者為該提議進行了預(yù)投票。在任意一輪中,區(qū)塊具有的超過2/3的預(yù)投票被稱作一個波爾卡(polka)。超過2/3的空預(yù)投票成為空波爾卡(nil-polka)。
當一個驗證者收到了一個波爾卡(polka),他接受到了一個信號,即網(wǎng)絡(luò)準備提交該區(qū)塊,作為一個驗證者簽名并且廣播預(yù)提交(pre-commit)的背書。有時,由于網(wǎng)絡(luò)的不同時性,驗證者可能沒有收到對應(yīng)的波爾卡或者波爾卡根本就不存在。在這種情況下,驗證者沒有對應(yīng)的波爾卡為這個預(yù)提交背書,此時預(yù)提交為空。也就是說,在沒有收到波爾卡背書的情況下,簽名一個預(yù)提交被看作是一個惡意行為。
預(yù)提交(pre-commit)是關(guān)于提交(commit)一個塊的投票??疹A(yù)提交則投票進入到下一輪。如果驗證者收到2/3以上驗證者的預(yù)提交,則其在本地提交該塊,計算結(jié)果狀態(tài),并移動到下一高度的第0輪。如果驗證者接收到超過2/3的空預(yù)提交,則投票進入下一輪。
三。 鎖
多輪投票的安全問題是棘手的,必須避免同一高度不同輪數(shù)分別提交兩個不同區(qū)塊的情形。在Tendermint中,這個問題可以通過鎖機制(locking mechanism)得到解決。鎖機制的大致定位在波爾卡附近。本質(zhì)上,預(yù)提交必須有一個波爾卡為其背書,驗證者被鎖定在其最近預(yù)提交(pre-commit)的區(qū)塊上。
鎖定規(guī)則:
預(yù)投票鎖(Prevote-the-Lock):驗證者只能預(yù)投票(pre-vote)他們被鎖定的區(qū)塊。這樣就阻止驗證者在上一輪中預(yù)提交(pre-commit)一個區(qū)塊,之后又預(yù)投票了下一輪的另一個區(qū)塊。
波爾卡解鎖(Unlock-on-Polka ):驗證者只有在看到更高一輪(相對于其當前被鎖定區(qū)塊的輪數(shù))的波爾卡之后才能釋放該鎖。這樣就允許驗證者解鎖,如果他們預(yù)提交了某個區(qū)塊,但是這個區(qū)塊網(wǎng)絡(luò)的剩余節(jié)點不想提交,這樣就保護了整個網(wǎng)絡(luò)的運轉(zhuǎn),并且這樣做并沒有損害網(wǎng)絡(luò)安全性。
簡單來說,驗證者可以被看作鎖在任意高度-1輪的nil-block上,所以波爾卡解鎖意味著驗證者不能預(yù)提交一個新高度的區(qū)塊直到他們看見一個波爾卡。
這些規(guī)則可以以例子的形式被更直觀的理解。考慮4個驗證者,A,B,C,D,假設(shè)有一個第R輪關(guān)于blockX的提議?,F(xiàn)在假設(shè)blockX已經(jīng)有一個波爾卡,但是A看不見它,預(yù)提交(pre-commit)為空,然而其他人對blockX進行了預(yù)提交。進一步假設(shè)只有D看見了所有的預(yù)提交,然而其他人并沒有看見D的預(yù)提交(他們只看見他們的預(yù)提交和A的空預(yù)提交)。D現(xiàn)在將要提交(commit)這個區(qū)塊,然而其他人進入到R+1輪。由于任何驗證者都可能是新的提議者,如果他們提議并投票了一個新的區(qū)塊blockY,他們可能提交這個區(qū)塊??墒荄已經(jīng)提交了bockX,因此損害了系統(tǒng)的安全性。注意,這里并沒有任何拜占庭行為,僅僅是不同時性。
鎖定解決了這個問題通過強迫驗證者粘附在他們預(yù)提交(pre-commit)的區(qū)塊上,因為其他的驗證者可能居于這個預(yù)提交進行了提交(如上例中的D)。本質(zhì)上,在任何一個節(jié)點一旦存在超過2/3預(yù)提交(pre-commit),整個網(wǎng)絡(luò)被鎖定在這個區(qū)塊上,也就是說在下一輪中無法產(chǎn)生一個不同塊的波爾卡。這是預(yù)投票鎖的直接動機。
當然這里必須有相應(yīng)的解鎖方式。假設(shè)在某一輪中,A和B預(yù)提交(pre-commit)了blockX,與此同時C和D的預(yù)提交為空。因此所有的驗證者進入到下一輪,預(yù)提議(pre-vote)blockY。假設(shè)A是拜占庭,為blockY也進行了預(yù)投票(不考慮其被鎖在blockX上),導(dǎo)致了一個波爾卡。假設(shè)B并沒有看見這個波爾卡,預(yù)提交為空,此時A下線,C,D預(yù)提交bolckY。他們進入到下一輪,但是B仍然被鎖定在blockX上,C和D被鎖定在blockY上。這時因為A下線了,他們將永遠得不到一個波爾卡。因此即使在拜占庭節(jié)點少于1/3的情況下,這里網(wǎng)絡(luò)的正常運轉(zhuǎn)仍然受到了影響。
解鎖的條件是1個波爾卡。一旦B看見了blockY的波爾卡(用來為C和D的關(guān)于blockY的預(yù)提交背書),他應(yīng)當能夠解鎖并預(yù)提交(pre-commit)blockY。這是波爾卡解鎖的動機,其允許驗證者在看見更高輪數(shù)波爾卡的時候解鎖并且提交對應(yīng)的新區(qū)塊。
區(qū)塊鏈
Tendermint對交易按批或塊進行處理。區(qū)塊之間通過加密哈哈希算法鏈成一個完整的區(qū)塊鏈。區(qū)塊鏈包括經(jīng)過排序的交易日志和驗證者提交的相關(guān)證據(jù)。
為什么是區(qū)塊?
共識算法一次提交若干個交易(transactions)。正如在第二章提到的那樣。從分批原子廣播(batched atomic broadcast)的角度來看待這個問題,對應(yīng)兩個主要的優(yōu)化,其給了我們更多的吞吐量和容錯能力:
帶寬優(yōu)化:因為每一次提交(commit)需要驗證者之間的兩輪通訊,以塊為單位交易的批處理,平攤了提交的成本在該區(qū)塊中的所有交易上。
完整性優(yōu)化:區(qū)塊的哈希鏈形成了一個不可篡改的數(shù)據(jù)結(jié)構(gòu),跟git倉庫很像,具備歷史任意點的子狀態(tài)認證檢查的能力。
區(qū)塊也引起了另外一個效應(yīng),看上去更微妙,但是可能更重要。他們增加了單個交易的最小延遲到區(qū)塊的最小延遲,對于Tendermint來說在數(shù)百毫秒到數(shù)秒量級。傳統(tǒng)的序列化數(shù)據(jù)庫系統(tǒng)提供了提交延遲在毫秒到數(shù)百毫秒量級。他們的低延遲是因為這些數(shù)據(jù)庫不是拜占庭容錯的,只需要一輪通訊而不是兩輪和來自于1/2而不是2/3節(jié)點的響應(yīng)。然而,與其他具有快速提交時間(commit times)的選舉算法不同,Tendermint提供了一個更常規(guī)的脈沖(pulse ),在節(jié)點故障和網(wǎng)絡(luò)不同時方面對整個網(wǎng)絡(luò)的狀態(tài)具有更好的響應(yīng)度。
脈沖在通訊自治系統(tǒng)一致性方面的角色現(xiàn)在并不明朗,但是由此引發(fā)的延遲在金融市場中是具有前景的。
區(qū)塊的結(jié)構(gòu)
區(qū)塊的目的是打包一批交易,并且鏈接到前面一個塊。鏈接包含兩種形式:前面一個區(qū)塊的哈希和前面區(qū)塊的預(yù)提交的集合,其也被稱作LastCommit。因此一個區(qū)塊由三部分構(gòu)成:區(qū)塊頭,交易列表和Lastcommit。
安全性
這里我們簡要地證明一下Tendermint滿足原子廣播。原子廣播被定義為滿足以下條件:
有效性(validity) - 如果一個正確的進程廣播m,它最終成功傳達了m
一致性(agreement) - 如果一個正確的進程成功傳達了m,所有最終所有的進程成功傳達m
完整性(integrity) - m只傳遞一次,并且是以廣播的形式被發(fā)送者發(fā)送出去
總的順序(total order) - 如果正確的進程p和q分別傳遞出m和m‘,p傳達m在m’之前,那么q傳達m在m‘之前
注意到, 如果把m看作一個區(qū)塊,Tendermint并不滿足有效性,因為并不能保證提議的區(qū)塊最會會被提交,因為驗證者可能進入到新的一輪,并提交一個不同的區(qū)塊。
如果我們把m看作某一區(qū)塊里的一批交易,那么我們能夠滿足有效性通過驗證者重新提議同一批交易直至交易最終被提交。
為了滿足完整性的第一部分,我們必須引入額外的規(guī)則來禁止一個合法的驗證者提議或者預(yù)提交一個區(qū)塊,其中這個區(qū)塊包含的這批交易已經(jīng)被提交過。幸運的是,交易可以被梅克爾根索引,在提議和預(yù)提交以前可以進行相關(guān)的查找來濾除已經(jīng)提交的交易。
或者我們可以把m當成一個交易(transaction),通過引入內(nèi)存池的持久屬性,可以滿足有效性,即,交易可以駐留在內(nèi)存池中直到它被提交。然而為了滿足完整性的第一部分,我們必須依賴應(yīng)用程序狀態(tài)(application state)來制定一些針對交易的規(guī)則,這樣一個給定的交易只能進行一次。例如,可以通過基于賬戶的序列號,正如在以太坊中的那樣?;蛘弑4嬉环菸词褂觅Y源的列表,每一個資源只能被使用一次,正如在比特幣中使用的那樣。因為有多種方法,Tendermint本身并不保證消息只傳達一次,但是允許應(yīng)用開發(fā)者來指定相關(guān)特性。完整性的第二部分顯而易見,因為只有正確的提議者提議的區(qū)塊中的交易才能被提交。
為了證明Tendermint滿足“總的順序”,我們引入了一個新的特性,狀態(tài)機安全性(state machine safety),并且可以證明滿足狀態(tài)機安全性的協(xié)議必定滿足“一致性”和“總的順序”。所謂的狀態(tài)機安全是指如果一個正確的驗證者在高度H提交了一個區(qū)塊,沒有其他的驗證者在同一高度提交一個不同的區(qū)塊??紤]到所有的消息最終被接收,這個立刻暗示了一致性,因為如果一個正確的驗證者在高度H提交了一個區(qū)塊B,包含了交易m,所有其他的正確的驗證者不能提交其他的區(qū)塊,因此最終提交了區(qū)塊B,傳達了消息m。
現(xiàn)在,我們需要證明狀態(tài)機安全滿足“總的順序”,并且Tendermint滿足狀態(tài)機安全。為了證明前者,考慮兩個消息m和m’分別由驗證者p和q發(fā)出。狀態(tài)機安全確保p發(fā)出消息m在高度Hm當且僅當q發(fā)出消息m在高度Hm,并且p發(fā)出消息m‘在高度Hm’當且僅當q發(fā)出消息m‘在高度Hm’。不失一般性,因為高度是嚴格遞增的,假設(shè)Hm
最后,為了證明當拜占庭節(jié)點少于1/3的時候,Tendermint滿足狀態(tài)機安全,我們采用反證法。假設(shè)Tendermint并不滿足狀態(tài)機安全,允許在某一高度提交多個區(qū)塊。那么我們可以證明至少需要1/3的拜占庭節(jié)點,與假設(shè)矛盾。
考慮一個有效的驗證者在高度H和輪數(shù)R提交了一個區(qū)塊B。提交一個區(qū)塊意味著驗證者在第R輪收到了關(guān)于區(qū)塊B的超過2/3的預(yù)提交。假設(shè)另一個區(qū)塊C在高度H提交。我們有兩個選項:要么在第R輪提交要么在S輪提交(S》R)。
如果區(qū)塊C在第R輪提交,那么超過2/3的驗證者必須為該區(qū)塊預(yù)提交,那么意味著至少1/3的驗證者在第R輪同時對區(qū)塊B和C進行了預(yù)提交,那么顯然這些同時節(jié)點是拜占庭節(jié)點。假設(shè)區(qū)塊C在S輪提交。因為超過2/3對B區(qū)塊進行了預(yù)提交,他們在S輪也將被鎖定在區(qū)塊B上,因此他們必須對B進行預(yù)投票。為了對區(qū)塊C進行預(yù)提交,他們必須接收到關(guān)于區(qū)塊C的波爾卡,因此需要關(guān)于區(qū)塊C的超過2/3的預(yù)投票。然而,超過2/3的驗證者已經(jīng)被鎖定在區(qū)塊B上。節(jié)點為了收到區(qū)塊C的波爾卡至少需要網(wǎng)絡(luò)中1/3的驗證者違背鎖機制,這部分節(jié)點顯然是拜占庭節(jié)點。因此,為了違背狀態(tài)機安全,至少需要1/3的拜占庭驗證者。即若網(wǎng)絡(luò)中的拜占庭節(jié)點少于總數(shù)的1/3,Tendermint滿足狀態(tài)機安全性。
綜上,Tendermint滿足原子廣播。
在未來的工作中,我們會提供關(guān)于Tendermint的安全性的更正式的證明。
責任制
一個具有問責制的拜占庭容錯算法能夠在存在安全隱患時標識所有的拜占庭驗證者。傳統(tǒng)的拜占庭容錯算法并沒與這個特性,對應(yīng)地也沒有任何相應(yīng)的保證。當然,問責制僅能適用在拜占庭節(jié)點在1/3到2/3的情況。如果超過2/3的節(jié)點是拜占庭,他們能夠完全占據(jù)協(xié)議,此時無法保證一個合法的驗證者可以收到任何拜占庭節(jié)點違法的證據(jù)。
進一步,問責制是在異步網(wǎng)絡(luò)環(huán)境下最終性的盡力而為,在這樣的網(wǎng)絡(luò)環(huán)境中著安全問題,關(guān)鍵消息(critical messages)的延遲使得在探測到安全問題以后才可能發(fā)現(xiàn)拜占庭驗證者。事實上,如果正確的進程(correct processes)可以接受拜占庭行為的相關(guān)證據(jù)(evidence),但是在他們能夠通訊之前不可逆地失敗了(fail irreversibly),可能使得問責制永久失效( Permanently compromised),盡管實際上這種情形可以通過高級備份策略來克服。
通過枚舉安全問題的各種隱患,拜占庭驗證者是可以識別的,這樣協(xié)議是具有問責制的。與其它競選相關(guān)的協(xié)議相比,Tendermint的簡潔給予了其更簡單的分析方法。
在Tendermint存在兩類安全隱患,每一種都是可問責的。第一種,拜占庭提議者在單輪中產(chǎn)生兩個沖突的提議,并且拜占庭驗證者同時對這兩個提議進行投票(vote)。第二種,一些驗證者在單輪已經(jīng)提交(commit)之后,拜占庭驗證者違反鎖機制(locking rules),致使其他驗證者在隨后的輪數(shù)提交一個不同的區(qū)塊。注意到,若拜占庭驗證者少于2/3,只通過違反解鎖機制的方法是無法引發(fā)安全性問題的,同時超過1/3的節(jié)點必須違背波爾卡鎖機制,因為每一個提交(commot)需要有一個波爾卡為其背書。
在存在提議或者投票沖突的情況下,同時接受沖突的提議或者投票,可以根據(jù)這些提議或投票的簽名來辨別這些拜占庭節(jié)點。
在違反鎖定機制(locking rules)的情況下,伴隨著相應(yīng)的安全性問題,有效的驗證者必須廣播在當前高度看到的所有投票,這樣證據(jù)可以被收集起來。少于2/3的正確驗證者在所有導(dǎo)致兩個區(qū)塊被同時提交的投票中集體隱匿。此時在這些投票中,如果沒有1/3或者更多的驗證者簽名沖突的投票,那么存在1/3或者更多的驗證者違反了鎖定機制。
如果預(yù)投票( pre-vote )或者預(yù)提交( pre-commit)影響了一個提交,它一定會被一個合法的驗證者看見。因此,通過搜集所有的投票,通過匹配每一個預(yù)投票和最近的預(yù)提交,可以探測到違反鎖機制的行為(violations of Prevotethe-Lock )。
類似的,通過匹配預(yù)提交(pre-commit )和為其背書的波卡爾卡(polka),可以探測到違反解鎖機制的行為(violations of Unlock-on-Polka )。注意到這就意味著如果拜占庭驗證者可以在看見波爾卡之前預(yù)提交(pre-commit),并且如果相應(yīng)的波爾卡最終發(fā)生的話,拜占庭驗證者將逃脫責任制。然而,如果每一個預(yù)提交有波爾卡背書的話,這些安全隱患就不存在。
目前的設(shè)計提供了問責制,伴隨著后危機廣播協(xié)議(post-crisis broadcast protocol),但是其能夠用來提高實時的問責制。也就是說,一旦提交被改變,相應(yīng)的預(yù)提交,為預(yù)提交背書的預(yù)投都會發(fā)生改變,這樣一直回退到創(chuàng)世紀塊。通過上面的方式,如果發(fā)生安全問題,沒有背書的投票可以立即被探測到。
故障和可用性
作為一個拜占庭共識容錯算法,Tendermint可以容忍拜占庭故障節(jié)點到(但不包括)節(jié)點總數(shù)的1/3。這就意味著節(jié)點可能會崩潰,發(fā)送不同和沖突的消息到不同的節(jié)點,拒絕中繼消息或者表現(xiàn)異常,安全或者運轉(zhuǎn)存在問題。
協(xié)議中有兩個地方我們可以通過使用本地時鐘的超時特性,為不同時性做一些優(yōu)化:在接收到2/3或者更多預(yù)投票(pre-votes)之后(不針對單個區(qū)塊或者nil)和在收到2/3或更多預(yù)提交(pre-commit)以后(不針對單個區(qū)塊或者nil)。在每一中情形中,我們可以睡眠一段時間用來給延遲的投票一個被接受的機會,因此減少在新的一輪沒有提交區(qū)塊的可能性。時鐘不需要在驗證者之間同步,因為驗證者在觀測到2/3或更多的投票時會重置各自的時間。
如果1/3或者更多的驗證者崩潰,網(wǎng)絡(luò)癱瘓,因為任何共識進展需要2/3以上驗證者的投票。網(wǎng)絡(luò)仍然可以讀取數(shù)據(jù),但是沒有新的區(qū)塊的提交。只要驗證者重新上線,他們能夠從之前的投票狀態(tài)開始。共識狀態(tài)機應(yīng)該配置一個預(yù)寫式日志(write-ahead log),這樣重新上線的的驗證者可以快速回退到之前機器崩潰時的位置,確保沒有違反規(guī)則。
如果1/3或者更多的驗證者是拜占庭,他們能夠以多種方式損害系統(tǒng)的安全性。例如,在同一輪提交兩個塊,并且投票提交這兩個區(qū)塊或者通過通過違反鎖定機制在同一高度不同輪提交兩個不同的區(qū)塊。在每一種情形中,有清晰的證據(jù)顯示哪些驗證者是拜占庭節(jié)點。在第一個例子中,他們在同一輪簽名兩個不同的提議,違反規(guī)則。在第二個例子中,他們鎖定在r-1輪在第r輪提交了一個不同的區(qū)塊,違反了鎖定機制。
當使用經(jīng)濟和治理組件來激勵和管理共識,這些額外的責任制保證是具有決定性的。
結(jié)論
Tendermint本身是弱同步,拜占庭容錯,狀態(tài)機復(fù)制協(xié)議,擁有優(yōu)化的拜占庭容錯和額外的責任制來保證當超過拜占庭容錯假設(shè)上限時的情形。協(xié)議采用round robin的提議者產(chǎn)生方法,用同樣的機制跳過一個提議者。多輪投票之間的安全性通過鎖機制得到了保障。
評論
查看更多