1.P2P连入网络需要seed
func (pc peerConn) ID() ID {
return PubKeyToID(pc.conn.(*tmconn.SecretConnection).RemotePubKey())
}
节点连接分为inbound和outbound。inbound的意思是别的节点连入自己,outbound的意思是自己主动连接别的节点
// IsOutbound returns true if the connection is outbound, false otherwise.
func (p *peer) IsOutbound() bool {
return p.peerConn.outbound
}
outbound的连接有两种:
- 节点启动的时候指定seeds,启动的时候会尝试连接所有的seed
- L初始化的时候有pex reactor(peer exchange),会启动goroutine定期检测outbound的数量,如果少于10个,就从本地保存的节点连接。
inbound的连接只有一种:
节点启动的时候监听connection,有连接连入的时候会判断目前是否有50个连接,如果够了就忽略新的连接。所以一般情况下节点的outbound数量至少为10,总的连接数量为50个(可能会有多于50个的情况,比如刚开始指定过多的seeds)
2.peer.go源码
P2P模块初始化的时候,也会初始化mempool reactor、blockchain reactor、consensus reactor、evidence reactor、pex reactor,然后add到p2p模块,不同的reactor带不同的channel id
当mempool、blockchain、consensus、evidence模块发送消息的时候,调用p2p模块的send,参数有channel id。
// Send msg bytes to the channel identified by chID byte. Returns false if the
// send queue is full after timeout, specified by MConnection.
func (p *peer) Send(chID byte, msgBytes []byte) bool {
if !p.IsRunning() {
// see Switch#Broadcast, where we fetch the list of peers and loop over
// them - while we're looping, one peer may be removed and stopped.
return false
} else if !p.hasChannel(chID) {
return false
}
return p.mconn.Send(chID, msgBytes)
}
对端节点p2p模块收到消息后,会根据channel id把消息转发给对应的模块。(create channel,join in channel)