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

lightningnetwork / lnd / 13086553769

01 Feb 2025 07:39AM UTC coverage: 58.822% (+0.01%) from 58.808%
13086553769

Pull #9175

github

ellemouton
lnwire: add NodeAnnouncement2
Pull Request #9175: lnwire+netann: update structure of g175 messages to be pure TLV

414 of 581 new or added lines in 13 files covered. (71.26%)

87 existing lines in 23 files now uncovered.

136444 of 231959 relevant lines covered (58.82%)

19261.9 hits per line

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

81.47
/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
        // Signature is used to validate the announced data and prove the
51
        // ownership of node id.
52
        Signature tlv.RecordT[tlv.TlvType160, Sig]
53

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

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

100✔
73
        n.Color.WhenSome(func(r tlv.RecordT[tlv.TlvType1, Color]) {
154✔
74
                recordProducers = append(recordProducers, &r)
54✔
75
        })
54✔
76

77
        n.Alias.WhenSome(func(a tlv.RecordT[tlv.TlvType3, []byte]) {
100✔
NEW
78
                recordProducers = append(recordProducers, &a)
×
NEW
79
        })
×
80

81
        n.IPV4Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType5, IPV4Addrs]) {
152✔
82
                recordProducers = append(recordProducers, &r)
52✔
83
        })
52✔
84

85
        n.IPV6Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType7, IPV6Addrs]) {
141✔
86
                recordProducers = append(recordProducers, &r)
41✔
87
        })
41✔
88

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

93
        recordProducers = append(recordProducers, RecordsAsProducers(
100✔
94
                tlv.MapToRecords(n.ExtraSignedFields),
100✔
95
        )...)
100✔
96

100✔
97
        return ProduceRecordsSorted(recordProducers...)
100✔
98
}
99

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

100✔
128
        typeMap, err := stream.DecodeWithParsedTypesP2P(r)
100✔
129
        if err != nil {
100✔
NEW
130
                return err
×
NEW
131
        }
×
132

133
        if _, ok := typeMap[n.Alias.TlvType()]; ok {
100✔
NEW
134
                n.Alias = tlv.SomeRecordT(alias)
×
NEW
135
        }
×
136

137
        if _, ok := typeMap[n.Color.TlvType()]; ok {
154✔
138
                n.Color = tlv.SomeRecordT(color)
54✔
139
        }
54✔
140

141
        if _, ok := typeMap[n.IPV4Addrs.TlvType()]; ok {
152✔
142
                n.IPV4Addrs = tlv.SomeRecordT(ipv4)
52✔
143
        }
52✔
144

145
        if _, ok := typeMap[n.IPV6Addrs.TlvType()]; ok {
141✔
146
                n.IPV6Addrs = tlv.SomeRecordT(ipv6)
41✔
147
        }
41✔
148

149
        if _, ok := typeMap[n.TorV3Addrs.TlvType()]; ok {
151✔
150
                n.TorV3Addrs = tlv.SomeRecordT(torV3)
51✔
151
        }
51✔
152

153
        n.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
100✔
154

100✔
155
        return nil
100✔
156
}
157

158
// Encode serializes the target ChannelUpdate2 into the passed io.Writer
159
// observing the protocol version specified.
160
//
161
// This is part of the lnwire.Message interface.
162
func (n *NodeAnnouncement2) Encode(w *bytes.Buffer, _ uint32) error {
100✔
163
        return EncodePureTLVMessage(n, w)
100✔
164
}
100✔
165

166
// MsgType returns the integer uniquely identifying this message type on the
167
// wire.
168
//
169
// This is part of the lnwire.Message interface.
170
func (n *NodeAnnouncement2) MsgType() MessageType {
100✔
171
        return MsgNodeAnnouncement2
100✔
172
}
100✔
173

174
// A compile-time check to ensure NodeAnnouncement2 implements the Message
175
// interface.
176
var _ Message = (*NodeAnnouncement2)(nil)
177

178
// A compile-time check to ensure NodeAnnouncement2 implements the
179
// PureTLVMessage interface.
180
var _ PureTLVMessage = (*NodeAnnouncement2)(nil)
181

182
type Color color.RGBA
183

184
func (c *Color) Record() tlv.Record {
154✔
185
        return tlv.MakeStaticRecord(0, c, 3, rgbEncoder, rgbDecoder)
154✔
186
}
154✔
187

188
func rgbEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
54✔
189
        if v, ok := val.(*Color); ok {
108✔
190
                buf := bytes.NewBuffer(nil)
54✔
191
                err := WriteColorRGBA(buf, color.RGBA(*v))
54✔
192
                if err != nil {
54✔
NEW
193
                        return err
×
NEW
194
                }
×
195
                _, err = w.Write(buf.Bytes())
54✔
196

54✔
197
                return err
54✔
198
        }
199

NEW
200
        return tlv.NewTypeForEncodingErr(val, "Color")
×
201
}
202

203
func rgbDecoder(r io.Reader, val interface{}, _ *[8]byte, l uint64) error {
54✔
204
        if v, ok := val.(*Color); ok {
108✔
205
                return ReadElements(r, &v.R, &v.G, &v.B)
54✔
206
        }
54✔
207

NEW
208
        return tlv.NewTypeForDecodingErr(val, "Color", l, 3)
×
209
}
210

211
// ipv4AddrEncodedSize is the number of bytes required to encode a single ipv4
212
// address. Four bytes are used to encode the IP address and two bytes for the
213
// port number.
214
const ipv4AddrEncodedSize = 4 + 2
215

216
// IPV4Addrs is a list of ipv4 addresses that can be encoded as a TLV record.
217
type IPV4Addrs []*net.TCPAddr
218

219
// Record returns a Record that can be used to encode/decode a IPV4Addrs
220
// to/from a TLV stream.
221
func (a *IPV4Addrs) Record() tlv.Record {
152✔
222
        return tlv.MakeDynamicRecord(
152✔
223
                0, a, a.EncodedSize, ipv4AddrsEncoder, ipv4AddrsDecoder,
152✔
224
        )
152✔
225
}
152✔
226

227
// EncodedSize returns the number of bytes required to encode an IPV4Addrs
228
// variable.
229
func (a *IPV4Addrs) EncodedSize() uint64 {
52✔
230
        return uint64(len(*a) * ipv4AddrEncodedSize)
52✔
231
}
52✔
232

233
func ipv4AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
52✔
234
        if v, ok := val.(*IPV4Addrs); ok {
104✔
235
                for _, ip := range *v {
104✔
236
                        _, err := w.Write(ip.IP.To4())
52✔
237
                        if err != nil {
52✔
NEW
238
                                return err
×
NEW
239
                        }
×
240
                        var port [2]byte
52✔
241
                        binary.BigEndian.PutUint16(port[:], uint16(ip.Port))
52✔
242
                        _, err = w.Write(port[:])
52✔
243

52✔
244
                        return err
52✔
245
                }
246
        }
247

NEW
248
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV4Addrs")
×
249
}
250

251
func ipv4AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte,
252
        l uint64) error {
52✔
253

52✔
254
        if v, ok := val.(*IPV4Addrs); ok {
104✔
255
                if l%(ipv4AddrEncodedSize) != 0 {
52✔
NEW
256
                        return fmt.Errorf("invalid ipv4 list encoding")
×
NEW
257
                }
×
258
                var (
52✔
259
                        numAddrs = int(l / ipv4AddrEncodedSize)
52✔
260
                        addrs    = make([]*net.TCPAddr, 0, numAddrs)
52✔
261
                        ip       [4]byte
52✔
262
                        port     [2]byte
52✔
263
                )
52✔
264
                for len(addrs) < numAddrs {
104✔
265
                        _, err := r.Read(ip[:])
52✔
266
                        if err != nil {
52✔
NEW
267
                                return err
×
NEW
268
                        }
×
269
                        _, err = r.Read(port[:])
52✔
270
                        if err != nil {
52✔
NEW
271
                                return err
×
NEW
272
                        }
×
273
                        addrs = append(addrs, &net.TCPAddr{
52✔
274
                                IP:   ip[:],
52✔
275
                                Port: int(binary.BigEndian.Uint16(port[:])),
52✔
276
                        })
52✔
277
                }
278
                *v = addrs
52✔
279

52✔
280
                return nil
52✔
281
        }
282

NEW
283
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV4Addrs")
×
284
}
285

286
// IPV6Addrs is a list of ipv6 addresses that can be encoded as a TLV record.
287
type IPV6Addrs []*net.TCPAddr
288

289
// Record returns a Record that can be used to encode/decode a IPV4Addrs
290
// to/from a TLV stream.
291
func (a *IPV6Addrs) Record() tlv.Record {
141✔
292
        return tlv.MakeDynamicRecord(
141✔
293
                0, a, a.EncodedSize, ipv6AddrsEncoder, ipv6AddrsDecoder,
141✔
294
        )
141✔
295
}
141✔
296

297
// ipv6AddrEncodedSize is the number of bytes required to encode a single ipv6
298
// address. Sixteen bytes are used to encode the IP address and two bytes for
299
// the port number.
300
const ipv6AddrEncodedSize = 16 + 2
301

302
// EncodedSize returns the number of bytes required to encode an IPV6Addrs
303
// variable.
304
func (a *IPV6Addrs) EncodedSize() uint64 {
41✔
305
        return uint64(len(*a) * ipv6AddrEncodedSize)
41✔
306
}
41✔
307

308
func ipv6AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
41✔
309
        if v, ok := val.(*IPV6Addrs); ok {
82✔
310
                for _, ip := range *v {
82✔
311
                        _, err := w.Write(ip.IP.To16())
41✔
312
                        if err != nil {
41✔
NEW
313
                                return err
×
NEW
314
                        }
×
315
                        var port [2]byte
41✔
316
                        binary.BigEndian.PutUint16(port[:], uint16(ip.Port))
41✔
317
                        _, err = w.Write(port[:])
41✔
318

41✔
319
                        return err
41✔
320
                }
321
        }
322

NEW
323
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs")
×
324
}
325

326
func ipv6AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte,
327
        l uint64) error {
41✔
328
        if v, ok := val.(*IPV6Addrs); ok {
82✔
329
                if l%(ipv6AddrEncodedSize) != 0 {
41✔
NEW
330
                        return fmt.Errorf("invalid ipv6 list encoding")
×
NEW
331
                }
×
332
                var (
41✔
333
                        numAddrs = int(l / ipv6AddrEncodedSize)
41✔
334
                        addrs    = make([]*net.TCPAddr, 0, numAddrs)
41✔
335
                        ip       [16]byte
41✔
336
                        port     [2]byte
41✔
337
                )
41✔
338
                for len(addrs) < numAddrs {
82✔
339
                        _, err := r.Read(ip[:])
41✔
340
                        if err != nil {
41✔
NEW
341
                                return err
×
NEW
342
                        }
×
343
                        _, err = r.Read(port[:])
41✔
344
                        if err != nil {
41✔
NEW
345
                                return err
×
NEW
346
                        }
×
347
                        addrs = append(addrs, &net.TCPAddr{
41✔
348
                                IP:   ip[:],
41✔
349
                                Port: int(binary.BigEndian.Uint16(port[:])),
41✔
350
                        })
41✔
351
                }
352
                *v = addrs
41✔
353
                return nil
41✔
354
        }
355

NEW
356
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs")
×
357
}
358

359
// TorV3Addrs is a list of tor v3 addresses that can be encoded as a TLV record.
360
type TorV3Addrs []*tor.OnionAddr
361

362
// torV3AddrEncodedSize is the number of bytes required to encode a single tor
363
// v3 address.
364
const torV3AddrEncodedSize = tor.V3DecodedLen + 2
365

366
// EncodedSize returns the number of bytes required to encode an TorV3Addrs
367
// variable.
368
func (a *TorV3Addrs) EncodedSize() uint64 {
51✔
369
        return uint64(len(*a) * torV3AddrEncodedSize)
51✔
370
}
51✔
371

372
// Record returns a Record that can be used to encode/decode a IPV4Addrs
373
// to/from a TLV stream.
374
func (a *TorV3Addrs) Record() tlv.Record {
151✔
375
        return tlv.MakeDynamicRecord(
151✔
376
                0, a, a.EncodedSize, torV3AddrsEncoder, torV3AddrsDecoder,
151✔
377
        )
151✔
378
}
151✔
379

380
func torV3AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
51✔
381
        if v, ok := val.(*TorV3Addrs); ok {
102✔
382
                for _, addr := range *v {
102✔
383
                        encodedHostLen := tor.V3Len - tor.OnionSuffixLen
51✔
384
                        host, err := tor.Base32Encoding.DecodeString(
51✔
385
                                addr.OnionService[:encodedHostLen],
51✔
386
                        )
51✔
387
                        if err != nil {
51✔
NEW
388
                                return err
×
NEW
389
                        }
×
390
                        if len(host) != tor.V3DecodedLen {
51✔
NEW
391
                                return fmt.Errorf("expected a tor v3 host "+
×
NEW
392
                                        "length of %d, got: %d",
×
NEW
393
                                        tor.V2DecodedLen, len(host))
×
NEW
394
                        }
×
395
                        if _, err = w.Write(host); err != nil {
51✔
NEW
396
                                return err
×
NEW
397
                        }
×
398
                        var port [2]byte
51✔
399
                        binary.BigEndian.PutUint16(port[:], uint16(addr.Port))
51✔
400
                        _, err = w.Write(port[:])
51✔
401
                        return err
51✔
402
                }
403
        }
404

NEW
405
        return tlv.NewTypeForEncodingErr(val, "lnwire.TorV3Addrs")
×
406
}
407

408
func torV3AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte,
409
        l uint64) error {
51✔
410

51✔
411
        if v, ok := val.(*TorV3Addrs); ok {
102✔
412
                if l%torV3AddrEncodedSize != 0 {
51✔
NEW
413
                        return fmt.Errorf("invalid tor v3 list encoding")
×
NEW
414
                }
×
415
                var (
51✔
416
                        numAddrs = int(l / torV3AddrEncodedSize)
51✔
417
                        addrs    = make([]*tor.OnionAddr, 0, numAddrs)
51✔
418
                        ip       [tor.V3DecodedLen]byte
51✔
419
                        p        [2]byte
51✔
420
                )
51✔
421
                for len(addrs) < numAddrs {
102✔
422
                        _, err := r.Read(ip[:])
51✔
423
                        if err != nil {
51✔
NEW
424
                                return err
×
NEW
425
                        }
×
426
                        _, err = r.Read(p[:])
51✔
427
                        if err != nil {
51✔
NEW
428
                                return err
×
NEW
429
                        }
×
430
                        onionService := tor.Base32Encoding.EncodeToString(ip[:])
51✔
431
                        onionService += tor.OnionSuffix
51✔
432
                        port := int(binary.BigEndian.Uint16(p[:]))
51✔
433
                        addrs = append(addrs, &tor.OnionAddr{
51✔
434
                                OnionService: onionService,
51✔
435
                                Port:         port,
51✔
436
                        })
51✔
437
                }
438
                *v = addrs
51✔
439
                return nil
51✔
440
        }
441

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