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

lightningnetwork / lnd / 13211764208

08 Feb 2025 03:08AM UTC coverage: 49.288% (-9.5%) from 58.815%
13211764208

Pull #9489

github

calvinrzachman
itest: verify switchrpc server enforces send then track

We prevent the rpc server from allowing onion dispatches for
attempt IDs which have already been tracked by rpc clients.

This helps protect the client from leaking a duplicate onion
attempt. NOTE: This is not the only method for solving this
issue! The issue could be addressed via careful client side
programming which accounts for the uncertainty and async
nature of dispatching onions to a remote process via RPC.
This would require some lnd ChannelRouter changes for how
we intend to use these RPCs though.
Pull Request #9489: multi: add BuildOnion, SendOnion, and TrackOnion RPCs

474 of 990 new or added lines in 11 files covered. (47.88%)

27321 existing lines in 435 files now uncovered.

101192 of 205306 relevant lines covered (49.29%)

1.54 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
        // ScriptEnforcedLeaseRequired is a required feature bit that signals
237
        // that the node requires channels having zero-fee second-level HTLC
238
        // transactions, which also imply anchor commitments, along with an
239
        // additional CLTV constraint of a channel lease's expiration height
240
        // applied to all outputs that pay directly to the channel initiator.
241
        //
242
        // TODO: Decide on actual feature bit value.
243
        ScriptEnforcedLeaseRequired FeatureBit = 2022
244

245
        // ScriptEnforcedLeaseOptional is an optional feature bit that signals
246
        // that the node requires channels having zero-fee second-level HTLC
247
        // transactions, which also imply anchor commitments, along with an
248
        // additional CLTV constraint of a channel lease's expiration height
249
        // applied to all outputs that pay directly to the channel initiator.
250
        //
251
        // TODO: Decide on actual feature bit value.
252
        ScriptEnforcedLeaseOptional FeatureBit = 2023
253

254
        // SimpleTaprootChannelsRequiredFinal is a required bit that indicates
255
        // the node is able to create taproot-native channels. This is the
256
        // final feature bit to be used once the channel type is finalized.
257
        SimpleTaprootChannelsRequiredFinal = 80
258

259
        // SimpleTaprootChannelsOptionalFinal is an optional bit that indicates
260
        // the node is able to create taproot-native channels. This is the
261
        // final feature bit to be used once the channel type is finalized.
262
        SimpleTaprootChannelsOptionalFinal = 81
263

264
        // SimpleTaprootChannelsRequiredStaging is a required bit that indicates
265
        // the node is able to create taproot-native channels. This is a
266
        // feature bit used in the wild while the channel type is still being
267
        // finalized.
268
        SimpleTaprootChannelsRequiredStaging = 180
269

270
        // SimpleTaprootChannelsOptionalStaging is an optional bit that
271
        // indicates the node is able to create taproot-native channels. This
272
        // is a feature bit used in the wild while the channel type is still
273
        // being finalized.
274
        SimpleTaprootChannelsOptionalStaging = 181
275

276
        // ExperimentalEndorsementRequired is a required feature bit that
277
        // indicates that the node will relay experimental endorsement signals.
278
        ExperimentalEndorsementRequired FeatureBit = 260
279

280
        // ExperimentalEndorsementOptional is an optional feature bit that
281
        // indicates that the node will relay experimental endorsement signals.
282
        ExperimentalEndorsementOptional FeatureBit = 261
283

284
        // Bolt11BlindedPathsRequired is a required feature bit that indicates
285
        // that the node is able to understand the blinded path tagged field in
286
        // a BOLT 11 invoice.
287
        Bolt11BlindedPathsRequired = 262
288

289
        // Bolt11BlindedPathsOptional is an optional feature bit that indicates
290
        // that the node is able to understand the blinded path tagged field in
291
        // a BOLT 11 invoice.
292
        Bolt11BlindedPathsOptional = 263
293

294
        // SimpleTaprootOverlayChansRequired is a required bit that indicates
295
        // support for the special custom taproot overlay channel.
296
        SimpleTaprootOverlayChansOptional = 2025
297

298
        // SimpleTaprootOverlayChansRequired is a required bit that indicates
299
        // support for the special custom taproot overlay channel.
300
        SimpleTaprootOverlayChansRequired = 2026
301

302
        // MaxBolt11Feature is the maximum feature bit value allowed in bolt 11
303
        // invoices.
304
        //
305
        // The base 32 encoded tagged fields in invoices are limited to 10 bits
306
        // to express the length of the field's data.
307
        //nolint:ll
308
        // See: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md#tagged-fields
309
        //
310
        // With a maximum length field of 1023 (2^10 -1) and 5 bit encoding,
311
        // the highest feature bit that can be expressed is:
312
        // 1023 * 5 - 1 = 5114.
313
        MaxBolt11Feature = 5114
314
)
315

316
// IsRequired returns true if the feature bit is even, and false otherwise.
317
func (b FeatureBit) IsRequired() bool {
3✔
318
        return b&0x01 == 0x00
3✔
319
}
3✔
320

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

378
// RawFeatureVector represents a set of feature bits as defined in BOLT-09.  A
379
// RawFeatureVector itself just stores a set of bit flags but can be used to
380
// construct a FeatureVector which binds meaning to each bit. Feature vectors
381
// can be serialized and deserialized to/from a byte representation that is
382
// transmitted in Lightning network messages.
383
type RawFeatureVector struct {
384
        features map[FeatureBit]struct{}
385
}
386

387
// NewRawFeatureVector creates a feature vector with all of the feature bits
388
// given as arguments enabled.
389
func NewRawFeatureVector(bits ...FeatureBit) *RawFeatureVector {
3✔
390
        fv := &RawFeatureVector{features: make(map[FeatureBit]struct{})}
3✔
391
        for _, bit := range bits {
6✔
392
                fv.Set(bit)
3✔
393
        }
3✔
394
        return fv
3✔
395
}
396

397
// IsEmpty returns whether the feature vector contains any feature bits.
398
func (fv RawFeatureVector) IsEmpty() bool {
3✔
399
        return len(fv.features) == 0
3✔
400
}
3✔
401

402
// OnlyContains determines whether only the specified feature bits are found.
403
func (fv RawFeatureVector) OnlyContains(bits ...FeatureBit) bool {
3✔
404
        if len(bits) != len(fv.features) {
6✔
405
                return false
3✔
406
        }
3✔
407
        for _, bit := range bits {
6✔
408
                if !fv.IsSet(bit) {
6✔
409
                        return false
3✔
410
                }
3✔
411
        }
412
        return true
3✔
413
}
414

415
// Equals determines whether two features vectors contain exactly the same
416
// features.
417
func (fv RawFeatureVector) Equals(other *RawFeatureVector) bool {
3✔
418
        if len(fv.features) != len(other.features) {
3✔
UNCOV
419
                return false
×
UNCOV
420
        }
×
421
        for bit := range fv.features {
6✔
422
                if _, ok := other.features[bit]; !ok {
3✔
UNCOV
423
                        return false
×
UNCOV
424
                }
×
425
        }
426
        return true
3✔
427
}
428

429
// Merges sets all feature bits in other on the receiver's feature vector.
430
func (fv *RawFeatureVector) Merge(other *RawFeatureVector) error {
3✔
431
        for bit := range other.features {
6✔
432
                err := fv.SafeSet(bit)
3✔
433
                if err != nil {
3✔
434
                        return err
×
435
                }
×
436
        }
437
        return nil
3✔
438
}
439

440
// ValidateUpdate checks whether a feature vector can safely be updated to the
441
// new feature vector provided, checking that it does not alter any of the
442
// "standard" features that are defined by LND. The new feature vector should
443
// be inclusive of all features in the original vector that it still wants to
444
// advertise, setting and unsetting updates as desired. Features in the vector
445
// are also checked against a maximum inclusive value, as feature vectors in
446
// different contexts have different maximum values.
447
func (fv *RawFeatureVector) ValidateUpdate(other *RawFeatureVector,
448
        maximumValue FeatureBit) error {
3✔
449

3✔
450
        // Run through the new set of features and check that we're not adding
3✔
451
        // any feature bits that are defined but not set in LND.
3✔
452
        for feature := range other.features {
6✔
453
                if fv.IsSet(feature) {
6✔
454
                        continue
3✔
455
                }
456

457
                if feature > maximumValue {
3✔
UNCOV
458
                        return fmt.Errorf("can't set feature bit %d: %w %v",
×
UNCOV
459
                                feature, ErrFeatureBitMaximum,
×
UNCOV
460
                                maximumValue)
×
UNCOV
461
                }
×
462

463
                if name, known := Features[feature]; known {
6✔
464
                        return fmt.Errorf("can't set feature "+
3✔
465
                                "bit %d (%v): %w", feature, name,
3✔
466
                                ErrFeatureStandard)
3✔
467
                }
3✔
468
        }
469

470
        // Check that the new feature vector for this set does not unset any
471
        // features that are standard in LND by comparing the features in our
472
        // current set to the omitted values in the new set.
473
        for feature := range fv.features {
6✔
474
                if other.IsSet(feature) {
6✔
475
                        continue
3✔
476
                }
477

478
                if name, known := Features[feature]; known {
3✔
UNCOV
479
                        return fmt.Errorf("can't unset feature "+
×
UNCOV
480
                                "bit %d (%v): %w", feature, name,
×
UNCOV
481
                                ErrFeatureStandard)
×
UNCOV
482
                }
×
483
        }
484

485
        return nil
3✔
486
}
487

488
// ValidatePairs checks each feature bit in a raw vector to ensure that the
489
// opposing bit is not set, validating that the vector has either the optional
490
// or required bit set, not both.
491
func (fv *RawFeatureVector) ValidatePairs() error {
3✔
492
        for feature := range fv.features {
6✔
493
                if _, ok := fv.features[feature^1]; ok {
3✔
UNCOV
494
                        return ErrFeaturePairExists
×
UNCOV
495
                }
×
496
        }
497

498
        return nil
3✔
499
}
500

501
// Clone makes a copy of a feature vector.
502
func (fv *RawFeatureVector) Clone() *RawFeatureVector {
3✔
503
        newFeatures := NewRawFeatureVector()
3✔
504
        for bit := range fv.features {
6✔
505
                newFeatures.Set(bit)
3✔
506
        }
3✔
507
        return newFeatures
3✔
508
}
509

510
// IsSet returns whether a particular feature bit is enabled in the vector.
511
func (fv *RawFeatureVector) IsSet(feature FeatureBit) bool {
3✔
512
        _, ok := fv.features[feature]
3✔
513
        return ok
3✔
514
}
3✔
515

516
// Set marks a feature as enabled in the vector.
517
func (fv *RawFeatureVector) Set(feature FeatureBit) {
3✔
518
        fv.features[feature] = struct{}{}
3✔
519
}
3✔
520

521
// SafeSet sets the chosen feature bit in the feature vector, but returns an
522
// error if the opposing feature bit is already set. This ensures both that we
523
// are creating properly structured feature vectors, and in some cases, that
524
// peers are sending properly encoded ones, i.e. it can't be both optional and
525
// required.
526
func (fv *RawFeatureVector) SafeSet(feature FeatureBit) error {
3✔
527
        if _, ok := fv.features[feature^1]; ok {
3✔
UNCOV
528
                return ErrFeaturePairExists
×
UNCOV
529
        }
×
530

531
        fv.Set(feature)
3✔
532
        return nil
3✔
533
}
534

535
// Unset marks a feature as disabled in the vector.
536
func (fv *RawFeatureVector) Unset(feature FeatureBit) {
3✔
537
        delete(fv.features, feature)
3✔
538
}
3✔
539

540
// SerializeSize returns the number of bytes needed to represent feature vector
541
// in byte format.
542
func (fv *RawFeatureVector) SerializeSize() int {
3✔
543
        // We calculate byte-length via the largest bit index.
3✔
544
        return fv.serializeSize(8)
3✔
545
}
3✔
546

547
// SerializeSize32 returns the number of bytes needed to represent feature
548
// vector in base32 format.
549
func (fv *RawFeatureVector) SerializeSize32() int {
3✔
550
        // We calculate base32-length via the largest bit index.
3✔
551
        return fv.serializeSize(5)
3✔
552
}
3✔
553

554
// serializeSize returns the number of bytes required to encode the feature
555
// vector using at most width bits per encoded byte.
556
func (fv *RawFeatureVector) serializeSize(width int) int {
3✔
557
        // Find the largest feature bit index
3✔
558
        max := -1
3✔
559
        for feature := range fv.features {
6✔
560
                index := int(feature)
3✔
561
                if index > max {
6✔
562
                        max = index
3✔
563
                }
3✔
564
        }
565
        if max == -1 {
6✔
566
                return 0
3✔
567
        }
3✔
568

569
        return max/width + 1
3✔
570
}
571

572
// Encode writes the feature vector in byte representation. Every feature
573
// encoded as a bit, and the bit vector is serialized using the least number of
574
// bytes. Since the bit vector length is variable, the first two bytes of the
575
// serialization represent the length.
576
func (fv *RawFeatureVector) Encode(w io.Writer) error {
3✔
577
        // Write length of feature vector.
3✔
578
        var l [2]byte
3✔
579
        length := fv.SerializeSize()
3✔
580
        binary.BigEndian.PutUint16(l[:], uint16(length))
3✔
581
        if _, err := w.Write(l[:]); err != nil {
3✔
582
                return err
×
583
        }
×
584

585
        return fv.encode(w, length, 8)
3✔
586
}
587

588
// EncodeBase256 writes the feature vector in base256 representation. Every
589
// feature is encoded as a bit, and the bit vector is serialized using the least
590
// number of bytes.
591
func (fv *RawFeatureVector) EncodeBase256(w io.Writer) error {
3✔
592
        length := fv.SerializeSize()
3✔
593
        return fv.encode(w, length, 8)
3✔
594
}
3✔
595

596
// EncodeBase32 writes the feature vector in base32 representation. Every feature
597
// is encoded as a bit, and the bit vector is serialized using the least number of
598
// bytes.
599
func (fv *RawFeatureVector) EncodeBase32(w io.Writer) error {
3✔
600
        length := fv.SerializeSize32()
3✔
601
        return fv.encode(w, length, 5)
3✔
602
}
3✔
603

604
// encode writes the feature vector
605
func (fv *RawFeatureVector) encode(w io.Writer, length, width int) error {
3✔
606
        // Generate the data and write it.
3✔
607
        data := make([]byte, length)
3✔
608
        for feature := range fv.features {
6✔
609
                byteIndex := int(feature) / width
3✔
610
                bitIndex := int(feature) % width
3✔
611
                data[length-byteIndex-1] |= 1 << uint(bitIndex)
3✔
612
        }
3✔
613

614
        _, err := w.Write(data)
3✔
615
        return err
3✔
616
}
617

618
// Decode reads the feature vector from its byte representation. Every feature
619
// is encoded as a bit, and the bit vector is serialized using the least number
620
// of bytes. Since the bit vector length is variable, the first two bytes of the
621
// serialization represent the length.
622
func (fv *RawFeatureVector) Decode(r io.Reader) error {
3✔
623
        // Read the length of the feature vector.
3✔
624
        var l [2]byte
3✔
625
        if _, err := io.ReadFull(r, l[:]); err != nil {
3✔
UNCOV
626
                return err
×
UNCOV
627
        }
×
628
        length := binary.BigEndian.Uint16(l[:])
3✔
629

3✔
630
        return fv.decode(r, int(length), 8)
3✔
631
}
632

633
// DecodeBase256 reads the feature vector from its base256 representation. Every
634
// feature encoded as a bit, and the bit vector is serialized using the least
635
// number of bytes.
636
func (fv *RawFeatureVector) DecodeBase256(r io.Reader, length int) error {
3✔
637
        return fv.decode(r, length, 8)
3✔
638
}
3✔
639

640
// DecodeBase32 reads the feature vector from its base32 representation. Every
641
// feature encoded as a bit, and the bit vector is serialized using the least
642
// number of bytes.
643
func (fv *RawFeatureVector) DecodeBase32(r io.Reader, length int) error {
3✔
644
        return fv.decode(r, length, 5)
3✔
645
}
3✔
646

647
// decode reads a feature vector from the next length bytes of the io.Reader,
648
// assuming each byte has width feature bits encoded per byte.
649
func (fv *RawFeatureVector) decode(r io.Reader, length, width int) error {
3✔
650
        // Read the feature vector data.
3✔
651
        data := make([]byte, length)
3✔
652
        if _, err := io.ReadFull(r, data); err != nil {
3✔
UNCOV
653
                return err
×
UNCOV
654
        }
×
655

656
        // Set feature bits from parsed data.
657
        bitsNumber := len(data) * width
3✔
658
        for i := 0; i < bitsNumber; i++ {
6✔
659
                byteIndex := int(i / width)
3✔
660
                bitIndex := uint(i % width)
3✔
661
                if (data[length-byteIndex-1]>>bitIndex)&1 == 1 {
6✔
662
                        fv.Set(FeatureBit(i))
3✔
663
                }
3✔
664
        }
665

666
        return nil
3✔
667
}
668

669
// sizeFunc returns the length required to encode the feature vector.
670
func (fv *RawFeatureVector) sizeFunc() uint64 {
3✔
671
        return uint64(fv.SerializeSize())
3✔
672
}
3✔
673

674
// Record returns a TLV record that can be used to encode/decode raw feature
675
// vectors. Note that the length of the feature vector is not included, because
676
// it is covered by the TLV record's length field.
UNCOV
677
func (fv *RawFeatureVector) Record() tlv.Record {
×
UNCOV
678
        return tlv.MakeDynamicRecord(
×
UNCOV
679
                0, fv, fv.sizeFunc, rawFeatureEncoder, rawFeatureDecoder,
×
UNCOV
680
        )
×
UNCOV
681
}
×
682

683
// rawFeatureEncoder is a custom TLV encoder for raw feature vectors.
684
func rawFeatureEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
3✔
685
        if v, ok := val.(*RawFeatureVector); ok {
6✔
686
                // Encode the feature bits as a byte slice without its length
3✔
687
                // prepended, as that's already taken care of by the TLV record.
3✔
688
                fv := *v
3✔
689
                return fv.encode(w, fv.SerializeSize(), 8)
3✔
690
        }
3✔
691

692
        return tlv.NewTypeForEncodingErr(val, "lnwire.RawFeatureVector")
×
693
}
694

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

3✔
699
        if v, ok := val.(*RawFeatureVector); ok {
6✔
700
                fv := NewRawFeatureVector()
3✔
701
                if err := fv.decode(r, int(l), 8); err != nil {
3✔
UNCOV
702
                        return err
×
UNCOV
703
                }
×
704
                *v = *fv
3✔
705

3✔
706
                return nil
3✔
707
        }
708

709
        return tlv.NewTypeForEncodingErr(val, "lnwire.RawFeatureVector")
×
710
}
711

712
// FeatureVector represents a set of enabled features. The set stores
713
// information on enabled flags and metadata about the feature names. A feature
714
// vector is serializable to a compact byte representation that is included in
715
// Lightning network messages.
716
type FeatureVector struct {
717
        *RawFeatureVector
718
        featureNames map[FeatureBit]string
719
}
720

721
// NewFeatureVector constructs a new FeatureVector from a raw feature vector
722
// and mapping of feature definitions. If the feature vector argument is nil, a
723
// new one will be constructed with no enabled features.
724
func NewFeatureVector(featureVector *RawFeatureVector,
725
        featureNames map[FeatureBit]string) *FeatureVector {
3✔
726

3✔
727
        if featureVector == nil {
6✔
728
                featureVector = NewRawFeatureVector()
3✔
729
        }
3✔
730
        return &FeatureVector{
3✔
731
                RawFeatureVector: featureVector,
3✔
732
                featureNames:     featureNames,
3✔
733
        }
3✔
734
}
735

736
// EmptyFeatureVector returns a feature vector with no bits set.
737
func EmptyFeatureVector() *FeatureVector {
3✔
738
        return NewFeatureVector(nil, Features)
3✔
739
}
3✔
740

741
// Record implements the RecordProducer interface for FeatureVector. Note that
742
// it uses a zero-value type is used to produce the record, as we expect this
743
// type value to be overwritten when used in generic TLV record production.
744
// This allows a single Record function to serve in the many different contexts
745
// in which feature vectors are encoded. This record wraps the encoding/
746
// decoding for our raw feature vectors so that we can directly parse fully
747
// formed feature vector types.
748
func (fv *FeatureVector) Record() tlv.Record {
3✔
749
        return tlv.MakeDynamicRecord(0, fv, fv.sizeFunc,
3✔
750
                func(w io.Writer, val interface{}, buf *[8]byte) error {
3✔
UNCOV
751
                        if f, ok := val.(*FeatureVector); ok {
×
UNCOV
752
                                return rawFeatureEncoder(
×
UNCOV
753
                                        w, f.RawFeatureVector, buf,
×
UNCOV
754
                                )
×
UNCOV
755
                        }
×
756

757
                        return tlv.NewTypeForEncodingErr(
×
758
                                val, "*lnwire.FeatureVector",
×
759
                        )
×
760
                },
761
                func(r io.Reader, val interface{}, buf *[8]byte,
UNCOV
762
                        l uint64) error {
×
UNCOV
763

×
UNCOV
764
                        if f, ok := val.(*FeatureVector); ok {
×
UNCOV
765
                                features := NewFeatureVector(nil, Features)
×
UNCOV
766
                                err := rawFeatureDecoder(
×
UNCOV
767
                                        r, features.RawFeatureVector, buf, l,
×
UNCOV
768
                                )
×
UNCOV
769
                                if err != nil {
×
770
                                        return err
×
771
                                }
×
772

UNCOV
773
                                *f = *features
×
UNCOV
774

×
UNCOV
775
                                return nil
×
776
                        }
777

778
                        return tlv.NewTypeForDecodingErr(
×
779
                                val, "*lnwire.FeatureVector", l, l,
×
780
                        )
×
781
                },
782
        )
783
}
784

785
// HasFeature returns whether a particular feature is included in the set. The
786
// feature can be seen as set either if the bit is set directly OR the queried
787
// bit has the same meaning as its corresponding even/odd bit, which is set
788
// instead. The second case is because feature bits are generally assigned in
789
// pairs where both the even and odd position represent the same feature.
790
func (fv *FeatureVector) HasFeature(feature FeatureBit) bool {
3✔
791
        return fv.IsSet(feature) ||
3✔
792
                (fv.isFeatureBitPair(feature) && fv.IsSet(feature^1))
3✔
793
}
3✔
794

795
// RequiresFeature returns true if the referenced feature vector *requires*
796
// that the given required bit be set. This method can be used with both
797
// optional and required feature bits as a parameter.
798
func (fv *FeatureVector) RequiresFeature(feature FeatureBit) bool {
3✔
799
        // If we weren't passed a required feature bit, then we'll flip the
3✔
800
        // lowest bit to query for the required version of the feature. This
3✔
801
        // lets callers pass in both the optional and required bits.
3✔
802
        if !feature.IsRequired() {
3✔
UNCOV
803
                feature ^= 1
×
UNCOV
804
        }
×
805

806
        return fv.IsSet(feature)
3✔
807
}
808

809
// UnknownRequiredFeatures returns a list of feature bits set in the vector
810
// that are unknown and in an even bit position. Feature bits with an even
811
// index must be known to a node receiving the feature vector in a message.
812
func (fv *FeatureVector) UnknownRequiredFeatures() []FeatureBit {
3✔
813
        var unknown []FeatureBit
3✔
814
        for feature := range fv.features {
6✔
815
                if feature%2 == 0 && !fv.IsKnown(feature) {
3✔
UNCOV
816
                        unknown = append(unknown, feature)
×
UNCOV
817
                }
×
818
        }
819
        return unknown
3✔
820
}
821

822
// UnknownFeatures returns a boolean if a feature vector contains *any*
823
// unknown features (even if they are odd).
UNCOV
824
func (fv *FeatureVector) UnknownFeatures() bool {
×
UNCOV
825
        for feature := range fv.features {
×
UNCOV
826
                if !fv.IsKnown(feature) {
×
UNCOV
827
                        return true
×
UNCOV
828
                }
×
829
        }
830

831
        return false
×
832
}
833

834
// Name returns a string identifier for the feature represented by this bit. If
835
// the bit does not represent a known feature, this returns a string indicating
836
// as such.
837
func (fv *FeatureVector) Name(bit FeatureBit) string {
3✔
838
        name, known := fv.featureNames[bit]
3✔
839
        if !known {
6✔
840
                return "unknown"
3✔
841
        }
3✔
842
        return name
3✔
843
}
844

845
// IsKnown returns whether this feature bit represents a known feature.
846
func (fv *FeatureVector) IsKnown(bit FeatureBit) bool {
3✔
847
        _, known := fv.featureNames[bit]
3✔
848
        return known
3✔
849
}
3✔
850

851
// isFeatureBitPair returns whether this feature bit and its corresponding
852
// even/odd bit both represent the same feature. This may often be the case as
853
// bits are generally assigned in pairs, first being assigned an odd bit
854
// position then being promoted to an even bit position once the network is
855
// ready.
856
func (fv *FeatureVector) isFeatureBitPair(bit FeatureBit) bool {
3✔
857
        name1, known1 := fv.featureNames[bit]
3✔
858
        name2, known2 := fv.featureNames[bit^1]
3✔
859
        return known1 && known2 && name1 == name2
3✔
860
}
3✔
861

862
// Features returns the set of raw features contained in the feature vector.
863
func (fv *FeatureVector) Features() map[FeatureBit]struct{} {
3✔
864
        fs := make(map[FeatureBit]struct{}, len(fv.RawFeatureVector.features))
3✔
865
        for b := range fv.RawFeatureVector.features {
6✔
866
                fs[b] = struct{}{}
3✔
867
        }
3✔
868
        return fs
3✔
869
}
870

871
// Clone copies a feature vector, carrying over its feature bits. The feature
872
// names are not copied.
873
func (fv *FeatureVector) Clone() *FeatureVector {
3✔
874
        features := fv.RawFeatureVector.Clone()
3✔
875
        return NewFeatureVector(features, fv.featureNames)
3✔
876
}
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