{"content":{"title":"Venus 同步代码解读","body":"`venus/app/submodule/syncer/syncer_submodule.go`的`Start()`方法会启动 一个for循环，不停的接受订阅`/fil/blocks/#{networkName}`的区块信息，然后调用`handleIncomingBlocks()`方法处理收到的区块。处理方法逻辑也非常简单，只有两个动作，一个是把收到的区块header存储到数据库。另一动作是开启一个goroutine，在goroutine里面请求一下header对应的messages（但是不存储，奇怪，为什么不存储呐？），然后把header通过调用`pkg/chainsync/dispatcher/dispatcher.go::SendGossipBlock()`方法把区块header广播出去。\r\n\r\n不管是`SendGossipBlock()`还是`SendOwnBlock()`，两个方法都是把要发送出去的参数放进`imcomming`的一个channel，然后`processingIncoming()`会通过for循环不停的读取`incomming`channel的信息，然后把信息通过调用`pkc/chainsync/types/target_tracker.go::Add()`方法，把`Target`对象放入`TargetTracker`对象，这个对象主要作用是一个优先级队列。\r\n\r\n`pkg/chainsync/dispatcher/dispatcher.go::syncWoker()`方法是在系统启动时就开启的一个for循环goroutine，方法会监听一个target的channel，每当有新的target通过`target_tracker::Add()`加入到队列时，就会触发channel，`syncWorkder()`方法内部就会调用`selectTarget()`来获取优先级最高的target，然后开启一个goroutine去调用`syncer.HandleNewTipSet()`方法来获取一系列tipset，对tipset的block进行验证，计算里面的messsage，修改区块状态。"},"author":{"user":"https://learnblockchain.cn/people/808","address":null},"history":"QmYeyYkdgmEecsG8CkAcHtzAX1aSTKLyjQsnNvWZMv2eNi","timestamp":1684743958,"version":1}