共识算法
区块链系统通过共识算法保障系统一致性。 理论上,共识是对某个提案(proposal)达成一致意见的过程,分布式系统中提案的含义十分宽泛,包括事件发生顺序、谁是leader等。区块链系统中,共识是各个共识节点对交易执行结果达成一致的过程。
共识算法分类
根据是否容忍 拜占庭错误 ,共识算法可分为容错(Crash Fault Tolerance, CFT)类算法和拜占庭容错(Byzantine Fault Tolerance, BFT)类算法:
- CFT类算法 :普通容错类算法,当系统出现网络、磁盘故障,服务器宕机等普通故障时,仍能针对某个提议达成共识,经典的算法包括Paxos、Raft等,这类算法性能较好、处理速度较快、可以容忍不超过一半的故障节点;
- BFT类算法 :拜占庭容错类算法,除了容忍系统共识过程中出现的普通故障外,还可容忍部分节点故意欺骗(如伪造交易执行结果)等拜占庭错误,经典算法包括PBFT等,这类算法性能较差,能容忍不超过三分之一的故障节点。
PBFT(Practical Byzantine Fault Tolerance)共识算法可以在少数节点作恶(如伪造消息)场景中达成共识,它采用签名、签名验证、哈希等密码学算法确保消息传递过程中的防篡改性、防伪造性、不可抵赖性,并优化了前人工作,将拜占庭容错算法复杂度从指数级降低到多项式级别,在一个由(3f+1)个节点构成的系统中,只要有不少于(2f+1)个非恶意节点正常工作,该系统就能达成一致性,如:7个节点的系统中允许2个节点出现拜占庭错误。
TaiyueChain共识算法
区块链网络无论采用哪种单一的共识机制来决定新区块的生成方式,皆无法同时兼顾扩展性(Scability)、安全性(Security)、去中心(Decentralization)这三项要求,至多只能三者取其二。对于联盟链来说,由于使用场景的特殊性,对于去中心化程度的要求不会有其他两项的要求那么高,因此,泰岳链使用了TBFT的共识算法来保证高扩展性和高安全性,同时保持一定的去中心化程度。
泰岳链的TBFT共识算法是PBFT算法的一种优化实用实现,基于轮次的投票机制。PBFT算法的实现过程根据算法的不同,分为:
- 强同步: 节点所发出的消息,在一个确定的时间内,肯定会到达目标节点。
- 异步: 节点所发出的消息,不能确定一定会到达目标节点。
- 弱同步: 节点发出的消息,虽然会有延迟,但是最终会到达目标节点。
TBFT与PBFT的区别
- 相同点:
- 同属BFT体系。
- 抗1/3拜占庭节点攻击。
- 三阶段提交,第一阶段广播交易(区块),后两阶段广播签名(确认)。
- 两者都需要达到法定人数才能提交块。
- 不同点:
- TBFT与PBFT的区别主要是在超过1/3节点为拜占庭节点的情况下。当拜占庭节点数量在验证者数量的1/3和2/3之间时,PBFT算法无法提供保证,使得攻击者可以将任意结果返回给客户端。而TBFT共识模型认为必须超过2/3数量的precommit确认才能提交块。举个例子,如果1/2的验证者是拜占庭节点,TBFT中这些拜占庭节点能够阻止区块的提交,但他们自己也无法提交恶意块。而在PBFT中拜占庭节点却是可以提交块给客户端。
- 另一个不同点在于拜占庭节点概念不同,PBFT指的是节点数,而TBFT代表的是节点的权益数,也就是投票权力。
TBFT锁机制
锁机制详解
举个例子,有四个validator 节点,A,B,C,D, 在某个R轮,在propose阶段,
- proposer节点广播出了新块blockX;
- A的超时时间内没有收到这个新块,向外广播pre-vote nil,B,C,D都收到了,向外广播pre-vote投给blockX;
- 现在四个节点进入了pre-commit阶段,A处于红色内圈,B,C,D处于蓝色外圈;
- 假设A由于自身网络不好,又没有在规定时间内收到超过2/3个对blockX的投票,于是只能发出 pre-commit nil投票消息投给空块;
- D收到了B和C的pre-vote消息,加上自己的,就超过了2/3了,于是D在本机区块链里commit了blockX;
- 假设此时B和C网络出现问题,收不到D在pre-commit消息,这是B和C只能看到2票投给了blockX,一票投给了空块,全部不足2/3,于是B和C都只能 commit空块,高度不变,进人R+1轮,A也只能看到2票投给了blockX,一票投给了空块,也只能commit空块,高度不变,进人R+1轮;
- 在R+1轮,由于新换了一个proposer, 提议了新的区块blockY,A,B,C 三个个可能会在达成共识,提交blockY,于是在同样的高度,就有blockX和blockY两个块,产生了分叉?其实,Tendermint加上了锁的机制,具体就是,在第7步,即使proposer出了新块blockY,A,B,C只能被锁定在第6步他们的pre-commit块上,即A在第6步投给了空块,那么在第R+1轮,只能继续投给空块,B在第6步投给了blockX,那么在新一轮,永远只能投给blockX,C也是类似。这样在R+1轮,就会有1票投给空块,两票投给blockX,最终达成共识blockX,A,B,C三人都会commit blockX,与D一致,没有产生冲突。
TBFT投票流程
TBFT是一种弱同步的PBFT算法,在算法的每一步流程里面都会加入超时机制,如果有节点超时回应就会被定义为fault节点,如果fault节点没有超过整体节点的三分之一就能走完整个流程。
TBFT的等每一个区块出块流程包含有八个步骤,如下图所示:
-
NewHeight:进入新的一个区块出块周期,这个步骤需要确定新出的区块的高度。
-
NewRound:对第一步骤的高度进行轮次投票,从零轮开始,一直到共识完成。如果本轮无法达成出块,会替换leader节点,并对该高度进行新的一个出块共识轮次,依此类推。
-
Propose:在这个步骤委员会的Leader节点会产生一个该高度的区块用于开始这一轮共识。其它节点会在这一步骤等待Leader节点propose的区块广播。(类似于PBFT的Pre-Prepare阶段)
-
Prevote:在这一步所有节点会对Propose产生的区块进行验证后并投票,投票通过验证接口为赞成或者反对投票。(类似于PBFT 的Prepare 阶段)
-
PrevoteWait:完成Prevote时进入的阶段,等待并收集其它节点的投票,当收集到超过委员会总人数的三分之二以上的赞成投票的时候进入下一步骤,这一阶段会引入超时机制,如果超时将被标记为反对投票
-
PreCommit:对块进行二次验证,并根据上一步的结果进行投票赞成PreCommit或者反对PreCommit.这一步骤和RoundStepPrevote差不多(类似于PBFT 的Commit),投票完成会进入下一阶段。
-
PreCommitWait:这一阶段同样也会等待并收集投票,当有收集到超过委员会总人数的三分之二以上的赞成时,会进入下一阶段,当超时并末收到超过委员会总人数的三分之二以上的赞成票时会替换leader 节点,轮次加一,然后进入新的NewRound循环。
-
RoundStepCommit:流程的最后阶段,完成这个区块高度的TBFT共识并广播到全网.这一步完成之后会进入下一个区块的NewHeight步骤。