You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
3.9 KiB
137 lines
3.9 KiB
package feature |
|
|
|
import ( |
|
"fmt" |
|
|
|
"github.com/lightningnetwork/lnd/lnwire" |
|
) |
|
|
|
// Config houses any runtime modifications to the default set descriptors. For |
|
// our purposes, this typically means disabling certain features to test legacy |
|
// protocol interoperability or functionality. |
|
type Config struct { |
|
// NoTLVOnion unsets any optional or required TLVOnionPaylod bits from |
|
// all feature sets. |
|
NoTLVOnion bool |
|
|
|
// 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 |
|
|
|
// NoWumbo unsets any bits signalling support for wumbo channels. |
|
NoWumbo bool |
|
} |
|
|
|
// Manager is responsible for generating feature vectors for different requested |
|
// feature sets. |
|
type Manager struct { |
|
// fsets is a static map of feature set to raw feature vectors. Requests |
|
// are fulfilled by cloning these interal feature vectors. |
|
fsets map[Set]*lnwire.RawFeatureVector |
|
} |
|
|
|
// NewManager creates a new feature Manager, applying any custom modifications |
|
// to its feature sets before returning. |
|
func NewManager(cfg Config) (*Manager, error) { |
|
return newManager(cfg, defaultSetDesc) |
|
} |
|
|
|
// newManager creates a new feature Manager, applying any custom modifications |
|
// to its feature sets before returning. This method accepts the setDesc as its |
|
// own parameter so that it can be unit tested. |
|
func newManager(cfg Config, desc setDesc) (*Manager, error) { |
|
// First build the default feature vector for all known sets. |
|
fsets := make(map[Set]*lnwire.RawFeatureVector) |
|
for bit, sets := range desc { |
|
for set := range sets { |
|
// Fetch the feature vector for this set, allocating a |
|
// new one if it doesn't exist. |
|
fv, ok := fsets[set] |
|
if !ok { |
|
fv = lnwire.NewRawFeatureVector() |
|
} |
|
|
|
// Set the configured bit on the feature vector, |
|
// ensuring that we don't set two feature bits for the |
|
// same pair. |
|
err := fv.SafeSet(bit) |
|
if err != nil { |
|
return nil, fmt.Errorf("unable to set "+ |
|
"%v in %v: %v", bit, set, err) |
|
} |
|
|
|
// Write the updated feature vector under its set. |
|
fsets[set] = fv |
|
} |
|
} |
|
|
|
// Now, remove any features as directed by the config. |
|
for set, raw := range fsets { |
|
if cfg.NoTLVOnion { |
|
raw.Unset(lnwire.TLVOnionPayloadOptional) |
|
raw.Unset(lnwire.TLVOnionPayloadRequired) |
|
raw.Unset(lnwire.PaymentAddrOptional) |
|
raw.Unset(lnwire.PaymentAddrRequired) |
|
raw.Unset(lnwire.MPPOptional) |
|
raw.Unset(lnwire.MPPRequired) |
|
raw.Unset(lnwire.AMPOptional) |
|
raw.Unset(lnwire.AMPRequired) |
|
} |
|
if cfg.NoStaticRemoteKey { |
|
raw.Unset(lnwire.StaticRemoteKeyOptional) |
|
raw.Unset(lnwire.StaticRemoteKeyRequired) |
|
} |
|
if cfg.NoAnchors { |
|
raw.Unset(lnwire.AnchorsZeroFeeHtlcTxOptional) |
|
raw.Unset(lnwire.AnchorsZeroFeeHtlcTxRequired) |
|
} |
|
if cfg.NoWumbo { |
|
raw.Unset(lnwire.WumboChannelsOptional) |
|
raw.Unset(lnwire.WumboChannelsRequired) |
|
} |
|
|
|
// Ensure that all of our feature sets properly set any |
|
// dependent features. |
|
fv := lnwire.NewFeatureVector(raw, lnwire.Features) |
|
err := ValidateDeps(fv) |
|
if err != nil { |
|
return nil, fmt.Errorf("invalid feature set %v: %v", |
|
set, err) |
|
} |
|
} |
|
|
|
return &Manager{ |
|
fsets: fsets, |
|
}, nil |
|
} |
|
|
|
// GetRaw returns a raw feature vector for the passed set. If no set is known, |
|
// an empty raw feature vector is returned. |
|
func (m *Manager) GetRaw(set Set) *lnwire.RawFeatureVector { |
|
if fv, ok := m.fsets[set]; ok { |
|
return fv.Clone() |
|
} |
|
|
|
return lnwire.NewRawFeatureVector() |
|
} |
|
|
|
// Get returns a feature vector for the passed set. If no set is known, an empty |
|
// feature vector is returned. |
|
func (m *Manager) Get(set Set) *lnwire.FeatureVector { |
|
raw := m.GetRaw(set) |
|
return lnwire.NewFeatureVector(raw, lnwire.Features) |
|
} |
|
|
|
// ListSets returns a list of the feature sets that our node supports. |
|
func (m *Manager) ListSets() []Set { |
|
var sets []Set |
|
|
|
for set := range m.fsets { |
|
sets = append(sets, set) |
|
} |
|
|
|
return sets |
|
}
|
|
|