diff --git a/discovery/gossiper.go b/discovery/gossiper.go index 15dfe796e..caa1c1637 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -316,6 +316,11 @@ type Config struct { // ChannelID. This is used to sign updates for them if the channel has // no AuthProof and the option-scid-alias feature bit was negotiated. GetAlias func(lnwire.ChannelID) (lnwire.ShortChannelID, error) + + // FindChannel allows the gossiper to find a channel that we're party + // to without iterating over the entire set of open channels. + FindChannel func(node *btcec.PublicKey, chanID lnwire.ChannelID) ( + *channeldb.OpenChannel, error) } // processedNetworkMsg is a wrapper around networkMsg and a boolean. It is @@ -3016,6 +3021,16 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg, ann.ShortChannelID, ) if err != nil { + _, err = d.cfg.FindChannel(nMsg.source, ann.ChannelID) + if err != nil { + err := fmt.Errorf("unable to store the proof for "+ + "short_chan_id=%v: %v", shortChanID, err) + log.Error(err) + nMsg.err <- err + + return nil, false + } + proof := channeldb.NewWaitingProof(nMsg.isRemote, ann) err := d.cfg.WaitingProofStore.Add(proof) if err != nil { diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go index f215b77ae..37823469c 100644 --- a/discovery/gossiper_test.go +++ b/discovery/gossiper_test.go @@ -697,6 +697,12 @@ func createChannelAnnouncement(blockHeight uint32, key1, key2 *btcec.PrivateKey, return a, nil } +func mockFindChannel(node *btcec.PublicKey, chanID lnwire.ChannelID) ( + *channeldb.OpenChannel, error) { + + return nil, nil +} + type testCtx struct { gossiper *AuthenticatedGossiper router *mockGraphSource @@ -792,6 +798,7 @@ func createTestCtx(t *testing.T, startHeight uint32) (*testCtx, error) { SignAliasUpdate: signAliasUpdate, FindBaseByAlias: findBaseByAlias, GetAlias: getAlias, + FindChannel: mockFindChannel, }, selfKeyDesc) if err := gossiper.Start(); err != nil { diff --git a/server.go b/server.go index 0f9e9d43e..03084f562 100644 --- a/server.go +++ b/server.go @@ -1022,6 +1022,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, SignAliasUpdate: s.signAliasUpdate, FindBaseByAlias: s.aliasMgr.FindBaseSCID, GetAlias: s.aliasMgr.GetPeerAlias, + FindChannel: s.findChannel, }, nodeKeyDesc) s.localChanMgr = &localchans.Manager{ @@ -1283,26 +1284,10 @@ func newServer(cfg *Config, listenAddrs []net.Addr, CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement, error) { return s.genNodeAnnouncement(true) }, - SendAnnouncement: s.authGossiper.ProcessLocalAnnouncement, - NotifyWhenOnline: s.NotifyWhenOnline, - TempChanIDSeed: chanIDSeed, - FindChannel: func(node *btcec.PublicKey, - chanID lnwire.ChannelID) (*channeldb.OpenChannel, - error) { - - nodeChans, err := s.chanStateDB.FetchOpenChannels(node) - if err != nil { - return nil, err - } - - for _, channel := range nodeChans { - if chanID.IsChanPoint(&channel.FundingOutpoint) { - return channel, nil - } - } - - return nil, fmt.Errorf("unable to find channel") - }, + SendAnnouncement: s.authGossiper.ProcessLocalAnnouncement, + NotifyWhenOnline: s.NotifyWhenOnline, + TempChanIDSeed: chanIDSeed, + FindChannel: s.findChannel, DefaultRoutingPolicy: cc.RoutingPolicy, DefaultMinHtlcIn: cc.MinHtlcIn, NumRequiredConfs: func(chanAmt btcutil.Amount, @@ -2879,6 +2864,26 @@ func (s *server) createNewHiddenService() error { return nil } +// findChannel finds a channel given a public key and ChannelID. It is an +// optimization that is quicker than seeking for a channel given only the +// ChannelID. +func (s *server) findChannel(node *btcec.PublicKey, chanID lnwire.ChannelID) ( + *channeldb.OpenChannel, error) { + + nodeChans, err := s.chanStateDB.FetchOpenChannels(node) + if err != nil { + return nil, err + } + + for _, channel := range nodeChans { + if chanID.IsChanPoint(&channel.FundingOutpoint) { + return channel, nil + } + } + + return nil, fmt.Errorf("unable to find channel") +} + // genNodeAnnouncement generates and returns the current fully signed node // announcement. If refresh is true, then the time stamp of the announcement // will be updated in order to ensure it propagates through the network.