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)