• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 15561477203

10 Jun 2025 01:54PM UTC coverage: 58.351% (-10.1%) from 68.487%
15561477203

Pull #9356

github

web-flow
Merge 6440b25db into c6d6d4c0b
Pull Request #9356: lnrpc: add incoming/outgoing channel ids filter to forwarding history request

33 of 36 new or added lines in 2 files covered. (91.67%)

28366 existing lines in 455 files now uncovered.

97715 of 167461 relevant lines covered (58.35%)

1.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.33
/lnwire/features.go
1
package lnwire
2

3
import (
4
        "encoding/binary"
5
        "errors"
6
        "fmt"
7
        "io"
8

9
        "github.com/lightningnetwork/lnd/tlv"
10
)
11

12
var (
13
        // ErrFeaturePairExists signals an error in feature vector construction
14
        // where the opposing bit in a feature pair has already been set.
15
        ErrFeaturePairExists = errors.New("feature pair exists")
16

17
        // ErrFeatureStandard is returned when attempts to modify LND's known
18
        // set of features are made.
19
        ErrFeatureStandard = errors.New("feature is used in standard " +
20
                "protocol set")
21

22
        // ErrFeatureBitMaximum is returned when a feature bit exceeds the
23
        // maximum allowable value.
24
        ErrFeatureBitMaximum = errors.New("feature bit exceeds allowed maximum")
25
)
26

27
// FeatureBit represents a feature that can be enabled in either a local or
28
// global feature vector at a specific bit position. Feature bits follow the
29
// "it's OK to be odd" rule, where features at even bit positions must be known
30
// to a node receiving them from a peer while odd bits do not. In accordance,
31
// feature bits are usually assigned in pairs, first being assigned an odd bit
32
// position which may later be changed to the preceding even position once
33
// knowledge of the feature becomes required on the network.
34
type FeatureBit uint16
35

36
const (
37
        // DataLossProtectRequired is a feature bit that indicates that a peer
38
        // *requires* the other party know about the data-loss-protect optional
39
        // feature. If the remote peer does not know of such a feature, then
40
        // the sending peer SHOULD disconnect them. The data-loss-protect
41
        // feature allows a peer that's lost partial data to recover their
42
        // settled funds of the latest commitment state.
43
        DataLossProtectRequired FeatureBit = 0
44

45
        // DataLossProtectOptional is an optional feature bit that indicates
46
        // that the sending peer knows of this new feature and can activate it
47
        // it. The data-loss-protect feature allows a peer that's lost partial
48
        // data to recover their settled funds of the latest commitment state.
49
        DataLossProtectOptional FeatureBit = 1
50

51
        // InitialRoutingSync is a local feature bit meaning that the receiving
52
        // node should send a complete dump of routing information when a new
53
        // connection is established.
54
        InitialRoutingSync FeatureBit = 3
55

56
        // UpfrontShutdownScriptRequired is a feature bit which indicates that a
57
        // peer *requires* that the remote peer accept an upfront shutdown script to
58
        // which payout is enforced on cooperative closes.
59
        UpfrontShutdownScriptRequired FeatureBit = 4
60

61
        // UpfrontShutdownScriptOptional is an optional feature bit which indicates
62
        // that the peer will accept an upfront shutdown script to which payout is
63
        // enforced on cooperative closes.
64
        UpfrontShutdownScriptOptional FeatureBit = 5
65

66
        // GossipQueriesRequired is a feature bit that indicates that the
67
        // receiving peer MUST know of the set of features that allows nodes to
68
        // more efficiently query the network view of peers on the network for
69
        // reconciliation purposes.
70
        GossipQueriesRequired FeatureBit = 6
71

72
        // GossipQueriesOptional is an optional feature bit that signals that
73
        // the setting peer knows of the set of features that allows more
74
        // efficient network view reconciliation.
75
        GossipQueriesOptional FeatureBit = 7
76

77
        // TLVOnionPayloadRequired is a feature bit that indicates a node is
78
        // able to decode the new TLV information included in the onion packet.
79
        TLVOnionPayloadRequired FeatureBit = 8
80

81
        // TLVOnionPayloadOptional is an optional feature bit that indicates a
82
        // node is able to decode the new TLV information included in the onion
83
        // packet.
84
        TLVOnionPayloadOptional FeatureBit = 9
85

86
        // StaticRemoteKeyRequired is a required feature bit that signals that
87
        // within one's commitment transaction, the key used for the remote
88
        // party's non-delay output should not be tweaked.
89
        StaticRemoteKeyRequired FeatureBit = 12
90

91
        // StaticRemoteKeyOptional is an optional feature bit that signals that
92
        // within one's commitment transaction, the key used for the remote
93
        // party's non-delay output should not be tweaked.
94
        StaticRemoteKeyOptional FeatureBit = 13
95

96
        // PaymentAddrRequired is a required feature bit that signals that a
97
        // node requires payment addresses, which are used to mitigate probing
98
        // attacks on the receiver of a payment.
99
        PaymentAddrRequired FeatureBit = 14
100

101
        // PaymentAddrOptional is an optional feature bit that signals that a
102
        // node supports payment addresses, which are used to mitigate probing
103
        // attacks on the receiver of a payment.
104
        PaymentAddrOptional FeatureBit = 15
105

106
        // MPPRequired is a required feature bit that signals that the receiver
107
        // of a payment requires settlement of an invoice with more than one
108
        // HTLC.
109
        MPPRequired FeatureBit = 16
110

111
        // MPPOptional is an optional feature bit that signals that the receiver
112
        // of a payment supports settlement of an invoice with more than one
113
        // HTLC.
114
        MPPOptional FeatureBit = 17
115

116
        // WumboChannelsRequired is a required feature bit that signals that a
117
        // node is willing to accept channels larger than 2^24 satoshis.
118
        WumboChannelsRequired FeatureBit = 18
119

120
        // WumboChannelsOptional is an optional feature bit that signals that a
121
        // node is willing to accept channels larger than 2^24 satoshis.
122
        WumboChannelsOptional FeatureBit = 19
123

124
        // AnchorsRequired is a required feature bit that signals that the node
125
        // requires channels to be made using commitments having anchor
126
        // outputs.
127
        AnchorsRequired FeatureBit = 20
128

129
        // AnchorsOptional is an optional feature bit that signals that the
130
        // node supports channels to be made using commitments having anchor
131
        // outputs.
132
        AnchorsOptional FeatureBit = 21
133

134
        // AnchorsZeroFeeHtlcTxRequired is a required feature bit that signals
135
        // that the node requires channels having zero-fee second-level HTLC
136
        // transactions, which also imply anchor commitments.
137
        AnchorsZeroFeeHtlcTxRequired FeatureBit = 22
138

139
        // AnchorsZeroFeeHtlcTxOptional is an optional feature bit that signals
140
        // that the node supports channels having zero-fee second-level HTLC
141
        // transactions, which also imply anchor commitments.
142
        AnchorsZeroFeeHtlcTxOptional FeatureBit = 23
143

144
        // RouteBlindingRequired is a required feature bit that signals that
145
        // the node supports blinded payments.
146
        RouteBlindingRequired FeatureBit = 24
147

148
        // RouteBlindingOptional is an optional feature bit that signals that
149
        // the node supports blinded payments.
150
        RouteBlindingOptional FeatureBit = 25
151

152
        // ShutdownAnySegwitRequired is an required feature bit that signals
153
        // that the sender is able to properly handle/parse segwit witness
154
        // programs up to version 16. This enables utilization of Taproot
155
        // addresses for cooperative closure addresses.
156
        ShutdownAnySegwitRequired FeatureBit = 26
157

158
        // ShutdownAnySegwitOptional is an optional feature bit that signals
159
        // that the sender is able to properly handle/parse segwit witness
160
        // programs up to version 16. This enables utilization of Taproot
161
        // addresses for cooperative closure addresses.
162
        ShutdownAnySegwitOptional FeatureBit = 27
163

164
        // AMPRequired is a required feature bit that signals that the receiver
165
        // of a payment supports accepts spontaneous payments, i.e.
166
        // sender-generated preimages according to BOLT XX.
167
        AMPRequired FeatureBit = 30
168

169
        // AMPOptional is an optional feature bit that signals that the receiver
170
        // of a payment supports accepts spontaneous payments, i.e.
171
        // sender-generated preimages according to BOLT XX.
172
        AMPOptional FeatureBit = 31
173

174
        // QuiescenceRequired is a required feature bit that denotes that a
175
        // connection established with this node must support the quiescence
176
        // protocol if it wants to have a channel relationship.
177
        QuiescenceRequired FeatureBit = 34
178

179
        // QuiescenceOptional is an optional feature bit that denotes that a
180
        // connection established with this node is permitted to use the
181
        // quiescence protocol.
182
        QuiescenceOptional FeatureBit = 35
183

184
        // ExplicitChannelTypeRequired is a required bit that denotes that a
185
        // connection established with this node is to use explicit channel
186
        // commitment types for negotiation instead of the existing implicit
187
        // negotiation methods. With this bit, there is no longer a "default"
188
        // implicit channel commitment type, allowing a connection to
189
        // open/maintain types of several channels over its lifetime.
190
        ExplicitChannelTypeRequired = 44
191

192
        // ExplicitChannelTypeOptional is an optional bit that denotes that a
193
        // connection established with this node is to use explicit channel
194
        // commitment types for negotiation instead of the existing implicit
195
        // negotiation methods. With this bit, there is no longer a "default"
196
        // implicit channel commitment type, allowing a connection to
197
        // TODO: Decide on actual feature bit value.
198
        ExplicitChannelTypeOptional = 45
199

200
        // ScidAliasRequired is a required feature bit that signals that the
201
        // node requires understanding of ShortChannelID aliases in the TLV
202
        // segment of the channel_ready message.
203
        ScidAliasRequired FeatureBit = 46
204

205
        // ScidAliasOptional is an optional feature bit that signals that the
206
        // node understands ShortChannelID aliases in the TLV segment of the
207
        // channel_ready message.
208
        ScidAliasOptional FeatureBit = 47
209

210
        // PaymentMetadataRequired is a required bit that denotes that if an
211
        // invoice contains metadata, it must be passed along with the payment
212
        // htlc(s).
213
        PaymentMetadataRequired = 48
214

215
        // PaymentMetadataOptional is an optional bit that denotes that if an
216
        // invoice contains metadata, it may be passed along with the payment
217
        // htlc(s).
218
        PaymentMetadataOptional = 49
219

220
        // ZeroConfRequired is a required feature bit that signals that the
221
        // node requires understanding of the zero-conf channel_type.
222
        ZeroConfRequired FeatureBit = 50
223

224
        // ZeroConfOptional is an optional feature bit that signals that the
225
        // node understands the zero-conf channel type.
226
        ZeroConfOptional FeatureBit = 51
227

228
        // KeysendRequired is a required bit that indicates that the node is
229
        // able and willing to accept keysend payments.
230
        KeysendRequired = 54
231

232
        // KeysendOptional is an optional bit that indicates that the node is
233
        // able and willing to accept keysend payments.
234
        KeysendOptional = 55
235

236
        // RbfCoopCloseRequired is a required feature bit that signals that
237
        // the new RBF-based co-op close protocol is supported.
238
        RbfCoopCloseRequired = 60
239

240
        // RbfCoopCloseOptional is an optional feature bit that signals that the
241
        // new RBF-based co-op close protocol is supported.
242
        RbfCoopCloseOptional = 61
243

244
        // RbfCoopCloseRequiredStaging is a required feature bit that signals
245
        // that the new RBF-based co-op close protocol is supported.
246
        RbfCoopCloseRequiredStaging = 160
247

248
        // RbfCoopCloseOptionalStaging is an optional feature bit that signals
249
        // that the new RBF-based co-op close protocol is supported.
250
        RbfCoopCloseOptionalStaging = 161
251

252
        // ScriptEnforcedLeaseRequired is a required feature bit that signals
253
        // that the node requires channels having zero-fee second-level HTLC
254
        // transactions, which also imply anchor commitments, along with an
255
        // additional CLTV constraint of a channel lease's expiration height
256
        // applied to all outputs that pay directly to the channel initiator.
257
        //
258
        // TODO: Decide on actual feature bit value.
259
        ScriptEnforcedLeaseRequired FeatureBit = 2022
260

261
        // ScriptEnforcedLeaseOptional is an optional feature bit that signals
262
        // that the node requires channels having zero-fee second-level HTLC
263
        // transactions, which also imply anchor commitments, along with an
264
        // additional CLTV constraint of a channel lease's expiration height
265
        // applied to all outputs that pay directly to the channel initiator.
266
        //
267
        // TODO: Decide on actual feature bit value.
268
        ScriptEnforcedLeaseOptional FeatureBit = 2023
269

270
        // SimpleTaprootChannelsRequiredFinal is a required bit that indicates
271
        // the node is able to create taproot-native channels. This is the
272
        // final feature bit to be used once the channel type is finalized.
273
        SimpleTaprootChannelsRequiredFinal = 80
274

275
        // SimpleTaprootChannelsOptionalFinal is an optional bit that indicates
276
        // the node is able to create taproot-native channels. This is the
277
        // final feature bit to be used once the channel type is finalized.
278
        SimpleTaprootChannelsOptionalFinal = 81
279

280
        // SimpleTaprootChannelsRequiredStaging is a required bit that indicates
281
        // the node is able to create taproot-native channels. This is a
282
        // feature bit used in the wild while the channel type is still being
283
        // finalized.
284
        SimpleTaprootChannelsRequiredStaging = 180
285

286
        // SimpleTaprootChannelsOptionalStaging is an optional bit that
287
        // indicates the node is able to create taproot-native channels. This
288
        // is a feature bit used in the wild while the channel type is still
289
        // being finalized.
290
        SimpleTaprootChannelsOptionalStaging = 181
291

292
        // ExperimentalEndorsementRequired is a required feature bit that
293
        // indicates that the node will relay experimental endorsement signals.
294
        ExperimentalEndorsementRequired FeatureBit = 260
295

296
        // ExperimentalEndorsementOptional is an optional feature bit that
297
        // indicates that the node will relay experimental endorsement signals.
298
        ExperimentalEndorsementOptional FeatureBit = 261
299

300
        // Bolt11BlindedPathsRequired is a required feature bit that indicates
301
        // that the node is able to understand the blinded path tagged field in
302
        // a BOLT 11 invoice.
303
        Bolt11BlindedPathsRequired = 262
304

305
        // Bolt11BlindedPathsOptional is an optional feature bit that indicates
306
        // that the node is able to understand the blinded path tagged field in
307
        // a BOLT 11 invoice.
308
        Bolt11BlindedPathsOptional = 263
309

310
        // SimpleTaprootOverlayChansRequired is a required bit that indicates
311
        // support for the special custom taproot overlay channel.
312
        SimpleTaprootOverlayChansOptional = 2025
313

314
        // SimpleTaprootOverlayChansRequired is a required bit that indicates
315
        // support for the special custom taproot overlay channel.
316
        SimpleTaprootOverlayChansRequired = 2026
317

318
        // MaxBolt11Feature is the maximum feature bit value allowed in bolt 11
319
        // invoices.
320
        //
321
        // The base 32 encoded tagged fields in invoices are limited to 10 bits
322
        // to express the length of the field's data.
323
        //nolint:ll
324
        // See: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md#tagged-fields
325
        //
326
        // With a maximum length field of 1023 (2^10 -1) and 5 bit encoding,
327
        // the highest feature bit that can be expressed is:
328
        // 1023 * 5 - 1 = 5114.
329
        MaxBolt11Feature = 5114
330
)
331

332
// IsRequired returns true if the feature bit is even, and false otherwise.
333
func (b FeatureBit) IsRequired() bool {
3✔
334
        return b&0x01 == 0x00
3✔
335
}
3✔
336

337
// Features is a mapping of known feature bits to a descriptive name. All known
338
// feature bits must be assigned a name in this mapping, and feature bit pairs
339
// must be assigned together for correct behavior.
340
var Features = map[FeatureBit]string{
341
        DataLossProtectRequired:              "data-loss-protect",
342
        DataLossProtectOptional:              "data-loss-protect",
343
        InitialRoutingSync:                   "initial-routing-sync",
344
        UpfrontShutdownScriptRequired:        "upfront-shutdown-script",
345
        UpfrontShutdownScriptOptional:        "upfront-shutdown-script",
346
        GossipQueriesRequired:                "gossip-queries",
347
        GossipQueriesOptional:                "gossip-queries",
348
        TLVOnionPayloadRequired:              "tlv-onion",
349
        TLVOnionPayloadOptional:              "tlv-onion",
350
        StaticRemoteKeyOptional:              "static-remote-key",
351
        StaticRemoteKeyRequired:              "static-remote-key",
352
        PaymentAddrOptional:                  "payment-addr",
353
        PaymentAddrRequired:                  "payment-addr",
354
        MPPOptional:                          "multi-path-payments",
355
        MPPRequired:                          "multi-path-payments",
356
        AnchorsRequired:                      "anchor-commitments",
357
        AnchorsOptional:                      "anchor-commitments",
358
        AnchorsZeroFeeHtlcTxRequired:         "anchors-zero-fee-htlc-tx",
359
        AnchorsZeroFeeHtlcTxOptional:         "anchors-zero-fee-htlc-tx",
360
        WumboChannelsRequired:                "wumbo-channels",
361
        WumboChannelsOptional:                "wumbo-channels",
362
        AMPRequired:                          "amp",
363
        AMPOptional:                          "amp",
364
        QuiescenceRequired:                   "quiescence",
365
        QuiescenceOptional:                   "quiescence",
366
        PaymentMetadataOptional:              "payment-metadata",
367
        PaymentMetadataRequired:              "payment-metadata",
368
        ExplicitChannelTypeOptional:          "explicit-commitment-type",
369
        ExplicitChannelTypeRequired:          "explicit-commitment-type",
370
        KeysendOptional:                      "keysend",
371
        KeysendRequired:                      "keysend",
372
        ScriptEnforcedLeaseRequired:          "script-enforced-lease",
373
        ScriptEnforcedLeaseOptional:          "script-enforced-lease",
374
        ScidAliasRequired:                    "scid-alias",
375
        ScidAliasOptional:                    "scid-alias",
376
        ZeroConfRequired:                     "zero-conf",
377
        ZeroConfOptional:                     "zero-conf",
378
        RouteBlindingRequired:                "route-blinding",
379
        RouteBlindingOptional:                "route-blinding",
380
        ShutdownAnySegwitRequired:            "shutdown-any-segwit",
381
        ShutdownAnySegwitOptional:            "shutdown-any-segwit",
382
        SimpleTaprootChannelsRequiredFinal:   "simple-taproot-chans",
383
        SimpleTaprootChannelsOptionalFinal:   "simple-taproot-chans",
384
        SimpleTaprootChannelsRequiredStaging: "simple-taproot-chans-x",
385
        SimpleTaprootChannelsOptionalStaging: "simple-taproot-chans-x",
386
        SimpleTaprootOverlayChansOptional:    "taproot-overlay-chans",
387
        SimpleTaprootOverlayChansRequired:    "taproot-overlay-chans",
388
        ExperimentalEndorsementRequired:      "endorsement-x",
389
        ExperimentalEndorsementOptional:      "endorsement-x",
390
        Bolt11BlindedPathsOptional:           "bolt-11-blinded-paths",
391
        Bolt11BlindedPathsRequired:           "bolt-11-blinded-paths",
392
        RbfCoopCloseOptional:                 "rbf-coop-close",
393
        RbfCoopCloseRequired:                 "rbf-coop-close",
394
        RbfCoopCloseOptionalStaging:          "rbf-coop-close-x",
395
        RbfCoopCloseRequiredStaging:          "rbf-coop-close-x",
396
}
397

398
// RawFeatureVector represents a set of feature bits as defined in BOLT-09.  A
399
// RawFeatureVector itself just stores a set of bit flags but can be used to
400
// construct a FeatureVector which binds meaning to each bit. Feature vectors
401
// can be serialized and deserialized to/from a byte representation that is
402
// transmitted in Lightning network messages.
403
type RawFeatureVector struct {
404
        features map[FeatureBit]struct{}
405
}
406

407
// NewRawFeatureVector creates a feature vector with all of the feature bits
408
// given as arguments enabled.
409
func NewRawFeatureVector(bits ...FeatureBit) *RawFeatureVector {
3✔
410
        fv := &RawFeatureVector{features: make(map[FeatureBit]struct{})}
3✔
411
        for _, bit := range bits {
6✔
412
                fv.Set(bit)
3✔
413
        }
3✔
414
        return fv
3✔
415
}
416

417
// IsEmpty returns whether the feature vector contains any feature bits.
418
func (fv RawFeatureVector) IsEmpty() bool {
3✔
419
        return len(fv.features) == 0
3✔
420
}
3✔
421

422
// OnlyContains determines whether only the specified feature bits are found.
423
func (fv RawFeatureVector) OnlyContains(bits ...FeatureBit) bool {
3✔
424
        if len(bits) != len(fv.features) {
6✔
425
                return false
3✔
426
        }
3✔
427
        for _, bit := range bits {
6✔
428
                if !fv.IsSet(bit) {
6✔
429
                        return false
3✔
430
                }
3✔
431
        }
432
        return true
3✔
433
}
434

435
// Equals determines whether two features vectors contain exactly the same
436
// features.
437
func (fv RawFeatureVector) Equals(other *RawFeatureVector) bool {
3✔
438
        if len(fv.features) != len(other.features) {
3✔
UNCOV
439
                return false
×
UNCOV
440
        }
×
441
        for bit := range fv.features {
6✔
442
                if _, ok := other.features[bit]; !ok {
3✔
UNCOV
443
                        return false
×
UNCOV
444
                }
×
445
        }
446
        return true
3✔
447
}
448

449
// Merges sets all feature bits in other on the receiver's feature vector.
450
func (fv *RawFeatureVector) Merge(other *RawFeatureVector) error {
3✔
451
        for bit := range other.features {
6✔
452
                err := fv.SafeSet(bit)
3✔
453
                if err != nil {
3✔
454
                        return err
×
455
                }
×
456
        }
457
        return nil
3✔
458
}
459

460
// ValidateUpdate checks whether a feature vector can safely be updated to the
461
// new feature vector provided, checking that it does not alter any of the
462
// "standard" features that are defined by LND. The new feature vector should
463
// be inclusive of all features in the original vector that it still wants to
464
// advertise, setting and unsetting updates as desired. Features in the vector
465
// are also checked against a maximum inclusive value, as feature vectors in
466
// different contexts have different maximum values.
467
func (fv *RawFeatureVector) ValidateUpdate(other *RawFeatureVector,
468
        maximumValue FeatureBit) error {
3✔
469

3✔
470
        // Run through the new set of features and check that we're not adding
3✔
471
        // any feature bits that are defined but not set in LND.
3✔
472
        for feature := range other.features {
6✔
473
                if fv.IsSet(feature) {
6✔
474
                        continue
3✔
475
                }
476

477
                if feature > maximumValue {
3✔
UNCOV
478
                        return fmt.Errorf("can't set feature bit %d: %w %v",
×
UNCOV
479
                                feature, ErrFeatureBitMaximum,
×
UNCOV
480
                                maximumValue)
×
UNCOV
481
                }
×
482

483
                if name, known := Features[feature]; known {
6✔
484
                        return fmt.Errorf("can't set feature "+
3✔
485
                                "bit %d (%v): %w", feature, name,
3✔
486
                                ErrFeatureStandard)
3✔
487
                }
3✔
488
        }
489

490
        // Check that the new feature vector for this set does not unset any
491
        // features that are standard in LND by comparing the features in our
492
        // current set to the omitted values in the new set.
493
        for feature := range fv.features {
6✔
494
                if other.IsSet(feature) {
6✔
495
                        continue
3✔
496
                }
497

498
                if name, known := Features[feature]; known {
3✔
UNCOV
499
                        return fmt.Errorf("can't unset feature "+
×
UNCOV
500
                                "bit %d (%v): %w", feature, name,
×
UNCOV
501
                                ErrFeatureStandard)
×
UNCOV
502
                }
×
503
        }
504

505
        return nil
3✔
506
}
507

508
// ValidatePairs checks each feature bit in a raw vector to ensure that the
509
// opposing bit is not set, validating that the vector has either the optional
510
// or required bit set, not both.
511
func (fv *RawFeatureVector) ValidatePairs() error {
3✔
512
        for feature := range fv.features {
6✔
513
                if _, ok := fv.features[feature^1]; ok {
3✔
UNCOV
514
                        return ErrFeaturePairExists
×
UNCOV
515
                }
×
516
        }
517

518
        return nil
3✔
519
}
520

521
// Clone makes a copy of a feature vector.
522
func (fv *RawFeatureVector) Clone() *RawFeatureVector {
3✔
523
        newFeatures := NewRawFeatureVector()
3✔
524
        for bit := range fv.features {
6✔
525
                newFeatures.Set(bit)
3✔
526
        }
3✔
527
        return newFeatures
3✔
528
}
529

530
// IsSet returns whether a particular feature bit is enabled in the vector.
531
func (fv *RawFeatureVector) IsSet(feature FeatureBit) bool {
3✔
532
        _, ok := fv.features[feature]
3✔
533
        return ok
3✔
534
}
3✔
535

536
// Set marks a feature as enabled in the vector.
537
func (fv *RawFeatureVector) Set(feature FeatureBit) {
3✔
538
        fv.features[feature] = struct{}{}
3✔
539
}
3✔
540

541
// SafeSet sets the chosen feature bit in the feature vector, but returns an
542
// error if the opposing feature bit is already set. This ensures both that we
543
// are creating properly structured feature vectors, and in some cases, that
544
// peers are sending properly encoded ones, i.e. it can't be both optional and
545
// required.
546
func (fv *RawFeatureVector) SafeSet(feature FeatureBit) error {
3✔
547
        if _, ok := fv.features[feature^1]; ok {
3✔
UNCOV
548
                return ErrFeaturePairExists
×
UNCOV
549
        }
×
550

551
        fv.Set(feature)
3✔
552
        return nil
3✔
553
}
554

555
// Unset marks a feature as disabled in the vector.
556
func (fv *RawFeatureVector) Unset(feature FeatureBit) {
3✔
557
        delete(fv.features, feature)
3✔
558
}
3✔
559

560
// SerializeSize returns the number of bytes needed to represent feature vector
561
// in byte format.
562
func (fv *RawFeatureVector) SerializeSize() int {
3✔
563
        // We calculate byte-length via the largest bit index.
3✔
564
        return fv.serializeSize(8)
3✔
565
}
3✔
566

567
// SerializeSize32 returns the number of bytes needed to represent feature
568
// vector in base32 format.
569
func (fv *RawFeatureVector) SerializeSize32() int {
3✔
570
        // We calculate base32-length via the largest bit index.
3✔
571
        return fv.serializeSize(5)
3✔
572
}
3✔
573

574
// serializeSize returns the number of bytes required to encode the feature
575
// vector using at most width bits per encoded byte.
576
func (fv *RawFeatureVector) serializeSize(width int) int {
3✔
577
        // Find the largest feature bit index
3✔
578
        max := -1
3✔
579
        for feature := range fv.features {
6✔
580
                index := int(feature)
3✔
581
                if index > max {
6✔
582
                        max = index
3✔
583
                }
3✔
584
        }
585
        if max == -1 {
6✔
586
                return 0
3✔
587
        }
3✔
588

589
        return max/width + 1
3✔
590
}
591

592
// Encode writes the feature vector in byte representation. Every feature
593
// encoded as a bit, and the bit vector is serialized using the least number of
594
// bytes. Since the bit vector length is variable, the first two bytes of the
595
// serialization represent the length.
596
func (fv *RawFeatureVector) Encode(w io.Writer) error {
3✔
597
        // Write length of feature vector.
3✔
598
        var l [2]byte
3✔
599
        length := fv.SerializeSize()
3✔
600
        binary.BigEndian.PutUint16(l[:], uint16(length))
3✔
601
        if _, err := w.Write(l[:]); err != nil {
3✔
602
                return err
×
603
        }
×
604

605
        return fv.encode(w, length, 8)
3✔
606
}
607

608
// EncodeBase256 writes the feature vector in base256 representation. Every
609
// feature is encoded as a bit, and the bit vector is serialized using the least
610
// number of bytes.
611
func (fv *RawFeatureVector) EncodeBase256(w io.Writer) error {
3✔
612
        length := fv.SerializeSize()
3✔
613
        return fv.encode(w, length, 8)
3✔
614
}
3✔
615

616
// EncodeBase32 writes the feature vector in base32 representation. Every feature
617
// is encoded as a bit, and the bit vector is serialized using the least number of
618
// bytes.
619
func (fv *RawFeatureVector) EncodeBase32(w io.Writer) error {
3✔
620
        length := fv.SerializeSize32()
3✔
621
        return fv.encode(w, length, 5)
3✔
622
}
3✔
623

624
// encode writes the feature vector
625
func (fv *RawFeatureVector) encode(w io.Writer, length, width int) error {
3✔
626
        // Generate the data and write it.
3✔
627
        data := make([]byte, length)
3✔
628
        for feature := range fv.features {
6✔
629
                byteIndex := int(feature) / width
3✔
630
                bitIndex := int(feature) % width
3✔
631
                data[length-byteIndex-1] |= 1 << uint(bitIndex)
3✔
632
        }
3✔
633

634
        _, err := w.Write(data)
3✔
635
        return err
3✔
636
}
637

638
// Decode reads the feature vector from its byte representation. Every feature
639
// is encoded as a bit, and the bit vector is serialized using the least number
640
// of bytes. Since the bit vector length is variable, the first two bytes of the
641
// serialization represent the length.
642
func (fv *RawFeatureVector) Decode(r io.Reader) error {
3✔
643
        // Read the length of the feature vector.
3✔
644
        var l [2]byte
3✔
645
        if _, err := io.ReadFull(r, l[:]); err != nil {
3✔
UNCOV
646
                return err
×
UNCOV
647
        }
×
648
        length := binary.BigEndian.Uint16(l[:])
3✔
649

3✔
650
        return fv.decode(r, int(length), 8)
3✔
651
}
652

653
// DecodeBase256 reads the feature vector from its base256 representation. Every
654
// feature encoded as a bit, and the bit vector is serialized using the least
655
// number of bytes.
656
func (fv *RawFeatureVector) DecodeBase256(r io.Reader, length int) error {
3✔
657
        return fv.decode(r, length, 8)
3✔
658
}
3✔
659

660
// DecodeBase32 reads the feature vector from its base32 representation. Every
661
// feature encoded as a bit, and the bit vector is serialized using the least
662
// number of bytes.
663
func (fv *RawFeatureVector) DecodeBase32(r io.Reader, length int) error {
3✔
664
        return fv.decode(r, length, 5)
3✔
665
}
3✔
666

667
// decode reads a feature vector from the next length bytes of the io.Reader,
668
// assuming each byte has width feature bits encoded per byte.
669
func (fv *RawFeatureVector) decode(r io.Reader, length, width int) error {
3✔
670
        // Read the feature vector data.
3✔
671
        data := make([]byte, length)
3✔
672
        if _, err := io.ReadFull(r, data); err != nil {
3✔
UNCOV
673
                return err
×
UNCOV
674
        }
×
675

676
        // Set feature bits from parsed data.
677
        bitsNumber := len(data) * width
3✔
678
        for i := 0; i < bitsNumber; i++ {
6✔
679
                byteIndex := int(i / width)
3✔
680
                bitIndex := uint(i % width)
3✔
681
                if (data[length-byteIndex-1]>>bitIndex)&1 == 1 {
6✔
682
                        fv.Set(FeatureBit(i))
3✔
683
                }
3✔
684
        }
685

686
        return nil
3✔
687
}
688

689
// sizeFunc returns the length required to encode the feature vector.
690
func (fv *RawFeatureVector) sizeFunc() uint64 {
3✔
691
        return uint64(fv.SerializeSize())
3✔
692
}
3✔
693

694
// Record returns a TLV record that can be used to encode/decode raw feature
695
// vectors. Note that the length of the feature vector is not included, because
696
// it is covered by the TLV record's length field.
UNCOV
697
func (fv *RawFeatureVector) Record() tlv.Record {
×
UNCOV
698
        return tlv.MakeDynamicRecord(
×
UNCOV
699
                0, fv, fv.sizeFunc, rawFeatureEncoder, rawFeatureDecoder,
×
UNCOV
700
        )
×
UNCOV
701
}
×
702

703
// rawFeatureEncoder is a custom TLV encoder for raw feature vectors.
704
func rawFeatureEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
3✔
705
        if v, ok := val.(*RawFeatureVector); ok {
6✔
706
                // Encode the feature bits as a byte slice without its length
3✔
707
                // prepended, as that's already taken care of by the TLV record.
3✔
708
                fv := *v
3✔
709
                return fv.encode(w, fv.SerializeSize(), 8)
3✔
710
        }
3✔
711

712
        return tlv.NewTypeForEncodingErr(val, "lnwire.RawFeatureVector")
×
713
}
714

715
// rawFeatureDecoder is a custom TLV decoder for raw feature vectors.
716
func rawFeatureDecoder(r io.Reader, val interface{}, _ *[8]byte,
717
        l uint64) error {
3✔
718

3✔
719
        if v, ok := val.(*RawFeatureVector); ok {
6✔
720
                fv := NewRawFeatureVector()
3✔
721
                if err := fv.decode(r, int(l), 8); err != nil {
3✔
UNCOV
722
                        return err
×
UNCOV
723
                }
×
724
                *v = *fv
3✔
725

3✔
726
                return nil
3✔
727
        }
728

729
        return tlv.NewTypeForEncodingErr(val, "lnwire.RawFeatureVector")
×
730
}
731

732
// FeatureVector represents a set of enabled features. The set stores
733
// information on enabled flags and metadata about the feature names. A feature
734
// vector is serializable to a compact byte representation that is included in
735
// Lightning network messages.
736
type FeatureVector struct {
737
        *RawFeatureVector
738
        featureNames map[FeatureBit]string
739
}
740

741
// NewFeatureVector constructs a new FeatureVector from a raw feature vector
742
// and mapping of feature definitions. If the feature vector argument is nil, a
743
// new one will be constructed with no enabled features.
744
func NewFeatureVector(featureVector *RawFeatureVector,
745
        featureNames map[FeatureBit]string) *FeatureVector {
3✔
746

3✔
747
        if featureVector == nil {
6✔
748
                featureVector = NewRawFeatureVector()
3✔
749
        }
3✔
750
        return &FeatureVector{
3✔
751
                RawFeatureVector: featureVector,
3✔
752
                featureNames:     featureNames,
3✔
753
        }
3✔
754
}
755

756
// EmptyFeatureVector returns a feature vector with no bits set.
757
func EmptyFeatureVector() *FeatureVector {
3✔
758
        return NewFeatureVector(nil, Features)
3✔
759
}
3✔
760

761
// Record implements the RecordProducer interface for FeatureVector. Note that
762
// it uses a zero-value type is used to produce the record, as we expect this
763
// type value to be overwritten when used in generic TLV record production.
764
// This allows a single Record function to serve in the many different contexts
765
// in which feature vectors are encoded. This record wraps the encoding/
766
// decoding for our raw feature vectors so that we can directly parse fully
767
// formed feature vector types.
768
func (fv *FeatureVector) Record() tlv.Record {
3✔
769
        return tlv.MakeDynamicRecord(0, fv, fv.sizeFunc,
3✔
770
                func(w io.Writer, val interface{}, buf *[8]byte) error {
3✔
UNCOV
771
                        if f, ok := val.(*FeatureVector); ok {
×
UNCOV
772
                                return rawFeatureEncoder(
×
UNCOV
773
                                        w, f.RawFeatureVector, buf,
×
UNCOV
774
                                )
×
UNCOV
775
                        }
×
776

777
                        return tlv.NewTypeForEncodingErr(
×
778
                                val, "*lnwire.FeatureVector",
×
779
                        )
×
780
                },
781
                func(r io.Reader, val interface{}, buf *[8]byte,
UNCOV
782
                        l uint64) error {
×
UNCOV
783

×
UNCOV
784
                        if f, ok := val.(*FeatureVector); ok {
×
UNCOV
785
                                features := NewFeatureVector(nil, Features)
×
UNCOV
786
                                err := rawFeatureDecoder(
×
UNCOV
787
                                        r, features.RawFeatureVector, buf, l,
×
UNCOV
788
                                )
×
UNCOV
789
                                if err != nil {
×
790
                                        return err
×
791
                                }
×
792

UNCOV
793
                                *f = *features
×
UNCOV
794

×
UNCOV
795
                                return nil
×
796
                        }
797

798
                        return tlv.NewTypeForDecodingErr(
×
799
                                val, "*lnwire.FeatureVector", l, l,
×
800
                        )
×
801
                },
802
        )
803
}
804

805
// HasFeature returns whether a particular feature is included in the set. The
806
// feature can be seen as set either if the bit is set directly OR the queried
807
// bit has the same meaning as its corresponding even/odd bit, which is set
808
// instead. The second case is because feature bits are generally assigned in
809
// pairs where both the even and odd position represent the same feature.
810
func (fv *FeatureVector) HasFeature(feature FeatureBit) bool {
3✔
811
        return fv.IsSet(feature) ||
3✔
812
                (fv.isFeatureBitPair(feature) && fv.IsSet(feature^1))
3✔
813
}
3✔
814

815
// RequiresFeature returns true if the referenced feature vector *requires*
816
// that the given required bit be set. This method can be used with both
817
// optional and required feature bits as a parameter.
818
func (fv *FeatureVector) RequiresFeature(feature FeatureBit) bool {
3✔
819
        // If we weren't passed a required feature bit, then we'll flip the
3✔
820
        // lowest bit to query for the required version of the feature. This
3✔
821
        // lets callers pass in both the optional and required bits.
3✔
822
        if !feature.IsRequired() {
3✔
UNCOV
823
                feature ^= 1
×
UNCOV
824
        }
×
825

826
        return fv.IsSet(feature)
3✔
827
}
828

829
// UnknownRequiredFeatures returns a list of feature bits set in the vector
830
// that are unknown and in an even bit position. Feature bits with an even
831
// index must be known to a node receiving the feature vector in a message.
832
func (fv *FeatureVector) UnknownRequiredFeatures() []FeatureBit {
3✔
833
        var unknown []FeatureBit
3✔
834
        for feature := range fv.features {
6✔
835
                if feature%2 == 0 && !fv.IsKnown(feature) {
3✔
UNCOV
836
                        unknown = append(unknown, feature)
×
UNCOV
837
                }
×
838
        }
839
        return unknown
3✔
840
}
841

842
// UnknownFeatures returns a boolean if a feature vector contains *any*
843
// unknown features (even if they are odd).
UNCOV
844
func (fv *FeatureVector) UnknownFeatures() bool {
×
UNCOV
845
        for feature := range fv.features {
×
UNCOV
846
                if !fv.IsKnown(feature) {
×
UNCOV
847
                        return true
×
UNCOV
848
                }
×
849
        }
850

851
        return false
×
852
}
853

854
// Name returns a string identifier for the feature represented by this bit. If
855
// the bit does not represent a known feature, this returns a string indicating
856
// as such.
857
func (fv *FeatureVector) Name(bit FeatureBit) string {
3✔
858
        name, known := fv.featureNames[bit]
3✔
859
        if !known {
6✔
860
                return "unknown"
3✔
861
        }
3✔
862
        return name
3✔
863
}
864

865
// IsKnown returns whether this feature bit represents a known feature.
866
func (fv *FeatureVector) IsKnown(bit FeatureBit) bool {
3✔
867
        _, known := fv.featureNames[bit]
3✔
868
        return known
3✔
869
}
3✔
870

871
// isFeatureBitPair returns whether this feature bit and its corresponding
872
// even/odd bit both represent the same feature. This may often be the case as
873
// bits are generally assigned in pairs, first being assigned an odd bit
874
// position then being promoted to an even bit position once the network is
875
// ready.
876
func (fv *FeatureVector) isFeatureBitPair(bit FeatureBit) bool {
3✔
877
        name1, known1 := fv.featureNames[bit]
3✔
878
        name2, known2 := fv.featureNames[bit^1]
3✔
879
        return known1 && known2 && name1 == name2
3✔
880
}
3✔
881

882
// Features returns the set of raw features contained in the feature vector.
883
func (fv *FeatureVector) Features() map[FeatureBit]struct{} {
3✔
884
        fs := make(map[FeatureBit]struct{}, len(fv.RawFeatureVector.features))
3✔
885
        for b := range fv.RawFeatureVector.features {
6✔
886
                fs[b] = struct{}{}
3✔
887
        }
3✔
888
        return fs
3✔
889
}
890

891
// Clone copies a feature vector, carrying over its feature bits. The feature
892
// names are not copied.
893
func (fv *FeatureVector) Clone() *FeatureVector {
3✔
894
        features := fv.RawFeatureVector.Clone()
3✔
895
        return NewFeatureVector(features, fv.featureNames)
3✔
896
}
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc