版本比较

密钥

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。
目录

当前同步算法

区块同步代码分析

dag 同步

名词解释

tips 节点

即 dag 的尖端节点。也就是如果我们把 dag 看成单链,那么就是当前高度最高的节点,放到 dag 图中,则是在当前某个时间领域内的无子区块的节点。

确认的 tips 节点表示需要从这些节点开始同步后续的子节点。

accumulator

merkle tree,叶子节点即我们的数据的hash值节点,可以快速验证和遍历叶子节点。更多详见https://cookbook.starcoin.org/zh/docs/concepts/accumulator

...

2)每次对 dag 节点的子节点做 hash 运算,hash 值作为 accumulator 中的节点下一个叶子节点。若 dag 的节点没有子节点,则保留下来,继续参与 hash 运算。中的节点下一个叶子节点。简单来说即广度优先搜索,将每次搜索的临时队列(存放父子节点对)做一次哈希运算,作为本次 accumulator的叶子节点。

3)若所有节点都没有子节点,则构建 accumulator 完成,tips节点也找到了。完成。

如下图,从 Genesis 开始,accumulator 的叶子节点都是上一个节点的子节点的 的叶子节点都是上一层父子节点对的 hash,从而构建出一个 accumulator(只画出叶子节点,省略没有画出 accumulator 的根节点和非叶子节点):

...

使用 accumulator 确认 tips 节点

构建好 accumulator 后,accumulator 的叶子节点中最右一个节点就是 tips 节点。

例如前面的例子中,JML 就是当前 dag 的 tips 节点。

tips节点后续节点的增加

...

节点的增加

增加节点时,如上图,分别增加了 P 和 V,它的 dag 结构和 accumulator 如下(新增黄色节点):如下:

...

可以看到,另一个节点的 可以看到,新增的节点,造成了 accumulator 和 本节点的 accumulator 从 JMKL 开始就不一致,因此确认的 tips应该是 JMKL 而不是 JML。

另一种情况是如下图:

...

这种情况下,由于 V 的父节点包含了 K,那么导致 ac

cumulator 从 JMKL 开始后面也是不一致的,那么此时确认的 tips 节点应该也是 JMKL,即应该从 JMKL 开始同步后续的子节点。

由此可见,增加新节点会造成 accumulator 的尾部发生变化,这个是正常的,对比第一张图,其 tips 节点是 JML,和其前一个节点仅少了一个 K,可见 JML 作为 tips 是很不稳定的,被新来的 PMV 替代也是正常。

因此,同步时,需要讲 JMKL 这样的节点找出来。

同步的三大任务

...

中的3,4节点更新,多了一些关系对,且新增了 accumulator 5 节点。此时,需要从 2 节点开始更新,更新节点对的时候可以采取增量更新的方式。例如,拿节点 3 来说,当发现3需要更新时,读出老的节点对,对比新的节点对,对于新增的节点对,插入db,然后计算新的 节点 3 hash。

同步的三大任务

确认边缘节点和验证历史节点

为什么要确认和验证

主要原因有两个:

1、握手;同步两个节点之间的状态;同步

2、防止恶意 peer 假冒诚实节点,必须通过历史区块的验证才能识别出节点是否为诚实节点。

确认和验证流程

...

对应代码

待补充

...

同步新的节点

流程

...

对应代码

待补充

拉取区块数据

流程

...

对应代码

待补充

攻击和异常

accumulator 的稳定性

前面说了,如果 tips 节点继续插入新的节点,那么 前面说了,如果继续插入新的节点,那么 accumulator 尾部会出现不稳定的节点,这主要是因为并发的原因,如果我们设置 ghostdag 的 k = 1,那么就跟单链一样了不稳定的问题会大大降低,但也失去了并发的特性。因此,稳定性和并发需要有一个平衡,必须保证大部分稳定(越老越稳定),也需要有一定的并发能力。

控制稳定性和并发的平衡,这里需要引入时间窗口的概念,即 tips 节点只能在特定的时间窗口内去加入新节点,过了窗口期,就只能在下一个 tips 节点加入新节点了。控制稳定性和并发的平衡,这里需要引入时间窗口的概念,即只能在特定的时间窗口内去加入新节点,过了窗口期,就只能在其它满足时间窗口内的节点加入新节点了。

以下是一个例子:

若不控制节点的插入,那么 accumulator 会变得很不稳定,例如下图中,突然插入一个 X 节点,导致几乎整个 accumulator 都变了:

...

因此,每次同步前,都必须对历史数据进行验证,直到 Genesis,也即对历史的 accmulator 叶子节点进行验证,都通过,才能同步 tips 后续节点。当然,后续节点也需要验证,保证链上的区块交易和状态都是可靠的。叶子节点进行验证,都通过,才能同步后续节点。当然,后续节点也需要验证,保证链上的区块交易和状态都是可靠的。

网络延迟高导致矿工被孤立

若某个矿工因为网络延迟的原因,造成挖了很多矿但实际跟外面的大部队已经相差很远,此时,若网络延迟恢复到正常,矿工的链就需要和大部队同步,此时就需要:

1)找到和大部队链一致的 tips 节点,验证 tips 节点的前序节点一致,然后同步后续节点。1)找到和大部队链一致的叶子节点,验证叶子节点的前序节点一致,然后同步后续节点。

2)回退交易状态,删除被回退的交易记录

第一个在同步流程中已经解决,但交易状态的回退可能需要想想怎么设计才好。相比之前的回滚, dag 引入了并发挖矿,交易的冲突或重复交易的问题会更多,还得想想有没有更好的设计。

...