Istanbul BFT作为BFT类算法的一种已经有过在以太坊上的实践。
Istanbul BFT作为BFT类算法的一种已经有过在以太坊上的实践。虽然Istanbul目前还存在一些潜在的问题,但其算法思想和实现还是值得学习和借鉴的。
源代码:https://github.com/jpmorganchase/quorum/tree/master/consensus/istanbul
core.backlogsRound和Sequence绑定在一起组成view,validator对区块验证后会对其进行签名。Istanbul BFT修改自PBFT算法,包括三个阶段:PRE-PREPARE、PREPARE以及COMMIT。在N个节点的网络中,这个算法可以最多容忍F个出错节点,其中N=3F+1。在每一轮开始前,validator会选择其中一个作为proposer,默认以轮询的方式(除此之外还有sticky的方式,搜索stickyProposer方法去看细节)。然后proposer会提出一个区块的proposal,并且广播PRE-PREPARE信息。一旦一个validator收到PRE-PREPARE信息,会把状态标记为PRE-PREPARED,然后广播PREPARE信息。这一步是为了确保所有的validator在同一个seqnence和round(代码中为view)上进行共识验证。一旦收到2F+ 1个PREPARE信息,validator进入PREPARED状态然后广播COMMIT信息。这一步是为了通知节点的peer已经接收到了提出的区块,并且即将插入区块到链中。最后,validator等待2F + 1个COMMIT信息,然后进入COMMITTED状态然后插入区块到链中。
Istanbul BFT算法中的区块是确定的,意味着链没有分叉并且合法的区块一定是在链中。为了防止一个恶意节点生成不同的链,在把区块插入进链之前,每一个validator必须把2F + 1个COMMIT签名放进区块头的extraData字段。因此,区块时可以自我验证的(因为有签名)并且轻客户端也支持。然而动态的extraData也会造成区块的hash计算问题。因为一个区块可以被不同的validator验证,所以会有不同的签名,所以同一个区块会有不同的hash。解决的方案是,计算区块hash的时候把COMMIT签名排除在外。因此我们任然可以在保证block hash一致性的同时进行共识验证。
New Round: 一个proposer发送新的区块proposal。validator等待PRE-PREPARE信息。PRE-PREPARED: 一个validator已经收到PRE-PREPARE信息,并且广播PREPARE信息。然后等待2F + 1个PREPARE或者COMMIT信息。PREPARED: 一个validator已经收到2F + 1个PREPARE信息,此时把自身状态标记为PREPARED,并且广播COMMIT信息。然后等待2F + 1个COMMIT信息COMMITTED: 一个validator已经收到2F + 1个COMMIT信息,此时把自身状态标记为COMMITTED,并且开始把提出的block插入链中。FINAL COMMITTED: 一个validator已经成功把区块成功插入了链中,此时把自身状态标记为FINAL COMMITTED,并且等待下一轮。ROUND CHANGE: 一个validator等待关于同一个round下的2F + 1个ROUND CHANGE信息。
PRE-PREPARED状态。PRE-PREPARED状态,一旦收到PRE-PREPARED信息并且伴随着以下情况:
PREPARE信息给其他validators。2F + 1个有效的PREPARE信息,因此而进入PREPARED状态。有效信息需要满足以下条件:
PREPARED状态,Validator广播COMMIT信息。2F + 1个·有效的COMMIT信息,以此进入COMMITTED状态。有效的信息需要满足以下条件:
2F + 1个commitment签名放进区块头的extraData并且尝试插入区块进区块链。FINAL COMMITTED状态。 
                如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!
