Merge pull request #4872 from Roasbeef/fix-tweakless-downgrade

peer: ensure consistent local+global feature bits when downgrading
This commit is contained in:
Johan T. Halseth 2020-12-18 09:53:45 +01:00 committed by GitHub
commit cc0321d188
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 2 deletions

@ -2775,6 +2775,7 @@ func (p *Brontide) RemoteFeatures() *lnwire.FeatureVector {
// our currently supported local and global features. // our currently supported local and global features.
func (p *Brontide) sendInitMsg(legacyChan bool) error { func (p *Brontide) sendInitMsg(legacyChan bool) error {
features := p.cfg.Features.Clone() features := p.cfg.Features.Clone()
legacyFeatures := p.cfg.LegacyFeatures.Clone()
// If we have a legacy channel open with a peer, we downgrade static // 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 // remote required to optional in case the peer does not understand the
@ -2786,12 +2787,18 @@ func (p *Brontide) sendInitMsg(legacyChan bool) error {
"downgrading static remote required feature bit to "+ "downgrading static remote required feature bit to "+
"optional", p.PubKey()) "optional", p.PubKey())
// Unset and set in both the local and global features to
// ensure both sets are consistent and merge able by old and
// new nodes.
features.Unset(lnwire.StaticRemoteKeyRequired) features.Unset(lnwire.StaticRemoteKeyRequired)
legacyFeatures.Unset(lnwire.StaticRemoteKeyRequired)
features.Set(lnwire.StaticRemoteKeyOptional) features.Set(lnwire.StaticRemoteKeyOptional)
legacyFeatures.Set(lnwire.StaticRemoteKeyOptional)
} }
msg := lnwire.NewInitMessage( msg := lnwire.NewInitMessage(
p.cfg.LegacyFeatures.RawFeatureVector, legacyFeatures.RawFeatureVector,
features.RawFeatureVector, features.RawFeatureVector,
) )

@ -875,6 +875,11 @@ func TestStaticRemoteDowngrade(t *testing.T) {
) )
legacy = lnwire.NewFeatureVector(rawLegacy, nil) legacy = lnwire.NewFeatureVector(rawLegacy, nil)
legacyCombinedOptional = lnwire.NewRawFeatureVector(
lnwire.UpfrontShutdownScriptOptional,
lnwire.StaticRemoteKeyOptional,
)
rawFeatureOptional = lnwire.NewRawFeatureVector( rawFeatureOptional = lnwire.NewRawFeatureVector(
lnwire.StaticRemoteKeyOptional, lnwire.StaticRemoteKeyOptional,
) )
@ -925,12 +930,17 @@ func TestStaticRemoteDowngrade(t *testing.T) {
Features: rawFeatureRequired, Features: rawFeatureRequired,
}, },
}, },
// In this case we need to flip our required bit to optional,
// this should also propagate to the legacy set of feature bits
// so we have proper consistency: a bit isn't set to optional
// in one field and required in the other.
{ {
name: "legacy channel, static required", name: "legacy channel, static required",
legacy: true, legacy: true,
features: featureRequired, features: featureRequired,
expectedInit: &lnwire.Init{ expectedInit: &lnwire.Init{
GlobalFeatures: rawLegacy, GlobalFeatures: legacyCombinedOptional,
Features: rawFeatureOptional, Features: rawFeatureOptional,
}, },
}, },