PBFT即实用拜占庭容错算法,由Miguel Castro和Barbara Liskov在1999年提出,可以在作恶节点少于三分之一的情况下,保证系统的正确性(避免分叉)。与原始的BFT算法相比,算法复杂度从指数级降低到了多项式级,从而使得BFT算法的实际应用成为可能。实际上,Tenermint就是PBFT的一个简化版本的实现。
首先了解一下几个基本概念:(从区块链的视角)
另外,primary是所有节点轮流做的,每个view上都会选出一个新的primary。
三阶段协议是PBFT的核心,参见下图:
从发起请求到最终收到reply,中间的共识过程需要经过3个阶段:
这里的逻辑有点绕:
第一次等待超过2/3的节点广播,是为了确认“已经有超过2/3的节点收到区块了”。但是这只是你自己知道,别人并不知道啊,因此需要再发送一次广播,告诉别的节点“我已经确认有超过2/3的节点收到区块啦”。而第二次等待超过2/3的节点广播,则是为了确认“已经有超过2/3的节点确认(有超过2/3的节点收到区块啦)”,此时说明已经达成共识,可以把该区块写到链上了。
这个原文是没有图的,只能根据文字描述自行理解,还是挺复杂的:
图中的圆角矩形表示状态,六边形表示等待阶段,绿线代表正常流程,红线代表异常流程。下面一个一个的来介绍:
需要注意的是,如果接收到了NEW-VIEW消息,则表示当前view未达成共识,需要在更高层的view上完成共识。因此,不管当前处于哪个阶段,都需要重新回到prepare状态。
接下来就是介绍一下相关的数据结构了,主要是状态和消息。
节点的状态主要包含三部分:
这里列出了三阶段协议相关的消息结构,其中PRE-PREPARE消息包含新生成的区块,其他消息则主要包含一些id、sequence number、区块内容摘要和签名等信息。
VIEW-CHANGE消息包含的内容比较多:
首先需要基于一个稳定的checkpoint,因此需要包含2f+1个CHECKPOINT消息以证明该checkpoint是有效的。
然后,在该checkpoint之上的所有sequence number,都需要打包对应的PRE-PREPARE消息以及2f个PREPARE消息。
NEW-VIEW消息首先需要包含2f+1个VIEW-CHANGE消息,以证明确实有超过2/3的节点同意在更高的view上进行新一轮共识。
然后,根据收到的所有VIEW-CHANGE消息中的checkpoint信息,找出最小值min_s和最大值max_s,打包该区间内的每一个sequence number对应的PRE-PREPARE消息。
特别的,为了减少重复验证,如果在某个sequence number上从未进行过view change(即第一轮就达成了共识),则PRE-PREPARE中包含一个特殊的null请求的摘要信息。
具体逻辑参见下图:
如果想要了解更多的算法细节,可以阅读论文原文:
http://pmg.csail.mit.edu/papers/osdi99.pdf
更多文章欢迎关注“鑫鑫点灯”专栏:https://blog.csdn.net/turkeycock
或关注飞久微信公众号: