discovery: attempt to request the full chan ann for stray chan updates

In this commit, we extend the AuthenticatedGossiper to take advantage of
the new query features in the case that it gets a channel update w/o
first receiving the full channel announcement. If this happens, we'll
attempt to find a syncer that's fully synced, and request the channel
announcement from it.
This commit is contained in:
Olaoluwa Osuntokun 2018-04-27 16:31:15 -07:00
parent 6a6700e629
commit 994d9cf7e4
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21
2 changed files with 52 additions and 2 deletions

@ -1873,12 +1873,28 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
d.pChanUpdMtx.Lock()
d.prematureChannelUpdates[shortChanID] = append(
d.prematureChannelUpdates[shortChanID],
nMsg)
nMsg,
)
d.pChanUpdMtx.Unlock()
log.Debugf("Got ChannelUpdate for edge not "+
"found in graph(shortChanID=%v), "+
"saving for reprocessing later",
shortChanID)
// If the node supports it, we may try to
// request the chan ann from it.
go func() {
reqErr := d.maybeRequestChanAnn(
msg.ShortChannelID,
)
if reqErr != nil {
log.Errorf("unable to request ann "+
"for chan_id=%v: %v", shortChanID,
reqErr)
}
}()
nMsg.err <- nil
return nil
default:
@ -2445,3 +2461,36 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo,
return chanAnn, chanUpdate, err
}
// maybeRequestChanAnn will attempt to request the full channel announcement
// for a particular short chan ID. We do this in the case that we get a channel
// update, yet don't already have a channel announcement for it.
func (d *AuthenticatedGossiper) maybeRequestChanAnn(cid lnwire.ShortChannelID) error {
d.syncerMtx.Lock()
defer d.syncerMtx.Unlock()
for nodeID, syncer := range d.peerSyncers {
// If this syncer is already at the terminal state, then we'll
// chose it to request the fully channel update.
if syncer.SyncState() == chansSynced {
pub, err := btcec.ParsePubKey(nodeID[:], btcec.S256())
if err != nil {
return err
}
log.Debugf("attempting to request chan ann for "+
"chan_id=%v from node=%x", cid, nodeID[:])
return d.cfg.SendToPeer(pub, &lnwire.QueryShortChanIDs{
ChainHash: d.cfg.ChainHash,
EncodingType: lnwire.EncodingSortedPlain,
ShortChanIDs: []lnwire.ShortChannelID{cid},
})
}
}
log.Debugf("unable to find peer to request chan ann for chan_id=%v "+
"from", cid)
return nil
}

@ -256,7 +256,8 @@ func (g *gossipSyncer) channelGraphSyncer() {
for {
state := atomic.LoadUint32(&g.state)
log.Debugf("gossipSyncer(%x): state=%v", g.peerPub[:], state)
log.Debugf("gossipSyncer(%x): state=%v", g.peerPub[:],
syncerState(state))
switch syncerState(state) {
// When we're in this state, we're trying to synchronize our