• 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

7.69
/channeldb/migration/lnwire21/features.go
1
package lnwire
2

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

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

15
// FeatureBit represents a feature that can be enabled in either a local or
16
// global feature vector at a specific bit position. Feature bits follow the
17
// "it's OK to be odd" rule, where features at even bit positions must be known
18
// to a node receiving them from a peer while odd bits do not. In accordance,
19
// feature bits are usually assigned in pairs, first being assigned an odd bit
20
// position which may later be changed to the preceding even position once
21
// knowledge of the feature becomes required on the network.
22
type FeatureBit uint16
23

24
const (
25
        // DataLossProtectRequired is a feature bit that indicates that a peer
26
        // *requires* the other party know about the data-loss-protect optional
27
        // feature. If the remote peer does not know of such a feature, then
28
        // the sending peer SHOLUD disconnect them. The data-loss-protect
29
        // feature allows a peer that's lost partial data to recover their
30
        // settled funds of the latest commitment state.
31
        DataLossProtectRequired FeatureBit = 0
32

33
        // DataLossProtectOptional is an optional feature bit that indicates
34
        // that the sending peer knows of this new feature and can activate it
35
        // it. The data-loss-protect feature allows a peer that's lost partial
36
        // data to recover their settled funds of the latest commitment state.
37
        DataLossProtectOptional FeatureBit = 1
38

39
        // InitialRoutingSync is a local feature bit meaning that the receiving
40
        // node should send a complete dump of routing information when a new
41
        // connection is established.
42
        InitialRoutingSync FeatureBit = 3
43

44
        // UpfrontShutdownScriptRequired is a feature bit which indicates that a
45
        // peer *requires* that the remote peer accept an upfront shutdown script to
46
        // which payout is enforced on cooperative closes.
47
        UpfrontShutdownScriptRequired FeatureBit = 4
48

49
        // UpfrontShutdownScriptOptional is an optional feature bit which indicates
50
        // that the peer will accept an upfront shutdown script to which payout is
51
        // enforced on cooperative closes.
52
        UpfrontShutdownScriptOptional FeatureBit = 5
53

54
        // GossipQueriesRequired is a feature bit that indicates that the
55
        // receiving peer MUST know of the set of features that allows nodes to
56
        // more efficiently query the network view of peers on the network for
57
        // reconciliation purposes.
58
        GossipQueriesRequired FeatureBit = 6
59

60
        // GossipQueriesOptional is an optional feature bit that signals that
61
        // the setting peer knows of the set of features that allows more
62
        // efficient network view reconciliation.
63
        GossipQueriesOptional FeatureBit = 7
64

65
        // TLVOnionPayloadRequired is a feature bit that indicates a node is
66
        // able to decode the new TLV information included in the onion packet.
67
        TLVOnionPayloadRequired FeatureBit = 8
68

69
        // TLVOnionPayloadOptional is an optional feature bit that indicates a
70
        // node is able to decode the new TLV information included in the onion
71
        // packet.
72
        TLVOnionPayloadOptional FeatureBit = 9
73

74
        // StaticRemoteKeyRequired is a required feature bit that signals that
75
        // within one's commitment transaction, the key used for the remote
76
        // party's non-delay output should not be tweaked.
77
        StaticRemoteKeyRequired FeatureBit = 12
78

79
        // StaticRemoteKeyOptional is an optional feature bit that signals that
80
        // within one's commitment transaction, the key used for the remote
81
        // party's non-delay output should not be tweaked.
82
        StaticRemoteKeyOptional FeatureBit = 13
83

84
        // PaymentAddrRequired is a required feature bit that signals that a
85
        // node requires payment addresses, which are used to mitigate probing
86
        // attacks on the receiver of a payment.
87
        PaymentAddrRequired FeatureBit = 14
88

89
        // PaymentAddrOptional is an optional feature bit that signals that a
90
        // node supports payment addresses, which are used to mitigate probing
91
        // attacks on the receiver of a payment.
92
        PaymentAddrOptional FeatureBit = 15
93

94
        // MPPOptional is a required feature bit that signals that the receiver
95
        // of a payment requires settlement of an invoice with more than one
96
        // HTLC.
97
        MPPRequired FeatureBit = 16
98

99
        // MPPOptional is an optional feature bit that signals that the receiver
100
        // of a payment supports settlement of an invoice with more than one
101
        // HTLC.
102
        MPPOptional FeatureBit = 17
103

104
        // WumboChannelsRequired is a required feature bit that signals that a
105
        // node is willing to accept channels larger than 2^24 satoshis.
106
        WumboChannelsRequired FeatureBit = 18
107

108
        // WumboChannelsOptional is an optional feature bit that signals that a
109
        // node is willing to accept channels larger than 2^24 satoshis.
110
        WumboChannelsOptional FeatureBit = 19
111

112
        // AnchorsRequired is a required feature bit that signals that the node
113
        // requires channels to be made using commitments having anchor
114
        // outputs.
115
        AnchorsRequired FeatureBit = 20
116

117
        // AnchorsOptional is an optional feature bit that signals that the
118
        // node supports channels to be made using commitments having anchor
119
        // outputs.
120
        AnchorsOptional FeatureBit = 21
121

122
        // AnchorsZeroFeeHtlcTxRequired is a required feature bit that signals
123
        // that the node requires channels having zero-fee second-level HTLC
124
        // transactions, which also imply anchor commitments.
125
        AnchorsZeroFeeHtlcTxRequired FeatureBit = 22
126

127
        // AnchorsZeroFeeHtlcTxRequired is an optional feature bit that signals
128
        // that the node supports channels having zero-fee second-level HTLC
129
        // transactions, which also imply anchor commitments.
130
        AnchorsZeroFeeHtlcTxOptional FeatureBit = 23
131

132
        // maxAllowedSize is a maximum allowed size of feature vector.
133
        //
134
        // NOTE: Within the protocol, the maximum allowed message size is 65535
135
        // bytes for all messages. Accounting for the overhead within the feature
136
        // message to signal the type of message, that leaves us with 65533 bytes
137
        // for the init message itself.  Next, we reserve 4 bytes to encode the
138
        // lengths of both the local and global feature vectors, so 65529 bytes
139
        // for the local and global features. Knocking off one byte for the sake
140
        // of the calculation, that leads us to 32764 bytes for each feature
141
        // vector, or 131056 different features.
142
        maxAllowedSize = 32764
143
)
144

145
// IsRequired returns true if the feature bit is even, and false otherwise.
146
func (b FeatureBit) IsRequired() bool {
×
147
        return b&0x01 == 0x00
×
148
}
×
149

150
// Features is a mapping of known feature bits to a descriptive name. All known
151
// feature bits must be assigned a name in this mapping, and feature bit pairs
152
// must be assigned together for correct behavior.
153
var Features = map[FeatureBit]string{
154
        DataLossProtectRequired:       "data-loss-protect",
155
        DataLossProtectOptional:       "data-loss-protect",
156
        InitialRoutingSync:            "initial-routing-sync",
157
        UpfrontShutdownScriptRequired: "upfront-shutdown-script",
158
        UpfrontShutdownScriptOptional: "upfront-shutdown-script",
159
        GossipQueriesRequired:         "gossip-queries",
160
        GossipQueriesOptional:         "gossip-queries",
161
        TLVOnionPayloadRequired:       "tlv-onion",
162
        TLVOnionPayloadOptional:       "tlv-onion",
163
        StaticRemoteKeyOptional:       "static-remote-key",
164
        StaticRemoteKeyRequired:       "static-remote-key",
165
        PaymentAddrOptional:           "payment-addr",
166
        PaymentAddrRequired:           "payment-addr",
167
        MPPOptional:                   "multi-path-payments",
168
        MPPRequired:                   "multi-path-payments",
169
        AnchorsRequired:               "anchor-commitments",
170
        AnchorsOptional:               "anchor-commitments",
171
        AnchorsZeroFeeHtlcTxRequired:  "anchors-zero-fee-htlc-tx",
172
        AnchorsZeroFeeHtlcTxOptional:  "anchors-zero-fee-htlc-tx",
173
        WumboChannelsRequired:         "wumbo-channels",
174
        WumboChannelsOptional:         "wumbo-channels",
175
}
176

177
// RawFeatureVector represents a set of feature bits as defined in BOLT-09.  A
178
// RawFeatureVector itself just stores a set of bit flags but can be used to
179
// construct a FeatureVector which binds meaning to each bit. Feature vectors
180
// can be serialized and deserialized to/from a byte representation that is
181
// transmitted in Lightning network messages.
182
type RawFeatureVector struct {
183
        features map[FeatureBit]bool
184
}
185

186
// NewRawFeatureVector creates a feature vector with all of the feature bits
187
// given as arguments enabled.
188
func NewRawFeatureVector(bits ...FeatureBit) *RawFeatureVector {
3✔
189
        fv := &RawFeatureVector{features: make(map[FeatureBit]bool)}
3✔
190
        for _, bit := range bits {
3✔
191
                fv.Set(bit)
×
192
        }
×
193
        return fv
3✔
194
}
195

196
// Merges sets all feature bits in other on the receiver's feature vector.
197
func (fv *RawFeatureVector) Merge(other *RawFeatureVector) error {
×
198
        for bit := range other.features {
×
199
                err := fv.SafeSet(bit)
×
200
                if err != nil {
×
201
                        return err
×
202
                }
×
203
        }
204
        return nil
×
205
}
206

207
// Clone makes a copy of a feature vector.
208
func (fv *RawFeatureVector) Clone() *RawFeatureVector {
×
209
        newFeatures := NewRawFeatureVector()
×
210
        for bit := range fv.features {
×
211
                newFeatures.Set(bit)
×
212
        }
×
213
        return newFeatures
×
214
}
215

216
// IsSet returns whether a particular feature bit is enabled in the vector.
217
func (fv *RawFeatureVector) IsSet(feature FeatureBit) bool {
×
218
        return fv.features[feature]
×
219
}
×
220

221
// Set marks a feature as enabled in the vector.
222
func (fv *RawFeatureVector) Set(feature FeatureBit) {
×
223
        fv.features[feature] = true
×
224
}
×
225

226
// SafeSet sets the chosen feature bit in the feature vector, but returns an
227
// error if the opposing feature bit is already set. This ensures both that we
228
// are creating properly structured feature vectors, and in some cases, that
229
// peers are sending properly encoded ones, i.e. it can't be both optional and
230
// required.
231
func (fv *RawFeatureVector) SafeSet(feature FeatureBit) error {
×
232
        if _, ok := fv.features[feature^1]; ok {
×
233
                return ErrFeaturePairExists
×
234
        }
×
235

236
        fv.Set(feature)
×
237
        return nil
×
238
}
239

240
// Unset marks a feature as disabled in the vector.
241
func (fv *RawFeatureVector) Unset(feature FeatureBit) {
×
242
        delete(fv.features, feature)
×
243
}
×
244

245
// SerializeSize returns the number of bytes needed to represent feature vector
246
// in byte format.
UNCOV
247
func (fv *RawFeatureVector) SerializeSize() int {
×
UNCOV
248
        // We calculate byte-length via the largest bit index.
×
UNCOV
249
        return fv.serializeSize(8)
×
UNCOV
250
}
×
251

252
// SerializeSize32 returns the number of bytes needed to represent feature
253
// vector in base32 format.
254
func (fv *RawFeatureVector) SerializeSize32() int {
×
255
        // We calculate base32-length via the largest bit index.
×
256
        return fv.serializeSize(5)
×
257
}
×
258

259
// serializeSize returns the number of bytes required to encode the feature
260
// vector using at most width bits per encoded byte.
UNCOV
261
func (fv *RawFeatureVector) serializeSize(width int) int {
×
UNCOV
262
        // Find the largest feature bit index
×
UNCOV
263
        max := -1
×
UNCOV
264
        for feature := range fv.features {
×
265
                index := int(feature)
×
266
                if index > max {
×
267
                        max = index
×
268
                }
×
269
        }
UNCOV
270
        if max == -1 {
×
UNCOV
271
                return 0
×
UNCOV
272
        }
×
273

274
        return max/width + 1
×
275
}
276

277
// Encode writes the feature vector in byte representation. Every feature
278
// encoded as a bit, and the bit vector is serialized using the least number of
279
// bytes. Since the bit vector length is variable, the first two bytes of the
280
// serialization represent the length.
UNCOV
281
func (fv *RawFeatureVector) Encode(w io.Writer) error {
×
UNCOV
282
        // Write length of feature vector.
×
UNCOV
283
        var l [2]byte
×
UNCOV
284
        length := fv.SerializeSize()
×
UNCOV
285
        binary.BigEndian.PutUint16(l[:], uint16(length))
×
UNCOV
286
        if _, err := w.Write(l[:]); err != nil {
×
287
                return err
×
288
        }
×
289

UNCOV
290
        return fv.encode(w, length, 8)
×
291
}
292

293
// EncodeBase256 writes the feature vector in base256 representation. Every
294
// feature is encoded as a bit, and the bit vector is serialized using the least
295
// number of bytes.
UNCOV
296
func (fv *RawFeatureVector) EncodeBase256(w io.Writer) error {
×
UNCOV
297
        length := fv.SerializeSize()
×
UNCOV
298
        return fv.encode(w, length, 8)
×
UNCOV
299
}
×
300

301
// EncodeBase32 writes the feature vector in base32 representation. Every feature
302
// is encoded as a bit, and the bit vector is serialized using the least number of
303
// bytes.
304
func (fv *RawFeatureVector) EncodeBase32(w io.Writer) error {
×
305
        length := fv.SerializeSize32()
×
306
        return fv.encode(w, length, 5)
×
307
}
×
308

309
// encode writes the feature vector
UNCOV
310
func (fv *RawFeatureVector) encode(w io.Writer, length, width int) error {
×
UNCOV
311
        // Generate the data and write it.
×
UNCOV
312
        data := make([]byte, length)
×
UNCOV
313
        for feature := range fv.features {
×
314
                byteIndex := int(feature) / width
×
315
                bitIndex := int(feature) % width
×
316
                data[length-byteIndex-1] |= 1 << uint(bitIndex)
×
317
        }
×
318

UNCOV
319
        _, err := w.Write(data)
×
UNCOV
320
        return err
×
321
}
322

323
// Decode reads the feature vector from its byte representation. Every feature
324
// is encoded as a bit, and the bit vector is serialized using the least number
325
// of bytes. Since the bit vector length is variable, the first two bytes of the
326
// serialization represent the length.
UNCOV
327
func (fv *RawFeatureVector) Decode(r io.Reader) error {
×
UNCOV
328
        // Read the length of the feature vector.
×
UNCOV
329
        var l [2]byte
×
UNCOV
330
        if _, err := io.ReadFull(r, l[:]); err != nil {
×
331
                return err
×
332
        }
×
UNCOV
333
        length := binary.BigEndian.Uint16(l[:])
×
UNCOV
334

×
UNCOV
335
        return fv.decode(r, int(length), 8)
×
336
}
337

338
// DecodeBase256 reads the feature vector from its base256 representation. Every
339
// feature encoded as a bit, and the bit vector is serialized using the least
340
// number of bytes.
341
func (fv *RawFeatureVector) DecodeBase256(r io.Reader, length int) error {
×
342
        return fv.decode(r, length, 8)
×
343
}
×
344

345
// DecodeBase32 reads the feature vector from its base32 representation. Every
346
// feature encoded as a bit, and the bit vector is serialized using the least
347
// number of bytes.
348
func (fv *RawFeatureVector) DecodeBase32(r io.Reader, length int) error {
×
349
        return fv.decode(r, length, 5)
×
350
}
×
351

352
// decode reads a feature vector from the next length bytes of the io.Reader,
353
// assuming each byte has width feature bits encoded per byte.
UNCOV
354
func (fv *RawFeatureVector) decode(r io.Reader, length, width int) error {
×
UNCOV
355
        // Read the feature vector data.
×
UNCOV
356
        data := make([]byte, length)
×
UNCOV
357
        if _, err := io.ReadFull(r, data); err != nil {
×
358
                return err
×
359
        }
×
360

361
        // Set feature bits from parsed data.
UNCOV
362
        bitsNumber := len(data) * width
×
UNCOV
363
        for i := 0; i < bitsNumber; i++ {
×
364
                byteIndex := int(i / width)
×
365
                bitIndex := uint(i % width)
×
366
                if (data[length-byteIndex-1]>>bitIndex)&1 == 1 {
×
367
                        fv.Set(FeatureBit(i))
×
368
                }
×
369
        }
370

UNCOV
371
        return nil
×
372
}
373

374
// FeatureVector represents a set of enabled features. The set stores
375
// information on enabled flags and metadata about the feature names. A feature
376
// vector is serializable to a compact byte representation that is included in
377
// Lightning network messages.
378
type FeatureVector struct {
379
        *RawFeatureVector
380
        featureNames map[FeatureBit]string
381
}
382

383
// NewFeatureVector constructs a new FeatureVector from a raw feature vector
384
// and mapping of feature definitions. If the feature vector argument is nil, a
385
// new one will be constructed with no enabled features.
386
func NewFeatureVector(featureVector *RawFeatureVector,
387
        featureNames map[FeatureBit]string) *FeatureVector {
3✔
388

3✔
389
        if featureVector == nil {
6✔
390
                featureVector = NewRawFeatureVector()
3✔
391
        }
3✔
392
        return &FeatureVector{
3✔
393
                RawFeatureVector: featureVector,
3✔
394
                featureNames:     featureNames,
3✔
395
        }
3✔
396
}
397

398
// EmptyFeatureVector returns a feature vector with no bits set.
399
func EmptyFeatureVector() *FeatureVector {
×
400
        return NewFeatureVector(nil, Features)
×
401
}
×
402

403
// HasFeature returns whether a particular feature is included in the set. The
404
// feature can be seen as set either if the bit is set directly OR the queried
405
// bit has the same meaning as its corresponding even/odd bit, which is set
406
// instead. The second case is because feature bits are generally assigned in
407
// pairs where both the even and odd position represent the same feature.
408
func (fv *FeatureVector) HasFeature(feature FeatureBit) bool {
×
409
        return fv.IsSet(feature) ||
×
410
                (fv.isFeatureBitPair(feature) && fv.IsSet(feature^1))
×
411
}
×
412

413
// RequiresFeature returns true if the referenced feature vector *requires*
414
// that the given required bit be set. This method can be used with both
415
// optional and required feature bits as a parameter.
416
func (fv *FeatureVector) RequiresFeature(feature FeatureBit) bool {
×
417
        // If we weren't passed a required feature bit, then we'll flip the
×
418
        // lowest bit to query for the required version of the feature. This
×
419
        // lets callers pass in both the optional and required bits.
×
420
        if !feature.IsRequired() {
×
421
                feature ^= 1
×
422
        }
×
423

424
        return fv.IsSet(feature)
×
425
}
426

427
// UnknownRequiredFeatures returns a list of feature bits set in the vector
428
// that are unknown and in an even bit position. Feature bits with an even
429
// index must be known to a node receiving the feature vector in a message.
430
func (fv *FeatureVector) UnknownRequiredFeatures() []FeatureBit {
×
431
        var unknown []FeatureBit
×
432
        for feature := range fv.features {
×
433
                if feature%2 == 0 && !fv.IsKnown(feature) {
×
434
                        unknown = append(unknown, feature)
×
435
                }
×
436
        }
437
        return unknown
×
438
}
439

440
// Name returns a string identifier for the feature represented by this bit. If
441
// the bit does not represent a known feature, this returns a string indicating
442
// as such.
443
func (fv *FeatureVector) Name(bit FeatureBit) string {
×
444
        name, known := fv.featureNames[bit]
×
445
        if !known {
×
446
                return "unknown"
×
447
        }
×
448
        return name
×
449
}
450

451
// IsKnown returns whether this feature bit represents a known feature.
452
func (fv *FeatureVector) IsKnown(bit FeatureBit) bool {
×
453
        _, known := fv.featureNames[bit]
×
454
        return known
×
455
}
×
456

457
// isFeatureBitPair returns whether this feature bit and its corresponding
458
// even/odd bit both represent the same feature. This may often be the case as
459
// bits are generally assigned in pairs, first being assigned an odd bit
460
// position then being promoted to an even bit position once the network is
461
// ready.
462
func (fv *FeatureVector) isFeatureBitPair(bit FeatureBit) bool {
×
463
        name1, known1 := fv.featureNames[bit]
×
464
        name2, known2 := fv.featureNames[bit^1]
×
465
        return known1 && known2 && name1 == name2
×
466
}
×
467

468
// Features returns the set of raw features contained in the feature vector.
469
func (fv *FeatureVector) Features() map[FeatureBit]struct{} {
×
470
        fs := make(map[FeatureBit]struct{}, len(fv.RawFeatureVector.features))
×
471
        for b := range fv.RawFeatureVector.features {
×
472
                fs[b] = struct{}{}
×
473
        }
×
474
        return fs
×
475
}
476

477
// Clone copies a feature vector, carrying over its feature bits. The feature
478
// names are not copied.
479
func (fv *FeatureVector) Clone() *FeatureVector {
×
480
        features := fv.RawFeatureVector.Clone()
×
481
        return NewFeatureVector(features, fv.featureNames)
×
482
}
×
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