network: rework discoverer/server interaction
* treat connected/handshaked peers separately in the discoverer, save "original" address for connected ones, it can be a name instead of IP and it's important to keep it to avoid reconnections * store name->IP mapping for seeds if and when they're connected to avoid reconnections * block seed if it's detected to be our own node (which is often the case for small private networks) * add an event for handshaked peers in the server, connected but non-handshaked ones are not really helpful for MinPeers or GetAddr logic Fixes #2796.
This commit is contained in:
parent
6ba4afc977
commit
23f118a1a9
10 changed files with 180 additions and 100 deletions
|
@ -127,6 +127,7 @@ type (
|
|||
|
||||
register chan Peer
|
||||
unregister chan peerDrop
|
||||
handshake chan Peer
|
||||
quit chan struct{}
|
||||
relayFin chan struct{}
|
||||
|
||||
|
@ -181,6 +182,7 @@ func newServerFromConstructors(config ServerConfig, chain Ledger, stSync StateSy
|
|||
relayFin: make(chan struct{}),
|
||||
register: make(chan Peer),
|
||||
unregister: make(chan peerDrop),
|
||||
handshake: make(chan Peer),
|
||||
txInMap: make(map[util.Uint256]struct{}),
|
||||
peers: make(map[Peer]bool),
|
||||
syncReached: atomic.NewBool(false),
|
||||
|
@ -462,31 +464,10 @@ func (s *Server) run() {
|
|||
zap.Stringer("addr", drop.peer.RemoteAddr()),
|
||||
zap.Error(drop.reason),
|
||||
zap.Int("peerCount", s.PeerCount()))
|
||||
addr := drop.peer.PeerAddr().String()
|
||||
if errors.Is(drop.reason, errIdenticalID) {
|
||||
s.discovery.RegisterBadAddr(addr)
|
||||
} else if errors.Is(drop.reason, errAlreadyConnected) {
|
||||
// There is a race condition when peer can be disconnected twice for the this reason
|
||||
// which can lead to no connections to peer at all. Here we check for such a possibility.
|
||||
stillConnected := false
|
||||
s.lock.RLock()
|
||||
verDrop := drop.peer.Version()
|
||||
addr := drop.peer.PeerAddr().String()
|
||||
if verDrop != nil {
|
||||
for peer := range s.peers {
|
||||
ver := peer.Version()
|
||||
// Already connected, drop this connection.
|
||||
if ver != nil && ver.Nonce == verDrop.Nonce && peer.PeerAddr().String() == addr {
|
||||
stillConnected = true
|
||||
}
|
||||
}
|
||||
}
|
||||
s.lock.RUnlock()
|
||||
if !stillConnected {
|
||||
s.discovery.UnregisterConnectedAddr(addr)
|
||||
}
|
||||
s.discovery.RegisterSelf(drop.peer)
|
||||
} else {
|
||||
s.discovery.UnregisterConnectedAddr(addr)
|
||||
s.discovery.UnregisterConnected(drop.peer, errors.Is(drop.reason, errAlreadyConnected))
|
||||
}
|
||||
updatePeersConnectedMetric(s.PeerCount())
|
||||
} else {
|
||||
|
@ -494,6 +475,19 @@ func (s *Server) run() {
|
|||
// because we have two goroutines sending signals here
|
||||
s.lock.Unlock()
|
||||
}
|
||||
|
||||
case p := <-s.handshake:
|
||||
ver := p.Version()
|
||||
s.log.Info("started protocol",
|
||||
zap.Stringer("addr", p.RemoteAddr()),
|
||||
zap.ByteString("userAgent", ver.UserAgent),
|
||||
zap.Uint32("startHeight", p.LastBlockIndex()),
|
||||
zap.Uint32("id", ver.Nonce))
|
||||
|
||||
s.discovery.RegisterGood(p)
|
||||
|
||||
s.tryInitStateSync()
|
||||
s.tryStartServices()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -700,7 +694,6 @@ func (s *Server) handleVersionCmd(p Peer, version *payload.Version) error {
|
|||
}
|
||||
}
|
||||
s.lock.RUnlock()
|
||||
s.discovery.RegisterConnectedAddr(peerAddr)
|
||||
return p.SendVersionAck(NewMessage(CMDVerack, payload.NewNullPayload()))
|
||||
}
|
||||
|
||||
|
@ -1356,9 +1349,6 @@ func (s *Server) handleMessage(peer Peer, msg *Message) error {
|
|||
return err
|
||||
}
|
||||
go peer.StartProtocol()
|
||||
|
||||
s.tryInitStateSync()
|
||||
s.tryStartServices()
|
||||
default:
|
||||
return fmt.Errorf("received '%s' during handshake", msg.Command.String())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue