From 21126ab0f301cf6252c0608545e49c325ce8dded Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 6 Mar 2020 16:11:48 +0100 Subject: [PATCH] multi: optionally enable and signal anchor support Defaults to disabled. --- feature/default_sets.go | 4 ++++ feature/deps.go | 3 +++ feature/manager.go | 7 +++++++ lncfg/protocol_legacy_off.go | 12 +++++++++--- lncfg/protocol_legacy_on.go | 16 +++++++++++++--- lnwire/features.go | 12 ++++++++++++ server.go | 16 ++++++++++++---- 7 files changed, 60 insertions(+), 10 deletions(-) diff --git a/feature/default_sets.go b/feature/default_sets.go index 32807654..8054894e 100644 --- a/feature/default_sets.go +++ b/feature/default_sets.go @@ -43,4 +43,8 @@ var defaultSetDesc = setDesc{ SetNodeAnn: {}, // N SetInvoice: {}, // 9 }, + lnwire.AnchorsOptional: { + SetInit: {}, // I + SetNodeAnn: {}, // N + }, } diff --git a/feature/deps.go b/feature/deps.go index 343f3f60..c2b8f175 100644 --- a/feature/deps.go +++ b/feature/deps.go @@ -55,6 +55,9 @@ var deps = depDesc{ lnwire.MPPOptional: { lnwire.PaymentAddrOptional: {}, }, + lnwire.AnchorsOptional: { + lnwire.StaticRemoteKeyOptional: {}, + }, } // ValidateDeps asserts that a feature vector sets all features and their diff --git a/feature/manager.go b/feature/manager.go index 01c82123..159540c2 100644 --- a/feature/manager.go +++ b/feature/manager.go @@ -17,6 +17,9 @@ type Config struct { // NoStaticRemoteKey unsets any optional or required StaticRemoteKey // bits from all feature sets. NoStaticRemoteKey bool + + // NoAnchors unsets any bits signaling support for anchor outputs. + NoAnchors bool } // Manager is responsible for generating feature vectors for different requested @@ -76,6 +79,10 @@ func newManager(cfg Config, desc setDesc) (*Manager, error) { raw.Unset(lnwire.StaticRemoteKeyOptional) raw.Unset(lnwire.StaticRemoteKeyRequired) } + if cfg.NoAnchors { + raw.Unset(lnwire.AnchorsOptional) + raw.Unset(lnwire.AnchorsRequired) + } // Ensure that all of our feature sets properly set any // dependent features. diff --git a/lncfg/protocol_legacy_off.go b/lncfg/protocol_legacy_off.go index 0011bb7f..bd589c24 100644 --- a/lncfg/protocol_legacy_off.go +++ b/lncfg/protocol_legacy_off.go @@ -15,8 +15,14 @@ func (l *ProtocolOptions) LegacyOnion() bool { return false } -// LegacyCommitment returns true if the old commitment format should be used -// for new funded channels. -func (l *ProtocolOptions) LegacyCommitment() bool { +// NoStaticRemoteKey returns true if the old commitment format with a tweaked +// remote key should be used for new funded channels. +func (l *ProtocolOptions) NoStaticRemoteKey() bool { + return false +} + +// AnchorCommitments returns true if support for the the anchor commitment type +// should be signaled. +func (l *ProtocolOptions) AnchorCommitments() bool { return false } diff --git a/lncfg/protocol_legacy_on.go b/lncfg/protocol_legacy_on.go index e091c6a6..9be0d1d6 100644 --- a/lncfg/protocol_legacy_on.go +++ b/lncfg/protocol_legacy_on.go @@ -16,6 +16,10 @@ type ProtocolOptions struct { // remote party's output in the commitment. If set to true, then we // won't signal StaticRemoteKeyOptional. CommitmentTweak bool `long:"committweak" description:"force node to not advertise the new commitment format"` + + // Anchors should be set if we want to support opening or accepting + // channels having the anchor commitment type. + Anchors bool `long:"anchors" description:"EXPERIMENTAL: enable experimental support for anchor commitments. Won't work with watchtowers or static channel backups"` } // LegacyOnion returns true if the old legacy onion format should be used when @@ -25,8 +29,14 @@ func (l *ProtocolOptions) LegacyOnion() bool { return l.LegacyOnionFormat } -// LegacyCommitment returns true if the old commitment format should be used -// for new funded channels. -func (l *ProtocolOptions) LegacyCommitment() bool { +// NoStaticRemoteKey returns true if the old commitment format with a tweaked +// remote key should be used for new funded channels. +func (l *ProtocolOptions) NoStaticRemoteKey() bool { return l.CommitmentTweak } + +// AnchorCommitments returns true if support for the the anchor commitment type +// should be signaled. +func (l *ProtocolOptions) AnchorCommitments() bool { + return l.Anchors +} diff --git a/lnwire/features.go b/lnwire/features.go index db170f6d..4e5899c2 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -101,6 +101,16 @@ const ( // HTLC. MPPOptional FeatureBit = 17 + // AnchorsRequired is a required feature bit that signals that the node + // requires channels to be made using commitments having anchor + // outputs. + AnchorsRequired FeatureBit = 1336 + + // AnchorsRequired is an optional feature bit that signals that the + // node supports channels to be made using commitments having anchor + // outputs. + AnchorsOptional FeatureBit = 1337 + // maxAllowedSize is a maximum allowed size of feature vector. // // NOTE: Within the protocol, the maximum allowed message size is 65535 @@ -138,6 +148,8 @@ var Features = map[FeatureBit]string{ PaymentAddrRequired: "payment-addr", MPPOptional: "multi-path-payments", MPPRequired: "multi-path-payments", + AnchorsRequired: "anchor-commitments", + AnchorsOptional: "anchor-commitments", } // RawFeatureVector represents a set of feature bits as defined in BOLT-09. A diff --git a/server.go b/server.go index a4bff136..103c9aad 100644 --- a/server.go +++ b/server.go @@ -340,12 +340,19 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, globalFeatures.Set(lnwire.TLVOnionPayloadOptional) } - // Similarly, we default to the new modern commitment format unless the - // legacy commitment config is set to true. - if !cfg.ProtocolOptions.LegacyCommitment() { + // Similarly, we default to supporting the new modern commitment format + // where the remote key is static unless the protocol config is set to + // keep using the older format. + if !cfg.ProtocolOptions.NoStaticRemoteKey() { globalFeatures.Set(lnwire.StaticRemoteKeyOptional) } + // We only signal that we support the experimental anchor commitments + // if explicitly enabled in the config. + if cfg.ProtocolOptions.AnchorCommitments() { + globalFeatures.Set(lnwire.AnchorsOptional) + } + var serializedPubKey [33]byte copy(serializedPubKey[:], privKey.PubKey().SerializeCompressed()) @@ -376,7 +383,8 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, featureMgr, err := feature.NewManager(feature.Config{ NoTLVOnion: cfg.ProtocolOptions.LegacyOnion(), - NoStaticRemoteKey: cfg.ProtocolOptions.LegacyCommitment(), + NoStaticRemoteKey: cfg.ProtocolOptions.NoStaticRemoteKey(), + NoAnchors: !cfg.ProtocolOptions.AnchorCommitments(), }) if err != nil { return nil, err