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

lightningnetwork / lnd / 18197857992

02 Oct 2025 03:32PM UTC coverage: 66.622% (-0.02%) from 66.646%
18197857992

Pull #10267

github

web-flow
Merge 0d9bfccfe into 1c2ff4a7e
Pull Request #10267: [g175] multi: small G175 preparations

24 of 141 new or added lines in 12 files covered. (17.02%)

64 existing lines in 20 files now uncovered.

137216 of 205963 relevant lines covered (66.62%)

21302.01 hits per line

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

74.85
/lnwire/node_announcement_2.go
1
package lnwire
2

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

13
        "github.com/lightningnetwork/lnd/tlv"
14
        "github.com/lightningnetwork/lnd/tor"
15
)
16

17
// NodeAnnouncement2 message is used to announce the presence of a Lightning
18
// node and also to signal that the node is accepting incoming connections.
19
// Each NodeAnnouncement2 authenticating the advertised information within the
20
// announcement via a signature using the advertised node pubkey.
21
type NodeAnnouncement2 struct {
22
        // Features is the feature vector that encodes the features supported
23
        // by the target node.
24
        Features tlv.RecordT[tlv.TlvType0, RawFeatureVector]
25

26
        // Color is an optional field used to customize a node's appearance in
27
        // maps and graphs.
28
        Color tlv.OptionalRecordT[tlv.TlvType1, Color]
29

30
        // BlockHeight allows ordering in the case of multiple announcements. We
31
        // should ignore the message if block height is not greater than the
32
        // last-received. The block height must always be greater or equal to
33
        // the block height that the channel funding transaction was confirmed
34
        // in.
35
        BlockHeight tlv.RecordT[tlv.TlvType2, uint32]
36

37
        // Alias is used to customize their node's appearance in maps and
38
        // graphs.
39
        Alias tlv.OptionalRecordT[tlv.TlvType3, NodeAlias2]
40

41
        // NodeID is the public key of the node creating the announcement.
42
        NodeID tlv.RecordT[tlv.TlvType4, [33]byte]
43

44
        // IPV4Addrs is an optional list of ipv4 addresses that the node is
45
        // reachable at.
46
        IPV4Addrs tlv.OptionalRecordT[tlv.TlvType5, IPV4Addrs]
47

48
        // IPV6Addrs is an optional list of ipv6 addresses that the node is
49
        // reachable at.
50
        IPV6Addrs tlv.OptionalRecordT[tlv.TlvType7, IPV6Addrs]
51

52
        // TorV3Addrs is an optional list of tor v3 addresses that the node is
53
        // reachable at.
54
        TorV3Addrs tlv.OptionalRecordT[tlv.TlvType9, TorV3Addrs]
55

56
        // DNSHostName is an optional DNS hostname that the node is reachable
57
        // at.
58
        DNSHostName tlv.OptionalRecordT[tlv.TlvType11, DNSAddress]
59

60
        // Signature is used to validate the announced data and prove the
61
        // ownership of node id.
62
        Signature tlv.RecordT[tlv.TlvType160, Sig]
63

64
        // Any extra fields in the signed range that we do not yet know about,
65
        // but we need to keep them for signature validation and to produce a
66
        // valid message.
67
        ExtraSignedFields
68
}
69

70
// SerializedSize returns the serialized size of the message in bytes.
71
//
72
// This is part of the lnwire.SizeableMessage interface.
73
func (n *NodeAnnouncement2) SerializedSize() (uint32, error) {
×
74
        return MessageSerializedSize(n)
×
75
}
×
76

77
// AllRecords returns all the TLV records for the message. This will include all
78
// the records we know about along with any that we don't know about but that
79
// fall in the signed TLV range.
80
//
81
// NOTE: this is part of the PureTLVMessage interface.
82
func (n *NodeAnnouncement2) AllRecords() []tlv.Record {
101✔
83
        recordProducers := []tlv.RecordProducer{
101✔
84
                &n.Features,
101✔
85
                &n.BlockHeight,
101✔
86
                &n.NodeID,
101✔
87
                &n.Signature,
101✔
88
        }
101✔
89

101✔
90
        n.Color.WhenSome(func(r tlv.RecordT[tlv.TlvType1, Color]) {
145✔
91
                recordProducers = append(recordProducers, &r)
44✔
92
        })
44✔
93

94
        n.Alias.WhenSome(func(a tlv.RecordT[tlv.TlvType3, NodeAlias2]) {
149✔
95
                recordProducers = append(recordProducers, &a)
48✔
96
        })
48✔
97

98
        n.IPV4Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType5, IPV4Addrs]) {
151✔
99
                recordProducers = append(recordProducers, &r)
50✔
100
        })
50✔
101

102
        n.IPV6Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType7, IPV6Addrs]) {
152✔
103
                recordProducers = append(recordProducers, &r)
51✔
104
        })
51✔
105

106
        n.TorV3Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType9, TorV3Addrs]) {
150✔
107
                recordProducers = append(recordProducers, &r)
49✔
108
        })
49✔
109

110
        n.DNSHostName.WhenSome(func(r tlv.RecordT[tlv.TlvType11, DNSAddress]) {
157✔
111
                recordProducers = append(recordProducers, &r)
56✔
112
        })
56✔
113

114
        recordProducers = append(recordProducers, RecordsAsProducers(
101✔
115
                tlv.MapToRecords(n.ExtraSignedFields),
101✔
116
        )...)
101✔
117

101✔
118
        return ProduceRecordsSorted(recordProducers...)
101✔
119
}
120

121
// Decode deserializes a serialized NodeAnnouncement2 stored in the passed
122
// io.Reader observing the specified protocol version.
123
//
124
// This is part of the lnwire.Message interface.
125
func (n *NodeAnnouncement2) Decode(r io.Reader, _ uint32) error {
101✔
126
        var (
101✔
127
                color = tlv.ZeroRecordT[tlv.TlvType1, Color]()
101✔
128
                alias = tlv.ZeroRecordT[tlv.TlvType3, NodeAlias2]()
101✔
129
                ipv4  = tlv.ZeroRecordT[tlv.TlvType5, IPV4Addrs]()
101✔
130
                ipv6  = tlv.ZeroRecordT[tlv.TlvType7, IPV6Addrs]()
101✔
131
                torV3 = tlv.ZeroRecordT[tlv.TlvType9, TorV3Addrs]()
101✔
132
                dns   = tlv.ZeroRecordT[tlv.TlvType11, DNSAddress]()
101✔
133
        )
101✔
134

101✔
135
        stream, err := tlv.NewStream(ProduceRecordsSorted(
101✔
136
                &n.Features,
101✔
137
                &n.BlockHeight,
101✔
138
                &n.NodeID,
101✔
139
                &n.Signature,
101✔
140
                &alias,
101✔
141
                &color,
101✔
142
                &ipv4,
101✔
143
                &ipv6,
101✔
144
                &torV3,
101✔
145
                &dns,
101✔
146
        )...)
101✔
147
        if err != nil {
101✔
148
                return err
×
149
        }
×
150
        n.Signature.Val.ForceSchnorr()
101✔
151

101✔
152
        typeMap, err := stream.DecodeWithParsedTypesP2P(r)
101✔
153
        if err != nil {
101✔
154
                return err
×
155
        }
×
156

157
        if _, ok := typeMap[n.Alias.TlvType()]; ok {
149✔
158
                n.Alias = tlv.SomeRecordT(alias)
48✔
159
        }
48✔
160

161
        if _, ok := typeMap[n.Color.TlvType()]; ok {
145✔
162
                n.Color = tlv.SomeRecordT(color)
44✔
163
        }
44✔
164

165
        if _, ok := typeMap[n.IPV4Addrs.TlvType()]; ok {
151✔
166
                n.IPV4Addrs = tlv.SomeRecordT(ipv4)
50✔
167
        }
50✔
168

169
        if _, ok := typeMap[n.IPV6Addrs.TlvType()]; ok {
152✔
170
                n.IPV6Addrs = tlv.SomeRecordT(ipv6)
51✔
171
        }
51✔
172

173
        if _, ok := typeMap[n.TorV3Addrs.TlvType()]; ok {
150✔
174
                n.TorV3Addrs = tlv.SomeRecordT(torV3)
49✔
175
        }
49✔
176

177
        if _, ok := typeMap[n.DNSHostName.TlvType()]; ok {
157✔
178
                n.DNSHostName = tlv.SomeRecordT(dns)
56✔
179
        }
56✔
180

181
        n.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
101✔
182

101✔
183
        return nil
101✔
184
}
185

186
// Encode serializes the target NodeAnnouncement2 into the passed io.Writer
187
// observing the protocol version specified.
188
//
189
// This is part of the lnwire.Message interface.
190
func (n *NodeAnnouncement2) Encode(w *bytes.Buffer, _ uint32) error {
101✔
191
        return EncodePureTLVMessage(n, w)
101✔
192
}
101✔
193

194
// MsgType returns the integer uniquely identifying this message type on the
195
// wire.
196
//
197
// This is part of the lnwire.Message interface.
198
func (n *NodeAnnouncement2) MsgType() MessageType {
100✔
199
        return MsgNodeAnnouncement2
100✔
200
}
100✔
201

202
// NodePub returns the identity public key of the node.
203
//
204
// NOTE: part of the NodeAnnouncement interface.
NEW
205
func (n *NodeAnnouncement2) NodePub() [33]byte {
×
NEW
206
        return n.NodeID.Val
×
NEW
207
}
×
208

209
// NodeFeatures returns the set of features supported by the node.
210
//
211
// NOTE: part of the NodeAnnouncement interface.
NEW
212
func (n *NodeAnnouncement2) NodeFeatures() *FeatureVector {
×
NEW
213
        return NewFeatureVector(&n.Features.Val, Features)
×
NEW
214
}
×
215

216
// TimestampDesc returns a human-readable description of the timestamp of the
217
// announcement.
218
//
219
// NOTE: part of the NodeAnnouncement interface.
NEW
220
func (n *NodeAnnouncement2) TimestampDesc() string {
×
NEW
221
        return fmt.Sprintf("block_height=%d", n.BlockHeight.Val)
×
NEW
222
}
×
223

224
// GossipVersion returns the gossip version that this message is part of.
225
//
226
// NOTE: this is part of the GossipMessage interface.
NEW
227
func (n *NodeAnnouncement2) GossipVersion() GossipVersion {
×
NEW
228
        return GossipVersion2
×
NEW
229
}
×
230

231
// A compile-time check to ensure NodeAnnouncement2 implements the Message
232
// interface.
233
var _ Message = (*NodeAnnouncement2)(nil)
234

235
// A compile time check to ensure NodeAnnouncement2 implements the
236
// lnwire.NodeAnnouncement interface.
237
var _ NodeAnnouncement = (*NodeAnnouncement2)(nil)
238

239
// A compile-time check to ensure NodeAnnouncement2 implements the
240
// PureTLVMessage interface.
241
var _ PureTLVMessage = (*NodeAnnouncement2)(nil)
242

243
// A compile time check to ensure ChannelAnnouncement2 implements the
244
// lnwire.SizeableMessage interface.
245
var _ SizeableMessage = (*NodeAnnouncement2)(nil)
246

247
// NodeAlias2 represents a UTF-8 encoded node alias with a maximum length of 32
248
// bytes.
249
type NodeAlias2 []byte
250

251
// Record returns a TLV record for encoding/decoding NodeAlias2.
252
func (n *NodeAlias2) Record() tlv.Record {
149✔
253
        sizeFunc := func() uint64 {
197✔
254
                return uint64(len(*n))
48✔
255
        }
48✔
256

257
        return tlv.MakeDynamicRecord(
149✔
258
                0, n, sizeFunc, nodeAlias2Encoder, nodeAlias2Decoder,
149✔
259
        )
149✔
260
}
261

262
// ValidateNodeAlias2 validates that the node alias is valid UTF-8 and within
263
// the 32-byte limit.
264
func ValidateNodeAlias2(alias []byte) error {
96✔
265
        if len(alias) == 0 {
96✔
266
                return errors.New("node alias cannot be empty")
×
267
        }
×
268

269
        if len(alias) > 32 {
96✔
270
                return fmt.Errorf("node alias exceeds 32 bytes: length %d",
×
271
                        len(alias))
×
272
        }
×
273

274
        if !utf8.Valid(alias) {
96✔
275
                return errors.New("node alias contains invalid UTF-8")
×
276
        }
×
277

278
        return nil
96✔
279
}
280

281
// nodeAlias2Encoder encodes a NodeAlias2 as raw UTF-8 bytes.
282
func nodeAlias2Encoder(w io.Writer, val any, _ *[8]byte) error {
48✔
283
        if v, ok := val.(*NodeAlias2); ok {
96✔
284
                if err := ValidateNodeAlias2(*v); err != nil {
48✔
285
                        return err
×
286
                }
×
287

288
                _, err := w.Write(*v)
48✔
289

48✔
290
                return err
48✔
291
        }
292

293
        return tlv.NewTypeForEncodingErr(val, "NodeAlias2")
×
294
}
295

296
// nodeAlias2Decoder decodes raw bytes into a NodeAlias2.
297
func nodeAlias2Decoder(r io.Reader, val any, _ *[8]byte, l uint64) error {
48✔
298
        if v, ok := val.(*NodeAlias2); ok {
96✔
299
                if l > 32 {
48✔
300
                        return fmt.Errorf("node alias exceeds 32 bytes: %d", l)
×
301
                }
×
302

303
                aliasBytes := make([]byte, l)
48✔
304
                if _, err := io.ReadFull(r, aliasBytes); err != nil {
48✔
305
                        return err
×
306
                }
×
307

308
                if err := ValidateNodeAlias2(aliasBytes); err != nil {
48✔
309
                        return err
×
310
                }
×
311

312
                *v = aliasBytes
48✔
313

48✔
314
                return nil
48✔
315
        }
316

317
        return tlv.NewTypeForDecodingErr(val, "NodeAlias2", l, 0)
×
318
}
319

320
// Color is a custom type to represent a color.RGBA that can be encoded/decoded
321
// as a TLV record.
322
type Color color.RGBA
323

324
// Record returns a TLV record for encoding/decoding Color.
325
func (c *Color) Record() tlv.Record {
145✔
326
        return tlv.MakeStaticRecord(0, c, 3, rgbEncoder, rgbDecoder)
145✔
327
}
145✔
328

329
// rgbEncoder encodes a Color as RGB bytes.
330
func rgbEncoder(w io.Writer, val any, _ *[8]byte) error {
44✔
331
        if v, ok := val.(*Color); ok {
88✔
332
                buf := bytes.NewBuffer(nil)
44✔
333
                err := WriteColorRGBA(buf, color.RGBA(*v))
44✔
334
                if err != nil {
44✔
335
                        return err
×
336
                }
×
337
                _, err = w.Write(buf.Bytes())
44✔
338

44✔
339
                return err
44✔
340
        }
341

342
        return tlv.NewTypeForEncodingErr(val, "Color")
×
343
}
344

345
// rgbDecoder decodes RGB bytes into a Color.
346
func rgbDecoder(r io.Reader, val any, _ *[8]byte, l uint64) error {
44✔
347
        if v, ok := val.(*Color); ok {
88✔
348
                return ReadElements(r, &v.R, &v.G, &v.B)
44✔
349
        }
44✔
350

351
        return tlv.NewTypeForDecodingErr(val, "Color", l, 3)
×
352
}
353

354
// ipv4AddrEncodedSize is the number of bytes required to encode a single ipv4
355
// address. Four bytes are used to encode the IP address and two bytes for the
356
// port number.
357
const ipv4AddrEncodedSize = 4 + 2
358

359
// IPV4Addrs is a list of ipv4 addresses that can be encoded as a TLV record.
360
type IPV4Addrs []*net.TCPAddr
361

362
// Record returns a Record that can be used to encode/decode a IPV4Addrs
363
// to/from a TLV stream.
364
func (a *IPV4Addrs) Record() tlv.Record {
151✔
365
        return tlv.MakeDynamicRecord(
151✔
366
                0, a, a.encodedSize, ipv4AddrsEncoder, ipv4AddrsDecoder,
151✔
367
        )
151✔
368
}
151✔
369

370
// encodedSize returns the number of bytes required to encode an IPV4Addrs
371
// variable.
372
func (a *IPV4Addrs) encodedSize() uint64 {
50✔
373
        return uint64(len(*a) * ipv4AddrEncodedSize)
50✔
374
}
50✔
375

376
// ipv4AddrsEncoder encodes IPv4 addresses as TLV bytes.
377
func ipv4AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
50✔
378
        if v, ok := val.(*IPV4Addrs); ok {
100✔
379
                for _, ip := range *v {
101✔
380
                        _, err := w.Write(ip.IP.To4())
51✔
381
                        if err != nil {
51✔
382
                                return err
×
383
                        }
×
384
                        var port [2]byte
51✔
385
                        binary.BigEndian.PutUint16(port[:], uint16(ip.Port))
51✔
386
                        _, err = w.Write(port[:])
51✔
387
                        if err != nil {
51✔
388
                                return err
×
389
                        }
×
390
                }
391

392
                return nil
50✔
393
        }
394

395
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV4Addrs")
×
396
}
397

398
// ipv4AddrsDecoder decodes TLV bytes into IPv4 addresses.
399
func ipv4AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte,
400
        l uint64) error {
50✔
401

50✔
402
        if v, ok := val.(*IPV4Addrs); ok {
100✔
403
                if l%(ipv4AddrEncodedSize) != 0 {
50✔
404
                        return fmt.Errorf("invalid ipv4 list encoding")
×
405
                }
×
406
                var (
50✔
407
                        numAddrs = int(l / ipv4AddrEncodedSize)
50✔
408
                        addrs    = make([]*net.TCPAddr, 0, numAddrs)
50✔
409
                        ip       [4]byte
50✔
410
                        port     [2]byte
50✔
411
                )
50✔
412
                for len(addrs) < numAddrs {
101✔
413
                        _, err := r.Read(ip[:])
51✔
414
                        if err != nil {
51✔
415
                                return err
×
416
                        }
×
417
                        _, err = r.Read(port[:])
51✔
418
                        if err != nil {
51✔
419
                                return err
×
420
                        }
×
421
                        addrs = append(addrs, &net.TCPAddr{
51✔
422
                                IP:   ip[:],
51✔
423
                                Port: int(binary.BigEndian.Uint16(port[:])),
51✔
424
                        })
51✔
425
                }
426
                *v = addrs
50✔
427

50✔
428
                return nil
50✔
429
        }
430

431
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV4Addrs")
×
432
}
433

434
// IPV6Addrs is a list of ipv6 addresses that can be encoded as a TLV record.
435
type IPV6Addrs []*net.TCPAddr
436

437
// Record returns a Record that can be used to encode/decode a IPV4Addrs
438
// to/from a TLV stream.
439
func (a *IPV6Addrs) Record() tlv.Record {
152✔
440
        return tlv.MakeDynamicRecord(
152✔
441
                0, a, a.encodedSize, ipv6AddrsEncoder, ipv6AddrsDecoder,
152✔
442
        )
152✔
443
}
152✔
444

445
// ipv6AddrEncodedSize is the number of bytes required to encode a single ipv6
446
// address. Sixteen bytes are used to encode the IP address and two bytes for
447
// the port number.
448
const ipv6AddrEncodedSize = 16 + 2
449

450
// encodedSize returns the number of bytes required to encode an IPV6Addrs
451
// variable.
452
func (a *IPV6Addrs) encodedSize() uint64 {
51✔
453
        return uint64(len(*a) * ipv6AddrEncodedSize)
51✔
454
}
51✔
455

456
// ipv6AddrsEncoder encodes IPv6 addresses as TLV bytes.
457
func ipv6AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
51✔
458
        if v, ok := val.(*IPV6Addrs); ok {
102✔
459
                for _, ip := range *v {
102✔
460
                        _, err := w.Write(ip.IP.To16())
51✔
461
                        if err != nil {
51✔
462
                                return err
×
463
                        }
×
464
                        var port [2]byte
51✔
465
                        binary.BigEndian.PutUint16(port[:], uint16(ip.Port))
51✔
466
                        _, err = w.Write(port[:])
51✔
467
                        if err != nil {
51✔
468
                                return err
×
469
                        }
×
470
                }
471

472
                return nil
51✔
473
        }
474

475
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs")
×
476
}
477

478
// ipv6AddrsDecoder decodes TLV bytes into IPv6 addresses.
479
func ipv6AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte,
480
        l uint64) error {
51✔
481

51✔
482
        if v, ok := val.(*IPV6Addrs); ok {
102✔
483
                if l%(ipv6AddrEncodedSize) != 0 {
51✔
484
                        return fmt.Errorf("invalid ipv6 list encoding")
×
485
                }
×
486
                var (
51✔
487
                        numAddrs = int(l / ipv6AddrEncodedSize)
51✔
488
                        addrs    = make([]*net.TCPAddr, 0, numAddrs)
51✔
489
                        ip       [16]byte
51✔
490
                        port     [2]byte
51✔
491
                )
51✔
492
                for len(addrs) < numAddrs {
102✔
493
                        _, err := r.Read(ip[:])
51✔
494
                        if err != nil {
51✔
495
                                return err
×
496
                        }
×
497
                        _, err = r.Read(port[:])
51✔
498
                        if err != nil {
51✔
499
                                return err
×
500
                        }
×
501
                        addrs = append(addrs, &net.TCPAddr{
51✔
502
                                IP:   ip[:],
51✔
503
                                Port: int(binary.BigEndian.Uint16(port[:])),
51✔
504
                        })
51✔
505
                }
506
                *v = addrs
51✔
507

51✔
508
                return nil
51✔
509
        }
510

511
        return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs")
×
512
}
513

514
// TorV3Addrs is a list of tor v3 addresses that can be encoded as a TLV record.
515
type TorV3Addrs []*tor.OnionAddr
516

517
// torV3AddrEncodedSize is the number of bytes required to encode a single tor
518
// v3 address.
519
const torV3AddrEncodedSize = tor.V3DecodedLen + 2
520

521
// encodedSize returns the number of bytes required to encode an TorV3Addrs
522
// variable.
523
func (a *TorV3Addrs) encodedSize() uint64 {
49✔
524
        return uint64(len(*a) * torV3AddrEncodedSize)
49✔
525
}
49✔
526

527
// Record returns a Record that can be used to encode/decode a IPV4Addrs
528
// to/from a TLV stream.
529
func (a *TorV3Addrs) Record() tlv.Record {
150✔
530
        return tlv.MakeDynamicRecord(
150✔
531
                0, a, a.encodedSize, torV3AddrsEncoder, torV3AddrsDecoder,
150✔
532
        )
150✔
533
}
150✔
534

535
// torV3AddrsEncoder encodes Tor v3 addresses as TLV bytes.
536
func torV3AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
49✔
537
        if v, ok := val.(*TorV3Addrs); ok {
98✔
538
                for _, addr := range *v {
98✔
539
                        encodedHostLen := tor.V3Len - tor.OnionSuffixLen
49✔
540
                        host, err := tor.Base32Encoding.DecodeString(
49✔
541
                                addr.OnionService[:encodedHostLen],
49✔
542
                        )
49✔
543
                        if err != nil {
49✔
544
                                return err
×
545
                        }
×
546

547
                        if len(host) != tor.V3DecodedLen {
49✔
548
                                return fmt.Errorf("expected a tor v3 host "+
×
549
                                        "length of %d, got: %d",
×
550
                                        tor.V3DecodedLen, len(host))
×
551
                        }
×
552

553
                        if _, err = w.Write(host); err != nil {
49✔
554
                                return err
×
555
                        }
×
556

557
                        var port [2]byte
49✔
558
                        binary.BigEndian.PutUint16(port[:], uint16(addr.Port))
49✔
559
                        if _, err = w.Write(port[:]); err != nil {
49✔
560
                                return err
×
561
                        }
×
562
                }
563

564
                return nil
49✔
565
        }
566

567
        return tlv.NewTypeForEncodingErr(val, "lnwire.TorV3Addrs")
×
568
}
569

570
// torV3AddrsDecoder decodes TLV bytes into Tor v3 addresses.
571
func torV3AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte,
572
        l uint64) error {
49✔
573

49✔
574
        if v, ok := val.(*TorV3Addrs); ok {
98✔
575
                if l%torV3AddrEncodedSize != 0 {
49✔
576
                        return fmt.Errorf("invalid tor v3 list encoding")
×
577
                }
×
578
                var (
49✔
579
                        numAddrs = int(l / torV3AddrEncodedSize)
49✔
580
                        addrs    = make([]*tor.OnionAddr, 0, numAddrs)
49✔
581
                        ip       [tor.V3DecodedLen]byte
49✔
582
                        p        [2]byte
49✔
583
                )
49✔
584
                for len(addrs) < numAddrs {
98✔
585
                        _, err := r.Read(ip[:])
49✔
586
                        if err != nil {
49✔
587
                                return err
×
588
                        }
×
589
                        _, err = r.Read(p[:])
49✔
590
                        if err != nil {
49✔
591
                                return err
×
592
                        }
×
593
                        onionService := tor.Base32Encoding.EncodeToString(ip[:])
49✔
594
                        onionService += tor.OnionSuffix
49✔
595

49✔
596
                        if len(onionService) != tor.V3Len {
49✔
597
                                return fmt.Errorf("expected a tor v3 onion "+
×
598
                                        "service length of %d, got: %d",
×
599
                                        tor.V3Len, len(onionService))
×
600
                        }
×
601

602
                        port := int(binary.BigEndian.Uint16(p[:]))
49✔
603
                        addrs = append(addrs, &tor.OnionAddr{
49✔
604
                                OnionService: onionService,
49✔
605
                                Port:         port,
49✔
606
                        })
49✔
607
                }
608
                *v = addrs
49✔
609

49✔
610
                return nil
49✔
611
        }
612

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