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

lightningnetwork / lnd / 17912443871

22 Sep 2025 10:28AM UTC coverage: 66.693% (+0.03%) from 66.668%
17912443871

Pull #10232

github

web-flow
Merge eaae09b85 into 055fb436e
Pull Request #10232: lnwire: add missing Gossip 1.75 fields and message

487 of 564 new or added lines in 19 files covered. (86.35%)

86 existing lines in 21 files now uncovered.

136872 of 205226 relevant lines covered (66.69%)

21306.01 hits per line

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

81.68
/lnwire/node_announcement_2.go
1
package lnwire
2

3
import (
4
        "bytes"
5
        "encoding/binary"
6
        "fmt"
7
        "image/color"
8
        "io"
9
        "net"
10

11
        "github.com/lightningnetwork/lnd/tlv"
12
        "github.com/lightningnetwork/lnd/tor"
13
)
14

15
type NodeAnnouncement2 struct {
16
        // Features is the feature vector that encodes the features supported
17
        // by the target node.
18
        Features tlv.RecordT[tlv.TlvType0, RawFeatureVector]
19

20
        // Color is an optional field used to customize a node's appearance in
21
        // maps and graphs.
22
        Color tlv.OptionalRecordT[tlv.TlvType1, Color]
23

24
        // BlockHeight allows ordering in the case of multiple announcements. We
25
        // should ignore the message if block height is not greater than the
26
        // last-received. The block height must always be greater or equal to
27
        // the block height that the channel funding transaction was confirmed
28
        // in.
29
        BlockHeight tlv.RecordT[tlv.TlvType2, uint32]
30

31
        // Alias is used to customize their node's appearance in maps and
32
        // graphs.
33
        Alias tlv.OptionalRecordT[tlv.TlvType3, []byte]
34

35
        // NodeID is the public key of the node creating the announcement.
36
        NodeID tlv.RecordT[tlv.TlvType6, [33]byte]
37

38
        // IPV4Addrs is an optional list of ipv4 addresses that the node is
39
        // reachable at.
40
        IPV4Addrs tlv.OptionalRecordT[tlv.TlvType5, IPV4Addrs]
41

42
        // IPV6Addrs is an optional list of ipv6 addresses that the node is
43
        // reachable at.
44
        IPV6Addrs tlv.OptionalRecordT[tlv.TlvType7, IPV6Addrs]
45

46
        // TorV3Addrs is an optional list of tor v3 addresses that the node is
47
        // reachable at.
48
        TorV3Addrs tlv.OptionalRecordT[tlv.TlvType9, TorV3Addrs]
49

50
        // DNSHostName is an optional DNS hostname that the node is reachable
51
        // at.
52
        DNSHostName tlv.OptionalRecordT[tlv.TlvType11, DNSAddress]
53

54
        // Signature is used to validate the announced data and prove the
55
        // ownership of node id.
56
        Signature tlv.RecordT[tlv.TlvType160, Sig]
57

58
        // Any extra fields in the signed range that we do not yet know about,
59
        // but we need to keep them for signature validation and to produce a
60
        // valid message.
61
        ExtraSignedFields
62
}
63

64
// AllRecords returns all the TLV records for the message. This will include all
65
// the records we know about along with any that we don't know about but that
66
// fall in the signed TLV range.
67
//
68
// NOTE: this is part of the PureTLVMessage interface.
69
func (n *NodeAnnouncement2) AllRecords() []tlv.Record {
101✔
70
        recordProducers := []tlv.RecordProducer{
101✔
71
                &n.Features,
101✔
72
                &n.BlockHeight,
101✔
73
                &n.NodeID,
101✔
74
                &n.Signature,
101✔
75
        }
101✔
76

101✔
77
        n.Color.WhenSome(func(r tlv.RecordT[tlv.TlvType1, Color]) {
153✔
78
                recordProducers = append(recordProducers, &r)
52✔
79
        })
52✔
80

81
        n.Alias.WhenSome(func(a tlv.RecordT[tlv.TlvType3, []byte]) {
149✔
82
                recordProducers = append(recordProducers, &a)
48✔
83
        })
48✔
84

85
        n.IPV4Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType5, IPV4Addrs]) {
156✔
86
                recordProducers = append(recordProducers, &r)
55✔
87
        })
55✔
88

89
        n.IPV6Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType7, IPV6Addrs]) {
151✔
90
                recordProducers = append(recordProducers, &r)
50✔
91
        })
50✔
92

93
        n.TorV3Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType9, TorV3Addrs]) {
149✔
94
                recordProducers = append(recordProducers, &r)
48✔
95
        })
48✔
96

97
        n.DNSHostName.WhenSome(func(r tlv.RecordT[tlv.TlvType11, DNSAddress]) {
155✔
98
                recordProducers = append(recordProducers, &r)
54✔
99
        })
54✔
100

101
        recordProducers = append(recordProducers, RecordsAsProducers(
101✔
102
                tlv.MapToRecords(n.ExtraSignedFields),
101✔
103
        )...)
101✔
104

101✔
105
        return ProduceRecordsSorted(recordProducers...)
101✔
106
}
107

108
// Decode deserializes a serialized ChannelUpdate2 stored in the passed
109
// io.Reader observing the specified protocol version.
110
//
111
// This is part of the lnwire.Message interface.
112
func (n *NodeAnnouncement2) Decode(r io.Reader, _ uint32) error {
101✔
113
        var (
101✔
114
                color = tlv.ZeroRecordT[tlv.TlvType1, Color]()
101✔
115
                alias = tlv.ZeroRecordT[tlv.TlvType3, []byte]()
101✔
116
                ipv4  = tlv.ZeroRecordT[tlv.TlvType5, IPV4Addrs]()
101✔
117
                ipv6  = tlv.ZeroRecordT[tlv.TlvType7, IPV6Addrs]()
101✔
118
                torV3 = tlv.ZeroRecordT[tlv.TlvType9, TorV3Addrs]()
101✔
119
                dns   = tlv.ZeroRecordT[tlv.TlvType11, DNSAddress]()
101✔
120
        )
101✔
121
        stream, err := tlv.NewStream(ProduceRecordsSorted(
101✔
122
                &n.Features,
101✔
123
                &n.BlockHeight,
101✔
124
                &n.NodeID,
101✔
125
                &n.Signature,
101✔
126
                &alias,
101✔
127
                &color,
101✔
128
                &ipv4,
101✔
129
                &ipv6,
101✔
130
                &torV3,
101✔
131
                &dns,
101✔
132
        )...)
101✔
133
        if err != nil {
101✔
NEW
134
                return err
×
NEW
135
        }
×
136
        n.Signature.Val.ForceSchnorr()
101✔
137

101✔
138
        typeMap, err := stream.DecodeWithParsedTypesP2P(r)
101✔
139
        if err != nil {
101✔
NEW
140
                return err
×
NEW
141
        }
×
142

143
        if _, ok := typeMap[n.Alias.TlvType()]; ok {
149✔
144
                n.Alias = tlv.SomeRecordT(alias)
48✔
145
        }
48✔
146

147
        if _, ok := typeMap[n.Color.TlvType()]; ok {
153✔
148
                n.Color = tlv.SomeRecordT(color)
52✔
149
        }
52✔
150

151
        if _, ok := typeMap[n.IPV4Addrs.TlvType()]; ok {
156✔
152
                n.IPV4Addrs = tlv.SomeRecordT(ipv4)
55✔
153
        }
55✔
154

155
        if _, ok := typeMap[n.IPV6Addrs.TlvType()]; ok {
151✔
156
                n.IPV6Addrs = tlv.SomeRecordT(ipv6)
50✔
157
        }
50✔
158

159
        if _, ok := typeMap[n.TorV3Addrs.TlvType()]; ok {
149✔
160
                n.TorV3Addrs = tlv.SomeRecordT(torV3)
48✔
161
        }
48✔
162

163
        if _, ok := typeMap[n.DNSHostName.TlvType()]; ok {
155✔
164
                n.DNSHostName = tlv.SomeRecordT(dns)
54✔
165
        }
54✔
166

167
        n.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
101✔
168

101✔
169
        return nil
101✔
170
}
171

172
// Encode serializes the target ChannelUpdate2 into the passed io.Writer
173
// observing the protocol version specified.
174
//
175
// This is part of the lnwire.Message interface.
176
func (n *NodeAnnouncement2) Encode(w *bytes.Buffer, _ uint32) error {
101✔
177
        return EncodePureTLVMessage(n, w)
101✔
178
}
101✔
179

180
// MsgType returns the integer uniquely identifying this message type on the
181
// wire.
182
//
183
// This is part of the lnwire.Message interface.
184
func (n *NodeAnnouncement2) MsgType() MessageType {
100✔
185
        return MsgNodeAnnouncement2
100✔
186
}
100✔
187

188
// A compile-time check to ensure NodeAnnouncement2 implements the Message
189
// interface.
190
var _ Message = (*NodeAnnouncement2)(nil)
191

192
// A compile-time check to ensure NodeAnnouncement2 implements the
193
// PureTLVMessage interface.
194
var _ PureTLVMessage = (*NodeAnnouncement2)(nil)
195

196
type Color color.RGBA
197

198
func (c *Color) Record() tlv.Record {
153✔
199
        return tlv.MakeStaticRecord(0, c, 3, rgbEncoder, rgbDecoder)
153✔
200
}
153✔
201

202
func rgbEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
52✔
203
        if v, ok := val.(*Color); ok {
104✔
204
                buf := bytes.NewBuffer(nil)
52✔
205
                err := WriteColorRGBA(buf, color.RGBA(*v))
52✔
206
                if err != nil {
52✔
NEW
207
                        return err
×
NEW
208
                }
×
209
                _, err = w.Write(buf.Bytes())
52✔
210

52✔
211
                return err
52✔
212
        }
213

NEW
214
        return tlv.NewTypeForEncodingErr(val, "Color")
×
215
}
216

217
func rgbDecoder(r io.Reader, val interface{}, _ *[8]byte, l uint64) error {
52✔
218
        if v, ok := val.(*Color); ok {
104✔
219
                return ReadElements(r, &v.R, &v.G, &v.B)
52✔
220
        }
52✔
221

NEW
222
        return tlv.NewTypeForDecodingErr(val, "Color", l, 3)
×
223
}
224

225
// ipv4AddrEncodedSize is the number of bytes required to encode a single ipv4
226
// address. Four bytes are used to encode the IP address and two bytes for the
227
// port number.
228
const ipv4AddrEncodedSize = 4 + 2
229

230
// IPV4Addrs is a list of ipv4 addresses that can be encoded as a TLV record.
231
type IPV4Addrs []*net.TCPAddr
232

233
// Record returns a Record that can be used to encode/decode a IPV4Addrs
234
// to/from a TLV stream.
235
func (a *IPV4Addrs) Record() tlv.Record {
156✔
236
        return tlv.MakeDynamicRecord(
156✔
237
                0, a, a.EncodedSize, ipv4AddrsEncoder, ipv4AddrsDecoder,
156✔
238
        )
156✔
239
}
156✔
240

241
// EncodedSize returns the number of bytes required to encode an IPV4Addrs
242
// variable.
243
func (a *IPV4Addrs) EncodedSize() uint64 {
55✔
244
        return uint64(len(*a) * ipv4AddrEncodedSize)
55✔
245
}
55✔
246

247
func ipv4AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
55✔
248
        if v, ok := val.(*IPV4Addrs); ok {
110✔
249
                for _, ip := range *v {
111✔
250
                        _, err := w.Write(ip.IP.To4())
56✔
251
                        if err != nil {
56✔
NEW
252
                                return err
×
NEW
253
                        }
×
254
                        var port [2]byte
56✔
255
                        binary.BigEndian.PutUint16(port[:], uint16(ip.Port))
56✔
256
                        _, err = w.Write(port[:])
56✔
257
                        if err != nil {
56✔
NEW
258
                                return err
×
NEW
259
                        }
×
260
                }
261
                return nil
55✔
262
        }
263

NEW
264
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV4Addrs")
×
265
}
266

267
func ipv4AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte,
268
        l uint64) error {
55✔
269

55✔
270
        if v, ok := val.(*IPV4Addrs); ok {
110✔
271
                if l%(ipv4AddrEncodedSize) != 0 {
55✔
NEW
272
                        return fmt.Errorf("invalid ipv4 list encoding")
×
NEW
273
                }
×
274
                var (
55✔
275
                        numAddrs = int(l / ipv4AddrEncodedSize)
55✔
276
                        addrs    = make([]*net.TCPAddr, 0, numAddrs)
55✔
277
                        ip       [4]byte
55✔
278
                        port     [2]byte
55✔
279
                )
55✔
280
                for len(addrs) < numAddrs {
111✔
281
                        _, err := r.Read(ip[:])
56✔
282
                        if err != nil {
56✔
NEW
283
                                return err
×
NEW
284
                        }
×
285
                        _, err = r.Read(port[:])
56✔
286
                        if err != nil {
56✔
NEW
287
                                return err
×
NEW
288
                        }
×
289
                        addrs = append(addrs, &net.TCPAddr{
56✔
290
                                IP:   ip[:],
56✔
291
                                Port: int(binary.BigEndian.Uint16(port[:])),
56✔
292
                        })
56✔
293
                }
294
                *v = addrs
55✔
295

55✔
296
                return nil
55✔
297
        }
298

NEW
299
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV4Addrs")
×
300
}
301

302
// IPV6Addrs is a list of ipv6 addresses that can be encoded as a TLV record.
303
type IPV6Addrs []*net.TCPAddr
304

305
// Record returns a Record that can be used to encode/decode a IPV4Addrs
306
// to/from a TLV stream.
307
func (a *IPV6Addrs) Record() tlv.Record {
151✔
308
        return tlv.MakeDynamicRecord(
151✔
309
                0, a, a.EncodedSize, ipv6AddrsEncoder, ipv6AddrsDecoder,
151✔
310
        )
151✔
311
}
151✔
312

313
// ipv6AddrEncodedSize is the number of bytes required to encode a single ipv6
314
// address. Sixteen bytes are used to encode the IP address and two bytes for
315
// the port number.
316
const ipv6AddrEncodedSize = 16 + 2
317

318
// EncodedSize returns the number of bytes required to encode an IPV6Addrs
319
// variable.
320
func (a *IPV6Addrs) EncodedSize() uint64 {
50✔
321
        return uint64(len(*a) * ipv6AddrEncodedSize)
50✔
322
}
50✔
323

324
func ipv6AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
50✔
325
        if v, ok := val.(*IPV6Addrs); ok {
100✔
326
                for _, ip := range *v {
100✔
327
                        _, err := w.Write(ip.IP.To16())
50✔
328
                        if err != nil {
50✔
NEW
329
                                return err
×
NEW
330
                        }
×
331
                        var port [2]byte
50✔
332
                        binary.BigEndian.PutUint16(port[:], uint16(ip.Port))
50✔
333
                        _, err = w.Write(port[:])
50✔
334
                        if err != nil {
50✔
NEW
335
                                return err
×
NEW
336
                        }
×
337
                }
338
                return nil
50✔
339
        }
340

NEW
341
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs")
×
342
}
343

344
func ipv6AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte,
345
        l uint64) error {
50✔
346
        if v, ok := val.(*IPV6Addrs); ok {
100✔
347
                if l%(ipv6AddrEncodedSize) != 0 {
50✔
NEW
348
                        return fmt.Errorf("invalid ipv6 list encoding")
×
NEW
349
                }
×
350
                var (
50✔
351
                        numAddrs = int(l / ipv6AddrEncodedSize)
50✔
352
                        addrs    = make([]*net.TCPAddr, 0, numAddrs)
50✔
353
                        ip       [16]byte
50✔
354
                        port     [2]byte
50✔
355
                )
50✔
356
                for len(addrs) < numAddrs {
100✔
357
                        _, err := r.Read(ip[:])
50✔
358
                        if err != nil {
50✔
NEW
359
                                return err
×
NEW
360
                        }
×
361
                        _, err = r.Read(port[:])
50✔
362
                        if err != nil {
50✔
NEW
363
                                return err
×
NEW
364
                        }
×
365
                        addrs = append(addrs, &net.TCPAddr{
50✔
366
                                IP:   ip[:],
50✔
367
                                Port: int(binary.BigEndian.Uint16(port[:])),
50✔
368
                        })
50✔
369
                }
370
                *v = addrs
50✔
371
                return nil
50✔
372
        }
373

NEW
374
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs")
×
375
}
376

377
// TorV3Addrs is a list of tor v3 addresses that can be encoded as a TLV record.
378
type TorV3Addrs []*tor.OnionAddr
379

380
// torV3AddrEncodedSize is the number of bytes required to encode a single tor
381
// v3 address.
382
const torV3AddrEncodedSize = tor.V3DecodedLen + 2
383

384
// EncodedSize returns the number of bytes required to encode an TorV3Addrs
385
// variable.
386
func (a *TorV3Addrs) EncodedSize() uint64 {
48✔
387
        return uint64(len(*a) * torV3AddrEncodedSize)
48✔
388
}
48✔
389

390
// Record returns a Record that can be used to encode/decode a IPV4Addrs
391
// to/from a TLV stream.
392
func (a *TorV3Addrs) Record() tlv.Record {
149✔
393
        return tlv.MakeDynamicRecord(
149✔
394
                0, a, a.EncodedSize, torV3AddrsEncoder, torV3AddrsDecoder,
149✔
395
        )
149✔
396
}
149✔
397

398
func torV3AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
48✔
399
        if v, ok := val.(*TorV3Addrs); ok {
96✔
400
                for _, addr := range *v {
96✔
401
                        encodedHostLen := tor.V3Len - tor.OnionSuffixLen
48✔
402
                        host, err := tor.Base32Encoding.DecodeString(
48✔
403
                                addr.OnionService[:encodedHostLen],
48✔
404
                        )
48✔
405
                        if err != nil {
48✔
NEW
406
                                return err
×
NEW
407
                        }
×
408
                        if len(host) != tor.V3DecodedLen {
48✔
NEW
409
                                return fmt.Errorf("expected a tor v3 host "+
×
NEW
410
                                        "length of %d, got: %d",
×
NEW
411
                                        tor.V2DecodedLen, len(host))
×
NEW
412
                        }
×
413
                        if _, err = w.Write(host); err != nil {
48✔
NEW
414
                                return err
×
NEW
415
                        }
×
416
                        var port [2]byte
48✔
417
                        binary.BigEndian.PutUint16(port[:], uint16(addr.Port))
48✔
418
                        if _, err = w.Write(port[:]); err != nil {
48✔
NEW
419
                                return err
×
NEW
420
                        }
×
421
                }
422
                return nil
48✔
423
        }
424

NEW
425
        return tlv.NewTypeForEncodingErr(val, "lnwire.TorV3Addrs")
×
426
}
427

428
func torV3AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte,
429
        l uint64) error {
48✔
430

48✔
431
        if v, ok := val.(*TorV3Addrs); ok {
96✔
432
                if l%torV3AddrEncodedSize != 0 {
48✔
NEW
433
                        return fmt.Errorf("invalid tor v3 list encoding")
×
NEW
434
                }
×
435
                var (
48✔
436
                        numAddrs = int(l / torV3AddrEncodedSize)
48✔
437
                        addrs    = make([]*tor.OnionAddr, 0, numAddrs)
48✔
438
                        ip       [tor.V3DecodedLen]byte
48✔
439
                        p        [2]byte
48✔
440
                )
48✔
441
                for len(addrs) < numAddrs {
96✔
442
                        _, err := r.Read(ip[:])
48✔
443
                        if err != nil {
48✔
NEW
444
                                return err
×
NEW
445
                        }
×
446
                        _, err = r.Read(p[:])
48✔
447
                        if err != nil {
48✔
NEW
448
                                return err
×
NEW
449
                        }
×
450
                        onionService := tor.Base32Encoding.EncodeToString(ip[:])
48✔
451
                        onionService += tor.OnionSuffix
48✔
452
                        port := int(binary.BigEndian.Uint16(p[:]))
48✔
453
                        addrs = append(addrs, &tor.OnionAddr{
48✔
454
                                OnionService: onionService,
48✔
455
                                Port:         port,
48✔
456
                        })
48✔
457
                }
458
                *v = addrs
48✔
459
                return nil
48✔
460
        }
461

NEW
462
        return tlv.NewTypeForEncodingErr(val, "lnwire.TorV3Addrs")
×
463
}
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