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.
This commit is contained in:
Johan T. Halseth 2020-12-09 16:13:50 +02:00 committed by carla
parent f98a3c9dac
commit 0532c21e33
No known key found for this signature in database
GPG Key ID: 4CA7FE54A6213C91

@ -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)