当前同步算法
dag 同步
确认历史区块
tips 节点
即 dag 的尖端节点。也就是如果我们把 dag 看成单链,那么就是当前高度最高的节点,放到 dag 图中,则是在当前某个时间领域内的无子区块的节点。
获得 current tips
只有 Genesis 区块
此时 Genesis 区块就是 current tips。 Genesis 是一个特殊的 tips,如果当前 tips 是 Genesis,那么说明 dag 中前面没有 parents 了。
starcoin 的单链在转向 dag 升级时,会指定某一个区块为 dag 的 Genesis 区块,以此区块开始,后续都会走 dag 协议。
普通的 tips 区块
例如上图的 J,M 和 L 就是普通的 tips 节点。普通 tips 节点,经过不断的回溯父节点,总是能回到 Genesis 节点,可能有些 tips 节点能提前回到 Genesis 节点,但若两个 node 有相同的 dag,则它们返回到 Genesis 所沿途的节点应该是一致的。
确认 tips 节点
为什么要确认 tisp 节点
相当于两个 node 要先握手,保证两个 node 的tips节点之前的 dag 结构是一致的。
构建 accumulator
1)Genesis 是 accumulator 的最左叶子节点;
2)每次tips 节点的子节点做 hash 运算,作为本次 tips节点的下一个 accumulator 兄弟节点;
如下图,从 Genesis 开始,accumulator 的叶子节点都是上一个节点的子节点的 hash,从而构建出一个 accumulator(只画出叶子节点,省略没有画出 accumulator 的根节点和非叶子节点):
使用 accumulator 确认 tips 节点
构建好 accumulator 后,可以拿出 accumulator 的最后一个节点(存放在 startup info 中,似乎从 accumulator 中读也行)去另一个 node 中同步看大家的 accumulator 是否相同,若相同,开始从 tips 节点拉取后面的子节点。
例如,另一个节点已经产生了新的节点 P 和 V,它的 dag 结构和 accumulator 如下(新增黄色节点):
可以看到,另一个节点的 accumulator 和 本节点的 accumulator 从 JMKL 开始就不一致,因此确认的 tips应该是 JMKL 而不是 JML。
另一种情况是如下图:
这种情况下,由于 V 的父节点包含了 K,那么导致 ac
cumulator 从 JMKL 开始后面也是不一致的,那么此时确认的 tips 节点应该也是 JMKL,即应该从 JMKL 开始同步后续的子节点。
使用时间戳保证 accumulator 不会混乱
若不控制节点的插入,那么 accumulator 会变得很不稳定,例如下图中,突然插入一个 X 节点,导致几乎整个 accumulator 都变了:
因此必须防止 X 这样的节点插入进来,因此,dag 的插入应该对区块的时间戳进行校验,若父子区块的时间戳差值超过窗口时间,则子区块应该被拒绝,从而减少 accumulator 的不稳定。