一文读懂Alaya共识方案(四):Giskard共识协议流程
Giskard共识协议流程
1. 正常流程
图1 Giskard正常流程
提议人在成功进入到新的View后,会连续产生多个区块。将消息:
PrepareBlock广播给验证人。
逐个验证区块:验证人校验签名和时间窗口,执行区块,成功后产生PrepareVote。当PrepareVote对应的父区块收集到N-f个PrepareVote时,使用BLS将N-f个PrepareVote的个体签名聚合成一个聚合签名,并将当前PrepareVote进行广播。我们将N-f个PrepareVote简化为prepareQC(quorum certificate) 。
当节点在当前view内最后一个区块收到prepareQC,则会进入新的view开始下一轮投票。
为了更安全的投票,投票必须符合以下规则:
区块执行后才能进行投票
诚实的节点只能对当前View提议的区块进行投票
诚实的节点当View超时后不能再进行投票,也不接收当前View的投票
在同一个View内,相同高度的两个区块只能投其中一个
当对Block(n+1)进行投票时,Block(n)需达到prepareQC
2. ViewChange流程
图2 时间窗口出块完成时切换窗口
图3 时间窗口出块未完成但过期时切换窗口
图4 viewchange投票流程
假设每个时间窗口最多允许产生n个区块,viewchange流程如下:
如果在时间窗口内,收到第n块的prepareQC,则更新本地view+1,进入新的正常流程,这种情况下如果是新提议人达成n的QC,则开始广播第一个区块,如图2所示,高度为BlockNumber(n)+1 ,并会携带n区块的prepareQC。
如果时间窗口过期,节点首先会拒绝对当前提议人的区块产生新的投票,同时没有收到第n块的prepareQC,则发送ViewChange消息,如图3所示。
下一个时间窗口的提议人收到N-f个ViewChange消息(我们将N-f个ViewChange消息简称为viewchangeQC )之后,使用BLS签名聚合成一个QC签名,然后更新本地ViewNumber+1,由于采用两轮投票锁定区块的规则,新提议人可以简单地从收到N-f个viewchange消息中选择HighestQCBlock,将新的区块序号定为HighestQCBlock+1,如图4所示,然后广播第一个区块给各验证人节点,并携带HighestQCBlock的QC签名和viewchange的QC签名。
各验证人节点会根据收到的HighestQCBlock+1序号开始新一轮共识。
3. 区块确认
| Pipelining流程
在传统BFT(PBFT, Tendermint)中,每个区块通常都需要经历明确的Pre-Commit和Commit阶段才最终确认:
: 当节点收到N-f个Prepare投票时会广播Pre-Commit, Pre-Commit可以看作对Prepare阶段的确认。
: 当收到N-f个Pre-Commit投票时,表明所有节点对指定消息达成一致,提交到本地磁盘。
根据上面的介绍,Giskard共识协议中也有类似的Prepare和ViewChange两个阶段,每个区块只有Prepare投票,没有明确的Pre-Commit和Commit阶段,那么如何达到区块的确认呢?Giskard可看作Pipeline版本的BFT,每个prepareQC都是对前面区块更高阶段的确认。
图5 Giskard确认流程
如上图所示prepareQC(2)作为Block(1)的Pre-Commit阶段,prepareQC(3)作为Block(1)的Commit阶段,Block(2)的Pre-Commit阶段。
因此在Giskard中,只有两种消息类型:prepare消息和view-change消息,每个消息的QC均采用聚合签名方式验证。
| 区块重组
假设每个view允许产生n个区块,当前view时间窗口超时,view切换到,此时产生的区块只有部分得到QC,部分区块会进行重组,重组规则如下:
Pre-Commit状态的区块被锁定,不能被重组,即如果当前节点在高度h上有Pre-Commit状态的区块,当前节点不能在高度h产生新的区块,也不能在高度h对其他区块投票。
Prepare状态的区块可以被重组,即如果当前节点在高度h上有Prepare状态的区块,当前节点可以在高度h产生新的区块,或者在高度h对其他区块投票(只允许对更高viewnumber的区块投票)。
(未完待续)
Scan QR code with WeChat