peer: dispatch gossip sync in peer start

This commit moves the gossip sync dispatch
such that it is more tightly coupled to the
life cycle of the peer. In testing, I noticed
that the gossip syncer needs to be dispatched
before the first gossip messages come across
the wire.

The prior spawn location in the server happens
after starting all of the peer's goroutines,
which could permit an ordering where the
gossip syncer has not yet been registered.
The new location registers the gossip syncer
within the read handler such that the call is
blocks before any messages are read.
This commit is contained in:
Conner Fromknecht 2018-09-03 21:58:48 -07:00
parent 2415675c3d
commit adf6b8619f
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7

45
peer.go
View File

@ -320,6 +320,43 @@ func (p *peer) Start() error {
return nil
}
// initGossipSync initializes either a gossip syncer or an initial routing
// dump, depending on the negotiated synchronization method.
func (p *peer) initGossipSync() {
switch {
// If the remote peer knows of the new gossip queries feature, then
// we'll create a new gossipSyncer in the AuthenticatedGossiper for it.
case p.remoteLocalFeatures.HasFeature(lnwire.GossipQueriesOptional):
srvrLog.Infof("Negotiated chan series queries with %x",
p.pubKeyBytes[:])
// We'll only request channel updates from the remote peer if
// its enabled in the config, or we're already getting updates
// from enough peers.
//
// TODO(roasbeef): craft s.t. we only get updates from a few
// peers
recvUpdates := !cfg.NoChanUpdates
// Register the this peer's for gossip syncer with the gossiper.
// This is blocks synchronously to ensure the gossip syncer is
// registered with the gossiper before attempting to read
// messages from the remote peer.
p.server.authGossiper.InitSyncState(p, recvUpdates)
// If the remote peer has the initial sync feature bit set, then we'll
// being the synchronization protocol to exchange authenticated channel
// graph edges/vertexes, but only if they don't know of the new gossip
// queries.
case p.remoteLocalFeatures.HasFeature(lnwire.InitialRoutingSync):
srvrLog.Infof("Requesting full table sync with %x",
p.pubKeyBytes[:])
go p.server.authGossiper.SynchronizeNode(p)
}
}
// QuitSignal is a method that should return a channel which will be sent upon
// or closed once the backing peer exits. This allows callers using the
// interface to cancel any processing in the event the backing implementation
@ -877,6 +914,14 @@ func (p *peer) readHandler() {
p.Disconnect(err)
})
// Initialize our negotiated gossip sync method before reading
// messages off the wire. When using gossip queries, this ensures
// a gossip syncer is active by the time query messages arrive.
//
// TODO(conner): have peer store gossip syncer directly and bypass
// gossiper?
p.initGossipSync()
discStream := newDiscMsgStream(p)
discStream.Start()
defer discStream.Stop()