节点信息初始化
初始化包含了所有的基本信息
局部代码
// 位置 node/node.go NewNode,大约153行
node := &Node{
config: config,
genesisDoc: genDoc,
privValidator: privValidator,
transport: transport,
sw: sw,
addrBook: addrBook,
nodeInfo: nodeInfo,
nodeKey: nodeKey,
stateDB: stateDB,
blockStore: blockStore,
bcReactor: bcReactor,
mempoolReactor: mempoolReactor,
consensusState: consensusState,
consensusReactor: consensusReactor,
evidencePool: evidencePool,
proxyApp: proxyApp,
txIndexer: txIndexer,
indexerService: indexerService,
eventBus: eventBus,
}
服务启动
服务调度common/server.go func Start ,各自调用自己的OnStart方法
服务启动的所有开始入口node/node.go
OnStart方法
p2p服务启动代码
addr, err := p2p.NewNetAddressStringWithOptionalID(n.config.P2P.ListenAddress)
if err != nil {
return err
}
if err := n.transport.Listen(*addr); err != nil {
return err
}
下面都继承p2p/base_reactor interface Reactor, 调用自己的OnStart方法
- pex/pex_reactor.go
别的省略
seed mode
模式一:seed/crawler mode
- 2分钟内不需要重拨
- 30秒更新一次peer
- 超过3小时的长连接断开
模式二:非seed/crawler mode
...
Accept Peers
入口位置:p2p/switch.go(func OnStart),大约204行
// 入口
go sw.acceptRoutine()
handshake握手
解释: 使用gosip协议,进行与其它节点进行的通信
代码位置:p2p/transport.go(func handshake),大约430行
推送nodeinfo
// push nodeinfo
go func(errc chan<- error, c net.Conn) {
_, err := cdc.MarshalBinaryLengthPrefixedWriter(c, ourNodeInfo)
errc <- err
}(errc, c)
拉去nodeinfo
// pull nodeinfo
go func(errc chan<- error, c net.Conn) {
_, err := cdc.UnmarshalBinaryLengthPrefixedReader(
c,
&peerNodeInfo,
int64(MaxNodeInfoSize()),
)
errc <- err
}(errc, c)
请求peer
请求peer服务端
位置:p2p/switch.go(func DialPeerWithAddress),大约448行
代码
func (sw *Switch) DialPeerWithAddress(addr *NetAddress, persistent bool) error {
sw.dialing.Set(string(addr.ID), addr)
defer sw.dialing.Delete(string(addr.ID))
return sw.addOutboundPeerWithConfig(addr, sw.config, persistent)
}
nodeinfo版本验证(有待确认)
位置:p2p/tansport.go(func upgrade),大约353行
nodeInfo.ValidateBasic()
数据发送与接收
查找过程
节点发送与接收时,将nodeinfo信息进行包装,然后通过server文件进行中转,触发onstart,然后再调用MConnection,再次触发onstart
位置:p2p/conn/connection.go(func OnStart),大约193行
代码
go c.sendRoutine()
go c.recvRoutine()
网友评论