mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-10-06 19:23:59 +02:00
feature: add new feature pkg to manage feature sets
This commit introduces a feature.Manager, which derives feature vectors for various contexts within the daemon. The sets can be described via a staticly compiled format, which makes any runtime adjustments to the feature sets when the manager is initialized.
This commit is contained in:
97
feature/manager.go
Normal file
97
feature/manager.go
Normal file
@@ -0,0 +1,97 @@
|
||||
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
|
||||
}
|
||||
|
||||
// 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 feeature 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 _, fv := range fsets {
|
||||
if cfg.NoTLVOnion {
|
||||
fv.Unset(lnwire.TLVOnionPayloadOptional)
|
||||
fv.Unset(lnwire.TLVOnionPayloadRequired)
|
||||
}
|
||||
if cfg.NoStaticRemoteKey {
|
||||
fv.Unset(lnwire.StaticRemoteKeyOptional)
|
||||
fv.Unset(lnwire.StaticRemoteKeyRequired)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
Reference in New Issue
Block a user