tendermint 共识算法伪代码浅析

tendermint 共识算法的论文可以从 https://arxiv.org/pdf/1807.04938.pdf 下载。

如何表示一个节点的共识状态。

tendermint 共识算法伪代码浅析_第1张图片
image

下标p表示节点的identity。
hp表示该节点的当前块高度,roundp表示当前共识轮次,stepp表示共识阶段(proposalprevoteprecommit
decisionp[] 暂且看作是节点p的区块列表,按照高度递增。
lockedValueplockedRoundp 表示该节点认可并且对外发起precommit的块的值,和当时的round
validValuepvalidRoundp 表示收到了2/3+的prevote,但是prevote来的晚了,已经投了nil票。
比较难理解的是validValuelockedValue的区别: validValue是用来提交proposal用的,它是节点认为validValue是其他节点的lockedValue。而lockedValue只要用来避免分叉的,只要lockedValue不为空,这个节点不会接受其他的proposal

StartRound

tendermint 共识算法伪代码浅析_第2张图片
image

每次进入新的一轮共识时,会判断自身是否为proposer,计算谁是proposer是固定稳定的一个算法,任何节点执行proposer函数, 对相同的hproundp,具有相同的输出。

如果经过计算发现自身是proposer,则 proposal应为validaValuep,或者从自己的mempool中选出入块的交易列表,同时根据上一个块的信息组装出proposal

实际算法中,会将proposal拆分成两个部分,proposal(只包含blockID部分)和blockParts,是由于一个块可能很大,将实际块的拆分成blockparts去传输,而proposal只包含block计算出的身份ID--blockId,这个blockId中会包含blockPartsmerkel hash root,用于在blockparts收集完毕后,验证块的正确性和完整性。

同时启动一个超时器,过一段时间后,如果仍然是当前状态,则会投nil的prevote票,进入prevote的step。

消息处理

tendermint 共识算法伪代码浅析_第3张图片
image

收到proposal

  • 如果该proposal声称是第一次提出,则校验proposal,和v是否和本地的lockedvalue相同或者lockedround为-1,是的话就投prevote票,同时进入prevote的step。

  • 如果该proposal声称是之前vr round出现过的proposal,则检查在该round是否有2/3的的prevote,如果是并且和本地的lockedValue相同,则进行投票,同时进入prevote的step。

  • 如果收到proposal时,已经有2/3+的该proposalprevote,则validValuevalidRound设置为该proposal和当前round。并且如果目前是prevote状态,也会设置lockedValuelockedRound则广播 precommit 投票。进入precommit的step。

收到revote

  • 一旦收到2/3+ 的nil prevote投票,并且自身的状态是prevote,则启动一个超时器,过一段时间后,如果还是当前状态,则投nil的precommit票,并且进入precommit的step。

实际上一进入prevote step的时候,就会启动一个超时器,过一段时间如果没有集齐足够的prevote,则投nil precommit票, 进入precommit的step。

收到precommit

这里的伪代码有一点出入,实际上进入commit step的时候,就会启动超时器,如果过一段时间状态没有变化,则会StartRound(hp+1) 进入新的一轮共识。

  • 一旦收到2/3+ 的precommit 投票,则共识成功,进入下一个高度的共识,reset各个状态。

你可能感兴趣的:(tendermint 共识算法伪代码浅析)