From 0532c21e3319716e4ebad5814607248bf22c3ee8 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Wed, 9 Dec 2020 16:13:50 +0200 Subject: [PATCH] peer: remove static remote required for peers with legacy channels This commit unsets option static remote key required for peers that we have existing legacy channels with. This ensures that we can still connect to peers that do not recognize this feature bit that we have existing channels with. --- peer/brontide.go | 66 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/peer/brontide.go b/peer/brontide.go index 578d7133..c0669cdf 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -446,9 +446,36 @@ func (p *Brontide) Start() error { peerLog.Tracef("Peer %v starting", p) + // Fetch and then load all the active channels we have with this remote + // peer from the database. + activeChans, err := p.cfg.ChannelDB.FetchOpenChannels( + p.cfg.Addr.IdentityKey, + ) + if err != nil { + peerLog.Errorf("Unable to fetch active chans "+ + "for peer %v: %v", p, err) + return err + } + + if len(activeChans) == 0 { + p.cfg.PrunePersistentPeerConnection(p.cfg.PubKeyBytes) + } + + // Quickly check if we have any existing legacy channels with this + // peer. + haveLegacyChan := false + for _, c := range activeChans { + if c.ChanType.IsTweakless() { + continue + } + + haveLegacyChan = true + break + } + // Exchange local and global features, the init message should be very // first between two nodes. - if err := p.sendInitMsg(); err != nil { + if err := p.sendInitMsg(haveLegacyChan); err != nil { return fmt.Errorf("unable to send init msg: %v", err) } @@ -496,19 +523,6 @@ func (p *Brontide) Start() error { "must be init message") } - // Fetch and then load all the active channels we have with this remote - // peer from the database. - activeChans, err := p.cfg.ChannelDB.FetchOpenChannels(p.cfg.Addr.IdentityKey) - if err != nil { - peerLog.Errorf("unable to fetch active chans "+ - "for peer %v: %v", p, err) - return err - } - - if len(activeChans) == 0 { - p.cfg.PrunePersistentPeerConnection(p.cfg.PubKeyBytes) - } - // Next, load all the active channels we have with this peer, // registering them with the switch and launching the necessary // goroutines required to operate them. @@ -2752,12 +2766,28 @@ func (p *Brontide) RemoteFeatures() *lnwire.FeatureVector { return p.remoteFeatures } -// sendInitMsg sends the Init message to the remote peer. This message contains our -// currently supported local and global features. -func (p *Brontide) sendInitMsg() error { +// sendInitMsg sends the Init message to the remote peer. This message contains +// our currently supported local and global features. +func (p *Brontide) sendInitMsg(legacyChan bool) error { + features := p.cfg.Features.Clone() + + // If we have a legacy channel open with a peer, we downgrade static + // remote required to optional in case the peer does not understand the + // required feature bit. If we do not do this, the peer will reject our + // connection because it does not understand a required feature bit, and + // our channel will be unusable. + if legacyChan && features.RequiresFeature(lnwire.StaticRemoteKeyRequired) { + peerLog.Infof("Legacy channel open with peer: %x, "+ + "downgrading static remote required feature bit to "+ + "optional", p.PubKey()) + + features.Unset(lnwire.StaticRemoteKeyRequired) + features.Set(lnwire.StaticRemoteKeyOptional) + } + msg := lnwire.NewInitMessage( p.cfg.LegacyFeatures.RawFeatureVector, - p.cfg.Features.RawFeatureVector, + features.RawFeatureVector, ) return p.writeMessage(msg)