BFT共识层中单个节点的操作流程
概览 BFT的节点根据是否参与投票可以区分为验证节点和非验证节点,其中验证节点需要参与每一个区块的投票。 这里有几个关键的特定词: Epoch : 每个epoch中包含多个round,单个epoch中验证者列表是固定的,这个列表不会随时变动否则会影响投票递进。 Round : 每一轮Round有一个Leader,这个Leader会根据收到的交易打包出新的待投票的区块。 Voting Power : 这个一般根据质押的代币数量来决定当前节点的VP。 共识层的代码会收到别的节点打包好发过来的消息,验证者需要单独的验证消息的内容。一般在单个节点的本地在新的Round 开始的时候会设置一个计时器,这个计时器的作用就是保证每个Round都能按照一定的周期推进。 投票的内容可以区分为3大类 TC : 本次Round的Leader没有在规定的时间范围之内打包好区块并且广播出去 NEC : 本地节点对区块的内容投票不背书 QC : QC的生成需要投票背书VP达到总量的>= 2/3 + 1 TC的详细流程 待添加中… QC的详细流程 通过一段RUST实现的BFT,可以详细梳理下整个QC的流程: pub fn process_vote<VT>( &mut self, author: &NodeId<SCT::NodeIdPubKey>, vote_msg: &VoteMessage<SCT>, validators: &VT, validator_mapping: &ValidatorMapping< SCT::NodeIdPubKey, SignatureCollectionKeyPairType<SCT>, >, ) -> (Option<QuorumCertificate<SCT>>, Vec<VoteStateCommand>) 参数内容: author:这个消息的发送节点 vote_msg: 发送的消息内容,包含投票的Round和Vote内容 validators: 当前Epoch中包含的验证者列表 当本地节点收到投票消息之后: 首先需要验证Round是否已经过期(由于网络延迟等原因造成),过期消息不再被处理 本地节点需要存储当前Round收到的所有消息,包含节点ID(author)和投票内容 然后将本次的内容插入到上诉的消息列表中,然后我们就得到了当前Round的所有投票内容 这时我们就可以开始计算VP,当VP >= 总VP * 2/3 + 1的时候,当前节点就可以为本轮Round生成QC 在生成QC之前本地节点还需要循环每个消息去验证签名信息,如果有非法的签名,就把这个签名的节点信息移出pending的消息列表,当移出之后再次检查VP的数量是否能够满足上诉的条件 一般情况下签名的内容应该都是合法的,否则签名的节点会受到相应的处罚。 当所有签名合法之后开始生成QC,并且更新本地的Round到Round+1 NEC的详细流程 待添加中… ...