区块变更通知
写节点每确定一次新的 canonical head,就向 Kafka 内部 topic 发布一条BlockChangeNotification:
规范链与分叉块
规范链是写节点当前 canonical head 所在的那条链。写节点发布通知前,把上一条已发布的区块与新 head 做共同祖先比较:changeType 为 1,newBlocks 按高度升序;存在被丢弃的分支时 changeType 为 2,同时带 dropBlocks 和 newBlocks。
被丢弃的块就是分叉块。它们不会从系统里消失:
同一高度在 S3 外部桶的前缀
{chainID}[/{version}]/{height}/ 下可能有多个对象,is_fork 是区分它们的唯一依据。查询节点冷启动追赶时靠它把高度解析成规范哈希。
已发布与已确认
写节点发布通知的那一刻,查询节点还没有应用这个区块。直接订阅内部 topic 的消费者会在“去查还查不到”的时候收到通知。consistency-checker 在中间加了一道确认:is_fork 区分。重组时 checker 先发 drop 通知,再发新块通知。
外部消费者因此得到一个保证:收到通知时,去查询集群一定能读到这个区块。等待副本超过 check_timeout_ms(默认 2000 毫秒)仍未达标时,checker 不发布该区块并整体重试。
同一个区块,三处记录
一个区块被确认后,链路上有三个地方各自记着它,服务不同的读取者:
leafage-evm 和 consistency-checker 都提供
getLatestBlock / getBlockByHeight / getBlockById / blockIsValid,方法名相同但语义不同:前者返回本节点当前视图,后者返回已确认的区块。
小结
- 区块变更通知只含哈希、高度等元信息,单分区全序,仅 Leader 发布;数据体在 S3。
- 重组表达为
changeType: 2加dropBlocks;被丢弃的分叉块在 S3 和查询节点内存中都保留,由 consistency-checker 回写is_fork。 - 已发布(内部 topic)与已确认(外部 topic)是两条不同的流,外部消费者应当只订阅后者。
- 已确认高度写在 etcd 的
lastBlockNumber,是 nodex-proxy 判断 State / Archive 的依据。