tendermint共識解析

本文關(guān)于tendermint的共識部分赡鲜,主要參考如下:
1. Ethan Buchman:Tendermint: Byzantine Fault Tolerance in the Age of
Blockchains

2. tendermint中文文檔
3.tendermint的一個論文
4. 萬向區(qū)塊鏈對參考0中論文的翻譯
5. tendermint官方doc

本文著重介紹tendermint的共識方面的細(xì)節(jié)睬塌。


image.png

tendermint共識狀態(tài)機(jī)解析

上圖中每個step,其實(shí)都是共識狀態(tài)機(jī)中的一個狀態(tài)昆庇,狀態(tài)轉(zhuǎn)換周期如下:

NewHeight -> (Propose -> Prevote -> Precommit)+ -> Commit -> NewHeight ->...

gossip 都廣播哪些內(nèi)容末贾?

我們知道在驅(qū)動狀態(tài)機(jī)最重要兩個因素,一個是通信(tendermint中的P2P是以gossip協(xié)議和reactor模式為基礎(chǔ))整吆;另一個就是event(設(shè)計上任何異步通訊的過程都離不開event)拱撵,這兩部分的內(nèi)容后面有機(jī)會的話會單獨(dú)寫文章解析,現(xiàn)在我們先來看看gossip都廣播哪些內(nèi)容表蝙,以使節(jié)點(diǎn)都能跟進(jìn)當(dāng)前的共識狀態(tài)拴测。
以下引用自官方文檔,逐條說明本人結(jié)合源碼對其的解析:

  • Nodes gossip PartSet parts of the current round's proposer's proposed block. A LibSwift inspired algorithm is used to quickly broadcast blocks across the gossip network.

說明:partset代表block的一些簡要信息府蛇,其結(jié)構(gòu)如下:

type PartSet struct {
  total int
  hash  []byte

  mtx           sync.Mutex
  parts         []*Part
  partsBitArray *bits.BitArray
  count         int
}
  • Nodes gossip prevote/precommit votes. A node NODE_A that is ahead of NODE_B can send NODE_Bprevotes or precommits for NODE_B's current (or future) round to enable it to progress forward.

說明:這條要結(jié)合下面狀態(tài)機(jī)的prevote集索、precommit狀態(tài)解析中的step ends一起理解。因?yàn)閜revote汇跨,precommit都需要2/3+的票數(shù)通過抄谐,才能進(jìn)行狀態(tài)轉(zhuǎn)換。

  • Nodes gossip prevotes for the proposed PoLC (proof-of-lock-change) round if one is proposed.

說明:gossip prevotes的另一個用處是polka unlock.

  • Nodes gossip to nodes lagging in blockchain height with block commits for older blocks.

說明:gossip block扰法,落后的節(jié)點(diǎn)同步新block。

  • Nodes opportunistically gossip HasVote messages to hint peers what votes it already has.

說明:節(jié)點(diǎn)偶爾gossip HasVote消息

  • Nodes broadcast their current state to all neighboring peers. (but is not gossiped further)

說明:節(jié)點(diǎn)gossip 當(dāng)前所在狀態(tài)(未來版本不再gossip此部分)

共識狀態(tài)解析

接下來讓我們逐條分析各個共識狀態(tài)毅厚。

1. propose step(height:H,round:R)

客戶端發(fā)起一筆交易gentx塞颁,通過rpc發(fā)到tendermint節(jié)點(diǎn)后進(jìn)入mempool cache,tm調(diào)用checktx的abci接口驗(yàn)證交易吸耿,如果驗(yàn)證成功就進(jìn)入mempool祠锣,proposer節(jié)點(diǎn)選擇打包交易到區(qū)塊中,并將區(qū)塊附到proposalMsg中咽安,對此msg進(jìn)行簽名伴网,然后通過gossip把此msg廣播到區(qū)塊鏈網(wǎng)絡(luò)中。

一個proposal包含一個(H,R)的block妆棒,和一個可選的最近的PoLC-Round < R澡腾,當(dāng)然前提是proposer知道此可選參數(shù)(PoLC:proof of lock change,指的2/3+ prevote某個block)糕珊,這樣適當(dāng)保住了共識網(wǎng)絡(luò)的liveness动分。

Upon entering Propose:

指定的proposer 提議了一個block(H,R).

The Propose step ends:

  1. timeoutProposeR 超時,則進(jìn)入-->Prevote(H,R)
  2. 當(dāng)收到了proposal block红选,并且改validator的所有prevote step 都在PoLC-Round澜公,則進(jìn)入-->Prevote(H,R)。(要理解這點(diǎn)喇肋,重點(diǎn)要理解某個validator有可能involve在若干個round坟乾,相當(dāng)于說你其他輪中都過了prevote的step迹辐,才能進(jìn)入新一輪的prevote step?但如果有鎖的情況下即使進(jìn)入了prevote輪甚侣,你也不能prevote了)
  3. After common exit conditions

Note:
注意每輪共識開始時明吩,validator節(jié)點(diǎn)在本地會有一個本地同步時鐘,用來記時ProPose timeout, 如果在timeout時間周期內(nèi)沒有收到proposer節(jié)點(diǎn)的提議渺绒,對該提議的預(yù)投票為空(nil)贺喝,validator節(jié)點(diǎn)會投票決定是否進(jìn)入下一輪共識,validator也可以通過治理模塊投票移出或者替換拜占庭驗(yàn)證者宗兼。而propose timeout也會隨著每輪共識而增加躏鱼。所以可以理解為此過程是同步過程。
但是在其后的prevote和precommit的兩階段共識是完全異步的殷绍,從而減少對時鐘同步的依賴染苛,或者網(wǎng)絡(luò)延遲。但這也同樣存在一個問題主到,如果這兩階段共識中就是得不到1/3以上validator的投票茶行,整個區(qū)塊鏈網(wǎng)絡(luò)將癱瘓(此處其實(shí)有待看源碼仔細(xì)研究,因?yàn)檫@兩個階段也是有timeout定時器的登钥,重點(diǎn)關(guān)注step end的條件畔师,以此來分析可能引起網(wǎng)絡(luò)hang住的場景)。這個問題的本質(zhì)其實(shí)就是FLP不可能定理牧牢。FLP 原理實(shí)際上說明對于允許節(jié)點(diǎn)失效情況下看锉,純粹異步系統(tǒng)無法確保一致性在有限時間內(nèi)完成。
所以tendermint其實(shí)在一定程度是假定節(jié)點(diǎn)中大部分都是正常節(jié)點(diǎn)塔鳍。

2. prevote step (height:H,round:R)

每個節(jié)點(diǎn)收到propose消息后伯铣,會先對區(qū)塊進(jìn)行驗(yàn)證,如果驗(yàn)證通過才開始prevote簽名轮纫,然后廣播到網(wǎng)絡(luò)中腔寡。

Upon entering Prevote, each validator broadcasts its prevote vote.

  1. First, if the validator is locked on a block since LastLockRound but now has a PoLC for something else at round PoLC-Round where LastLockRound < PoLC-Round < R, then it unlocks.(這條好理解,就是解鎖條件掌唾,重點(diǎn)還是要理解異步)放前。
  2. If the validator is still locked on a block, it prevotes that. (這條是因?yàn)殒i的規(guī)則,他只能prevote自己lock住的block郑兴,但是會引起重復(fù)prevote犀斋?這個還得結(jié)合源碼研究)。
  3. Else, if the proposed block from Propose(H,R) is good, it prevotes that.(沒啥好解釋的情连,就是驗(yàn)證了proposal后正常prevote)
  4. Else, if the proposal is invalid or wasn't received on time, it prevotes <nil>.(proposal無效叽粹,或者定時器超時,就prevote<nil>)

The Prevote step ends:

  • After +2/3 prevotes for a particular block or <nil>. -->; goto Precommit(H,R)
  • After timeoutPrevote after receiving any +2/3 prevotes. --> goto Precommit(H,R)
  • After common exit conditions

3. Precommit Step (height:H,round:R)

Upon entering Precommit, each validator broadcasts its precommit vote.

  1. If the validator has a PoLC at (H,R) for a particular block B, it (re)locks (or changes lock to) and precommits B and sets LastLockRound = R.(說明了什么時候上鎖)
  2. Else, if the validator has a PoLC at (H,R) for <nil>, it unlocks and precommits <nil>.(說明了什么時候precommit nil,簡言之虫几,就是獲得了POLC的<nil>)
    3.Else, it keeps the lock unchanged and precommits <nil>.(最后剩下的情況也就是超時了吧锤灿?)

A precommit for <nil> means "I didn’t see a PoLC for this round, but I did get +2/3 prevotes and waited a bit".(這句可以理解為沒有獲得非nil的POLC,而且等待了timeout時間段)

The Precommit step ends:

  1. After +2/3 precommits for <nil>. --> goto Propose(H,R+1)(注意辆脸,并沒有commit nil但校。prevote nil、precommit nil進(jìn)入下一輪啡氢,因此tendermint中沒有類似PBFT中的viewchange )
  2. After timeoutPrecommit after receiving any +2/3 precommits. --> goto Propose(H,R+1)(我理解此處+2/3 precommits是筆誤状囱?應(yīng)該是+2/3 prevotes?)
  3. After common exit conditions

Common exit conditions

  1. After +2/3 precommits for a particular block. --> goto Commit(H)
  2. After any +2/3 prevotes received at (H,R+x). --> goto Prevote(H,R+x)
  3. After any +2/3 precommits received at (H,R+x). --> goto Precommit(H,R+x)
    第一點(diǎn)倘是,可理解為在R內(nèi)要追趕最新狀態(tài)搀崭,盡快commit瘤睹。
    后兩點(diǎn)可理解為要追趕更新的R轰传。

4. Commit Step (height:H)

  1. Set CommitTime = now()
  2. Wait until block is received. --> goto NewHeight(H+1) //注意此處要等到本輪的塊到了才會進(jìn)入NewHeight step.

5. NewHeight Step (height:H)

Move Precommits to LastCommit and increment height.
Set StartTime = CommitTime+timeoutCommit
Wait until StartTime to receive straggler commits. --> goto Propose(H,0)

小結(jié)

在異步網(wǎng)絡(luò)中获茬,一個最大的問題就是同高度上锦茁,在不同的round提交了不同的block码俩。tendermint引入了鎖的機(jī)制稿存。

什么時候鎖瞳秽?

每個validator鎖定在他獲得PoLC的block中练俐,然后只能對該block precommit,在后面的R中燕锥,如果沒有unlock也只能prevote此block。

什么時候解鎖托慨?

提交了一個當(dāng)前鎖定的塊后
在下一輪(準(zhǔn)確說應(yīng)該是PoLC round)看到PoLC(proof of lock change暇榴,在新的一輪收到大于2/3 prevote的block)時獲得解鎖, 解鎖后不會在PoLC round 投票了蔼紧,因?yàn)樵谠揜中已經(jīng)獲得了polka歉井,也就是說已經(jīng)結(jié)束了prevote state哩至。

鎖定規(guī)則

驗(yàn)證者只能預(yù)投票(pre-vote)他們被鎖定的區(qū)塊(因?yàn)樗谀砇ound中prevote的block未必和precommit的block是相同的)菩貌。這樣就阻止驗(yàn)證者在同一個高度箭阶,上一輪中預(yù)提交(pre-commit)一個區(qū)塊嘹叫,之后又預(yù)投票了下一輪的另一個區(qū)塊诈乒。

Proof of Safety

假設(shè)有-1/3的Byzantine voting power(-1/3指不到1/3), 在R輪時,validator commit一個block B怕磨。這就意味著有1/3+的誠實(shí)節(jié)點(diǎn)lock在了R' > R, 他們直到獲得在R`>R 的POLC才能unlock喂饥。但是這種unlock的情況不會發(fā)生肠鲫,因?yàn)槭S嗟?2/3個節(jié)點(diǎn)能投票給B以外的block,無法形成POLC导饲。(這不是會導(dǎo)致誠實(shí)節(jié)點(diǎn)一直鎖嗎氯材?從而網(wǎng)絡(luò)hang住棠枉?)

Proof of Liveness

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浓体,一起剝皮案震驚了整個濱河市辈讶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌生闲,老刑警劉巖碍讯,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捉兴,死亡現(xiàn)場離奇詭異倍啥,居然都是意外死亡澎埠,警方通過查閱死者的電腦和手機(jī)虽缕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒲稳,“玉大人氮趋,你說我怎么就攤上這事〗” “怎么了剩胁?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長祥国。 經(jīng)常有香客問我摧冀,道長,這世上最難降的妖魔是什么系宫? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮建车,結(jié)果婚禮上扩借,老公的妹妹穿的比我還像新娘。我一直安慰自己缤至,他們只是感情好潮罪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布康谆。 她就那樣靜靜地躺著,像睡著了一般嫉到。 火紅的嫁衣襯著肌膚如雪沃暗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天何恶,我揣著相機(jī)與錄音孽锥,去河邊找鬼。 笑死细层,一個胖子當(dāng)著我的面吹牛惜辑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疫赎,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼盛撑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捧搞?” 一聲冷哼從身側(cè)響起抵卫,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胎撇,沒想到半個月后介粘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡创坞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年碗短,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片题涨。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡偎谁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纲堵,到底是詐尸還是另有隱情巡雨,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布席函,位于F島的核電站铐望,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茂附。R本人自食惡果不足惜正蛙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望营曼。 院中可真熱鬧乒验,春花似錦、人聲如沸蒂阱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鳄厌,卻和暖如春荞胡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背了嚎。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工泪漂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人新思。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓窖梁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親夹囚。 傳聞我的和親對象是個殘疾皇子纵刘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容