导读
- round by round范式
- lock-unlock范式
- 如何不能丢失、覆盖已提交的共识
锁定范式(lock)
锁定=记住(remember),尽管还没提交。classic paxos的phase 1就是锁定。
锁定=节点提出一个承诺:将来不会接受比这个更旧的决定。
锁定要求:如果一个正确的节点锁定在
lock如何产生?当收到一个QC(PBFT),也就是证明至少n-f个节点ack。hotstuff要收到两个QC才锁定。
一个极端场景
这里指出一个很多文献都提及的极端网络情况(文献[2]的情况5),用于说明两阶段协议(PBFT、Tendermint)以及HotStuff之间的处理差异,尽管表述不尽相同。
这种情况出现的根本问题还是safety和liveness的矛盾:要保证safety就要等,可能丧失liveness;要liveness就要进行切换、开辟新分支,可能破坏safety。
文献【2】的情况5如下,讨论的是两阶段提交的BFT算法(弱化的PBFT):拥有qc1->锁定,拥有qc2->提交。而且:
- 拥有qc1可以推出最少有f+1个正确节点投票给某区块。
- 拥有qc2可以推出最少有f+1个正确节点有qc1,处于锁定状态。

由于大规模网络延迟,其他节点没有收到两个B1的qc,随后在下一轮中开辟新分支B2。只有某节点收到了两个B1的QC,那么它就会提交B1, 在将来的投票中否决B2的投票。此时,系统出现了不一致!各自提交了不同的数据。
那么PBFT如何解决这个问题?节点申请更换leader需要给出证明:n-f个prepareQC消息。细节看参考文献【2】:
HotStuff如何解决这个问题?
总结各个节点通过qc获得的增量信息:
| 协议 | qc1 | qc2 | qc3 |
|---|---|---|---|
| PBFT | 至少f+1个正确节点投给了区块B | 至少f+1个正确节点有qc1,此时可以更新锁定的区块。自己不会投给冲突的区块。 | |
| HotStuff | 至少f+1个正确节点投给了区块B | 至少f+1个正确节点收到了qc1,此时可以更新锁定的区块。自己不会投给冲突的区块。 | 至少f+1个正确节点更新了锁定的区块,它们不会投票给冲突的区块了(根据算法过程)。此时可以安心提交区块。 |
所以最大的区别在于:hotstuff通过第三轮共识,每个节点补全了这部分消息:至少f+1个正确节点不可能会投给冲突,于是冲突区块无法形成qc1。随后hotstuff提交区块,再进入下一个视图。
而PBFT需要先进入下一轮视图,让新leader收集、广播这部分消息,从而禁止冲突区块形成qc。但是由于leader介入补全这部分信息,导致通信复杂度提高了。
参考
- https://www.youtube.com/watch?v=ONobI3X70Rc (video里面的lock不一定是lockedQC,而是qc-high)
- https://zhuanlan.zhihu.com/p/78772451
