tendermint 共识算法伪代码浅析

2019-07-12  本文已影响0人  zjubfd

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

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

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

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。

消息处理

image

收到proposal

收到revote

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

收到precommit

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

上一篇下一篇

猜你喜欢

热点阅读