server: request addresses from new peers once they can process messages

This was previously done within the OnVersion listener, which should not
be a blocking operation. It turns out that requesting these messages
there can lead to blocking due to peers not being able to process
messages since their message queues have yet to start. Therefore, we'll
now request within handleAddPeerMsg, which should allow it to go
through.
This commit is contained in:
Wilmer Paulino 2019-10-11 18:24:31 -04:00
parent a1a5bfa819
commit 769c4e152f
No known key found for this signature in database
GPG key ID: 6DF57B9F9514972F

View file

@ -438,11 +438,6 @@ func (sp *serverPeer) OnVersion(_ *peer.Peer, msg *wire.MsgVersion) *wire.MsgRej
return wire.NewMsgReject(msg.Command(), wire.RejectNonstandard, reason) return wire.NewMsgReject(msg.Command(), wire.RejectNonstandard, reason)
} }
// Update the address manager and request known addresses from the
// remote peer for outbound connections. This is skipped when running
// on the simulation test network since it is only intended to connect
// to specified peers and actively avoids advertising and connecting to
// discovered peers.
if !cfg.SimNet && !isInbound { if !cfg.SimNet && !isInbound {
// After soft-fork activation, only make outbound // After soft-fork activation, only make outbound
// connection to peers if they flag that they're segwit // connection to peers if they flag that they're segwit
@ -461,29 +456,6 @@ func (sp *serverPeer) OnVersion(_ *peer.Peer, msg *wire.MsgVersion) *wire.MsgRej
sp.Disconnect() sp.Disconnect()
return nil return nil
} }
// Advertise the local address when the server accepts incoming
// connections and it believes itself to be close to the best known tip.
if !cfg.DisableListen && sp.server.syncManager.IsCurrent() {
// Get address that best matches.
lna := addrManager.GetBestLocalAddress(remoteAddr)
if addrmgr.IsRoutable(lna) {
// Filter addresses the peer already knows about.
addresses := []*wire.NetAddress{lna}
sp.pushAddrMsg(addresses)
}
}
// Request known addresses if the server address manager needs
// more and the peer has a protocol version new enough to
// include a timestamp with addresses.
hasTimestamp := sp.ProtocolVersion() >= wire.NetAddressTimeVersion
if addrManager.NeedMoreAddresses() && hasTimestamp {
sp.QueueMessage(wire.NewMsgGetAddr(), nil)
}
// Mark the address as a known good address.
addrManager.Good(remoteAddr)
} }
// Add the remote peer time as a sample for creating an offset against // Add the remote peer time as a sample for creating an offset against
@ -1661,6 +1633,37 @@ func (s *server) handleAddPeerMsg(state *peerState, sp *serverPeer) bool {
// Signal the sync manager this peer is a new sync candidate. // Signal the sync manager this peer is a new sync candidate.
s.syncManager.NewPeer(sp.Peer) s.syncManager.NewPeer(sp.Peer)
// Update the address manager and request known addresses from the
// remote peer for outbound connections. This is skipped when running on
// the simulation test network since it is only intended to connect to
// specified peers and actively avoids advertising and connecting to
// discovered peers.
if !cfg.SimNet && !sp.Inbound() {
// Advertise the local address when the server accepts incoming
// connections and it believes itself to be close to the best
// known tip.
if !cfg.DisableListen && s.syncManager.IsCurrent() {
// Get address that best matches.
lna := s.addrManager.GetBestLocalAddress(sp.NA())
if addrmgr.IsRoutable(lna) {
// Filter addresses the peer already knows about.
addresses := []*wire.NetAddress{lna}
sp.pushAddrMsg(addresses)
}
}
// Request known addresses if the server address manager needs
// more and the peer has a protocol version new enough to
// include a timestamp with addresses.
hasTimestamp := sp.ProtocolVersion() >= wire.NetAddressTimeVersion
if s.addrManager.NeedMoreAddresses() && hasTimestamp {
sp.QueueMessage(wire.NewMsgGetAddr(), nil)
}
// Mark the address as a known good address.
s.addrManager.Good(sp.NA())
}
return true return true
} }