赞
踩
很多人喜欢玩狼人杀,我用狼人杀跟拜占庭将军问题做个类比。
在狼人杀开局的时候,你是好人,并且不知道自己的队友是谁,也不知道狼人是谁,但所有的好人都有一个共同的目的:干死狼人,好人获胜。所以游戏中需要使用技巧和策略,达成目的。
拜占庭将军问题是类似的,好的将军不知道其他将军是好的,还是坏的,但所有好的将军的目的是:行动一致,共同进退。所以,它们也需要策略达成一致。
BFT 是一类解决拜占庭将军问题的策略/算法:让非拜占庭节点达成一致的算法。在这类论文中,拜占庭节点指“坏”的将军,非拜占庭节点指“好”的将军。
PBFT 作为解决拜占庭问题的策略:非拜占庭节点不知道哪些是拜占庭节点,哪些是非拜占庭节点,PBFT 要让非拜占庭节点达成一致。PBFT算法天然适用于区块技术中,来解决共识问题。
PBFT拥有一个很大的一个特点:容错,可以在少数节点作恶场景中达成共识。它采用签名、签名验证、哈希等密码学算法确保消息传递过程中的防篡改性、防伪造性、不可抵赖性,但是PBFT只能有不少于 ( 2*f+1 ) 个非恶意节点正常工作,该系统就能达成一致性。
(1)节点ID && 节点索引
为了防止节点作恶,PBFT共识过程中每个共识节点均对其发送的消息进行签名,对收到的消息包进行验签名,因此每个节点均维护一份公私钥对,私钥用于对发送的消息进行签名,公钥作为节点ID,用于标识和验签。
(2)视图(view)
就是根据view和block_number来计算出在本轮共识的leader是谁。计算公式如下:
leader_idx = (view + block_number) % node_num
可以说view值就是对应leader的索引。根据上面这个公式可以看出,当没有leader不是作恶节点,block正常上链,block_number是自增的,view值是不变的,那么leader是轮流做。当leader是作恶节点,发现leader是作恶节点时,就会全局广播view+1,这是block_number是没有发生变化的,导致切换leader,从新共识。
(1)系统架构流程
PBFT共识主要包括两个线程:
PBFTSealer: PBFT打包线程,负责从交易池取交易,并将打包好的区块封装成PBFT Prepare包,交给PBFTEngine处理;
PBFTEngine: PBFT共识线程,从PBFTSealer或者P2P网络接收PBFT共识消息包,区块验证器(Blockverifier)负责开始执行区块,完成共识流程,将达成共识的区块写入区块链,区块上链后,从交易池中删除已经上链的交易。
(2)PBFT核心流程
下面对三个阶段详细展开叙述。
PBFT共识算法中,共识节点轮流出块,每一轮共识仅有一个leader打包区块,leader索引通过公式(block_number + current_view) % consensus_node_num计算得出。
节点计算当前leader索引与自己索引相同后,就开始打包区块。区块打包主要由PBFTSealer线程完成Prepare包,交给PBFTEngine处理进行广播。
(1)pre-prepare阶段:
每个节点都会接收到由leader节点完成Prepare包,并对prepare包做一下校验:
也就是说,假如包内有交易,会对每一笔交易进行验证,验证后会得出一个结果,这区块能不上链,把这个结果跟自己的签名信息广播给其他节点。
(2)Prepare阶段:
本阶段,已经开始收集其他节点给出结果,并作出判断,最终是否进行上链。会做出一下校验:
==注意: 只要接受到f+1节点给出结果一样,就能最终判定这个区块到底是否能够上链。我们试想,作恶节点有f个,当f+1个节点给出结果时,必然有一个结果一定是正确的。 ==
(3)Commit阶段:jiu
共识节点收到Commit包后,进入Commit阶段,jiu此阶段工作流程包括:
此过程和Prepare阶段差不多,是为了保持全局数据一致性。
Prepare阶段 是一个局部一致,不是全局诚实节点的一致,即节点 i 看到了非拜占庭节点认可了 ,但整个系统包含 3f+1 个节点,异步的系统中,存在丢包、延时、拜占庭节点故意向部分节点发送 Prepare 等拜占庭行文,节点i 无法确定,其他节点也达到 Prepare节点状态做出结果。如果少于 f 个节点完成 Prepare,然后执行了上链,系统就出现了不一致。所以,前 2 个阶段的消息,并不能让非拜占庭节点完全达成一致。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。