0.25版本的bft模块,在收到chain的rich_status时,只有 status_height + 1 == height 或 status_height == height 时,才会更新 bft 当前的 pre_hash,这里似乎有bug。
当 status_height > height 时,不更新 pre_hash,但当前高度 height 会跃升到 status_height,此时当前 height 对应的 pre_hash 是不正确的。
后续会造成 bft 收到 status_height + 1 的提案验证不通过,后续只能投空票。另外不能更新 bft 当前 proof,在高轮次节点若为提案者,发不出提案,会造成长时间不出块。
关于bft模块更新 pre_hash的疑问
这个提问有价值,关键是这个 self.pre_hash 这个字段的设置,对于跳高度不友好,容易导致混乱,所以用了保守的设置,等待chain重发status的时候,进行设置。
后续的cita-ee 版本,把这个字段 变成了 pre_hashes : BTreemap<usize,H256>. 高度对应pre_hash,这样就避免了混乱
容易导致混乱,除了上面描述的可能导致长时间不出块外,还有可能导致哪些混乱呢。
为什么会导致长时间不出块? 跳高度的前提是本节点至少落后网络中 2/3+ 节点1个块,也就是网络中去除了本节点,也一样能出块。
我说的混乱是没有高度对应的pre_hash, 有可能并不是正在共识的高度的pre_hash. 使用高度对应以后,程序就能明确的知道pre_hash的缺失了
pre_hashes 是一种解决方案;但是撸代码发现,只要改成:当 status_height >= self.height 就 self.pre_hash = status.pre_hash,应该是减少或杜绝混乱,无需等待18s(或18s倍数)后,再次收到链的状态通知,不知道这个方案会造成什么混乱?
方案没问题,可以这么改