viewchange struct

1、当当前执行区块的seqNocheckpoint周期(即pbftcore.K)的整数倍的时候,就初始化checkpoint的信息。

2、当接受到一个block发送preprepare消息的时候,都将会将给该block分配的seqNo+1seqNo默认是从0开始的。如果发生了viewchange且当前的nv.Xset里有给block重新分配的序号,那么seqNo就等于nv.Xset里存的seqNo的最大值;如果nv.Xset里为空,那么seqNo就等于当前结点的低水位。

数据清空

1、何时清空blockstore?

  • 当节点接受到的checkpoint对应blockseqNo大于本节点的高水位并且大于高水位的checkpoint的个数大于f+1的时候,那么该节点刚执行完的block.seqNo对应的checkpoint将永远也达不到stable状态(stable状态是指收到2f+1条针对该block.seqNocheckpoint信息),因为别的节点比本节点快太多,本节点错过了接受其他节点发送该block.seqNo对应的checkpoint的时机。在这种状况下,本节点将会清空blockStoreoutstandingBlocks,从数据库里也删除block,重新定义高低水位。当新的区块来到时,如果是非主节点就会调用recvPrePrepare(),在其中针对blockseqNo在新的高低水位中进行判断;如果该节点是主节点,它就会调用sendPrePrepare,此时分配的seqNo就不在高低水位之间,就会触发viewchange,在viewchange的过程中会将pbftcore.seqNo更新为当前的低水位或者是seqNo就等于nv.Xset里存的seqNo的最大值。

  • 在调用函数movewatermarks()的时候,如果certstore存储blockseqNo小于低水位就把block从数据库里删除,从blockstore里删除。

  • viewchange结束后blockstore清空。blockStore里存储的始终是当前view下共识的区块,psetqset里始终存储的是当前view下的request。所以如果再次发生viewchangeblockStorepsetqset里的区块能正常进行对比,不会报错。

2、何时清空psetqsetcertstore?

在调用函数movewatermarks()的时候,如果psetqsetcertstore存储的seqNo小于低水位,就清空。

3、psetqset能不能每当一个block记录到区块链上,就清空一次psetqset?能不能不用psetqset了?

不能。如果一个block处于committed状态后,就把它从psetqset里删除。假如再此时停止了挖矿,再重新启动节点的时候,psetqset为空,那么在restoreState()的时候就不能从psetqset里面获得最新的关于viewseqNo的信息,结果导致seqNoview又从0开始。在fabric里面,除了第一次启动节点时会出现psetqset为空的情况,在接下来的启动中不会出现psetqset为空的情况,因为在进行movewatermarks(n)的时候,低水位的值计算是小于n的,也就是说psetqset里面只会删除一部分关于request的信息,不会全删完。

4、在fabric里面:假设一种情况,有一个RequestBatch1进行共识,里面的请求都存储在了psetqset里,一轮共识结束后,psetqset里面并没有把RequestBatch1里的请求进行删除。然后又来了一个RequestBatch2,RequestBatch1里的请求也都存储在了psetqset里面,进行共识的过程中发生了viewchange,此时会对psetqset里面的请求重新进行共识,其中包括RequestBatch1里面的请求,对RequestBatch1里面的请求再重新进行共识有无必要?

有必要。RequestBatch1里面的请求共识达到committed状态,只能是说明在该节点上RequestBatch1里的请求得到了其他节点的认可,但是其他节点上RequestBatch1能否达到committed状态还不一定。当节点在一个checkpoint上收到2f+1条来自其他节点的checkpoint的信息的时候,说明2f+1个其他节点都完成了该checkpoint所在之前请求的共识,此时便可移动高低水位,把checkpoint之前的请求从psetqset等里删除。

geth-pbtf里面,当发生viewchange的时候,我们就没必要对RequestBatch1(这里相当于是Block1)重新进行共识了,因为一轮共识结束之后,我们就把该区块放在了区块链上了。

Last updated

Was this helpful?