github.com/decred/dcrlnd@v0.7.6/feature/manager.go (about) 1 package feature 2 3 import ( 4 "fmt" 5 6 "github.com/decred/dcrlnd/lnwire" 7 ) 8 9 // Config houses any runtime modifications to the default set descriptors. For 10 // our purposes, this typically means disabling certain features to test legacy 11 // protocol interoperability or functionality. 12 type Config struct { 13 // NoTLVOnion unsets any optional or required TLVOnionPaylod bits from 14 // all feature sets. 15 NoTLVOnion bool 16 17 // NoStaticRemoteKey unsets any optional or required StaticRemoteKey 18 // bits from all feature sets. 19 NoStaticRemoteKey bool 20 21 // NoAnchors unsets any bits signaling support for anchor outputs. 22 NoAnchors bool 23 24 // NoWumbo unsets any bits signalling support for wumbo channels. 25 NoWumbo bool 26 27 // NoScriptEnforcementLease unsets any bits signaling support for script 28 // enforced leases. 29 NoScriptEnforcementLease bool 30 } 31 32 // Manager is responsible for generating feature vectors for different requested 33 // feature sets. 34 type Manager struct { 35 // fsets is a static map of feature set to raw feature vectors. Requests 36 // are fulfilled by cloning these interal feature vectors. 37 fsets map[Set]*lnwire.RawFeatureVector 38 } 39 40 // NewManager creates a new feature Manager, applying any custom modifications 41 // to its feature sets before returning. 42 func NewManager(cfg Config) (*Manager, error) { 43 return newManager(cfg, defaultSetDesc) 44 } 45 46 // newManager creates a new feature Manager, applying any custom modifications 47 // to its feature sets before returning. This method accepts the setDesc as its 48 // own parameter so that it can be unit tested. 49 func newManager(cfg Config, desc setDesc) (*Manager, error) { 50 // First build the default feature vector for all known sets. 51 fsets := make(map[Set]*lnwire.RawFeatureVector) 52 for bit, sets := range desc { 53 for set := range sets { 54 // Fetch the feature vector for this set, allocating a 55 // new one if it doesn't exist. 56 fv, ok := fsets[set] 57 if !ok { 58 fv = lnwire.NewRawFeatureVector() 59 } 60 61 // Set the configured bit on the feature vector, 62 // ensuring that we don't set two feature bits for the 63 // same pair. 64 err := fv.SafeSet(bit) 65 if err != nil { 66 return nil, fmt.Errorf("unable to set "+ 67 "%v in %v: %v", bit, set, err) 68 } 69 70 // Write the updated feature vector under its set. 71 fsets[set] = fv 72 } 73 } 74 75 // Now, remove any features as directed by the config. 76 for set, raw := range fsets { 77 if cfg.NoTLVOnion { 78 raw.Unset(lnwire.TLVOnionPayloadOptional) 79 raw.Unset(lnwire.TLVOnionPayloadRequired) 80 raw.Unset(lnwire.PaymentAddrOptional) 81 raw.Unset(lnwire.PaymentAddrRequired) 82 raw.Unset(lnwire.MPPOptional) 83 raw.Unset(lnwire.MPPRequired) 84 raw.Unset(lnwire.AMPOptional) 85 raw.Unset(lnwire.AMPRequired) 86 } 87 if cfg.NoStaticRemoteKey { 88 raw.Unset(lnwire.StaticRemoteKeyOptional) 89 raw.Unset(lnwire.StaticRemoteKeyRequired) 90 } 91 if cfg.NoAnchors { 92 raw.Unset(lnwire.AnchorsZeroFeeHtlcTxOptional) 93 raw.Unset(lnwire.AnchorsZeroFeeHtlcTxRequired) 94 95 // If anchors are disabled, then we also need to 96 // disable all other features that depend on it as 97 // well, as otherwise we may create an invalid feature 98 // bit set. 99 for bit, depFeatures := range deps { 100 for depFeature := range depFeatures { 101 switch { 102 case depFeature == lnwire.AnchorsZeroFeeHtlcTxRequired: 103 fallthrough 104 case depFeature == lnwire.AnchorsZeroFeeHtlcTxOptional: 105 raw.Unset(bit) 106 } 107 } 108 } 109 } 110 if cfg.NoWumbo { 111 raw.Unset(lnwire.WumboChannelsOptional) 112 raw.Unset(lnwire.WumboChannelsRequired) 113 } 114 if cfg.NoScriptEnforcementLease { 115 raw.Unset(lnwire.ScriptEnforcedLeaseOptional) 116 raw.Unset(lnwire.ScriptEnforcedLeaseRequired) 117 } 118 119 // Ensure that all of our feature sets properly set any 120 // dependent features. 121 fv := lnwire.NewFeatureVector(raw, lnwire.Features) 122 err := ValidateDeps(fv) 123 if err != nil { 124 return nil, fmt.Errorf("invalid feature set %v: %v", 125 set, err) 126 } 127 } 128 129 return &Manager{ 130 fsets: fsets, 131 }, nil 132 } 133 134 // GetRaw returns a raw feature vector for the passed set. If no set is known, 135 // an empty raw feature vector is returned. 136 func (m *Manager) GetRaw(set Set) *lnwire.RawFeatureVector { 137 if fv, ok := m.fsets[set]; ok { 138 return fv.Clone() 139 } 140 141 return lnwire.NewRawFeatureVector() 142 } 143 144 // Get returns a feature vector for the passed set. If no set is known, an empty 145 // feature vector is returned. 146 func (m *Manager) Get(set Set) *lnwire.FeatureVector { 147 raw := m.GetRaw(set) 148 return lnwire.NewFeatureVector(raw, lnwire.Features) 149 } 150 151 // ListSets returns a list of the feature sets that our node supports. 152 func (m *Manager) ListSets() []Set { 153 var sets []Set 154 155 for set := range m.fsets { 156 sets = append(sets, set) 157 } 158 159 return sets 160 }