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

lightningnetwork / lnd / 12338043150

15 Dec 2024 10:22AM UTC coverage: 58.62% (-0.02%) from 58.636%
12338043150

Pull #9175

github

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

408 of 574 new or added lines in 11 files covered. (71.08%)

150 existing lines in 25 files now uncovered.

134667 of 229729 relevant lines covered (58.62%)

19281.2 hits per line

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

81.25
/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]) {
151✔
74
                recordProducers = append(recordProducers, &r)
51✔
75
        })
51✔
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]) {
153✔
82
                recordProducers = append(recordProducers, &r)
53✔
83
        })
53✔
84

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

89
        n.TorV3Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType9, TorV3Addrs]) {
143✔
90
                recordProducers = append(recordProducers, &r)
43✔
91
        })
43✔
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 {
151✔
138
                n.Color = tlv.SomeRecordT(color)
51✔
139
        }
51✔
140

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

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

149
        if _, ok := typeMap[n.TorV3Addrs.TlvType()]; ok {
143✔
150
                n.TorV3Addrs = tlv.SomeRecordT(torV3)
43✔
151
        }
43✔
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 {
151✔
185
        return tlv.MakeStaticRecord(0, c, 3, rgbEncoder, rgbDecoder)
151✔
186
}
151✔
187

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

51✔
197
                return err
51✔
198
        }
199

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

203
func rgbDecoder(r io.Reader, val interface{}, _ *[8]byte, l uint64) error {
51✔
204
        if v, ok := val.(*Color); ok {
102✔
205
                return ReadElements(r, &v.R, &v.G, &v.B)
51✔
206
        }
51✔
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 {
153✔
222
        return tlv.MakeDynamicRecord(
153✔
223
                0, a, a.EncodedSize, ipv4AddrsEncoder, ipv4AddrsDecoder,
153✔
224
        )
153✔
225
}
153✔
226

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

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

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

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

NEW
280
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV4Addrs")
×
281
}
282

283
// IPV6Addrs is a list of ipv6 addresses that can be encoded as a TLV record.
284
type IPV6Addrs []*net.TCPAddr
285

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

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

299
// EncodedSize returns the number of bytes required to encode an IPV6Addrs
300
// variable.
301
func (a *IPV6Addrs) EncodedSize() uint64 {
49✔
302
        return uint64(len(*a) * ipv6AddrEncodedSize)
49✔
303
}
49✔
304

305
func ipv6AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
49✔
306
        if v, ok := val.(*IPV6Addrs); ok {
98✔
307

49✔
308
                for _, ip := range *v {
98✔
309
                        _, err := w.Write(ip.IP.To16())
49✔
310
                        if err != nil {
49✔
NEW
311
                                return err
×
NEW
312
                        }
×
313
                        var port [2]byte
49✔
314
                        binary.BigEndian.PutUint16(port[:], uint16(ip.Port))
49✔
315
                        _, err = w.Write(port[:])
49✔
316
                        return err
49✔
317
                }
318
        }
319

NEW
320
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs")
×
321
}
322

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

NEW
353
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs")
×
354
}
355

356
// TorV3Addrs is a list of tor v3 addresses that can be encoded as a TLV record.
357
type TorV3Addrs []*tor.OnionAddr
358

359
// torV3AddrEncodedSize is the number of bytes required to encode a single tor
360
// v3 address.
361
const torV3AddrEncodedSize = tor.V3DecodedLen + 2
362

363
// EncodedSize returns the number of bytes required to encode an TorV3Addrs
364
// variable.
365
func (a *TorV3Addrs) EncodedSize() uint64 {
43✔
366
        return uint64(len(*a) * torV3AddrEncodedSize)
43✔
367
}
43✔
368

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

377
func torV3AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
43✔
378
        if v, ok := val.(*TorV3Addrs); ok {
86✔
379

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

NEW
403
        return tlv.NewTypeForEncodingErr(val, "lnwire.TorV3Addrs")
×
404
}
405

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

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