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

lightningnetwork / lnd / 16982438758

15 Aug 2025 03:47AM UTC coverage: 66.748% (-0.03%) from 66.776%
16982438758

Pull #9455

github

web-flow
Merge 9a33d5e7b into 31fc55650
Pull Request #9455: [1/2] discovery+lnwire: add support for DNS host name in NodeAnnouncement msg

209 of 304 new or added lines in 8 files covered. (68.75%)

1268 existing lines in 30 files now uncovered.

136026 of 203789 relevant lines covered (66.75%)

21540.12 hits per line

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

69.54
/lnwire/lnwire.go
1
package lnwire
2

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

13
        "github.com/btcsuite/btcd/btcec/v2"
14
        "github.com/btcsuite/btcd/btcutil"
15
        "github.com/btcsuite/btcd/chaincfg/chainhash"
16
        "github.com/btcsuite/btcd/wire"
17
        "github.com/lightningnetwork/lnd/tor"
18
)
19

20
const (
21
        // MaxSliceLength is the maximum allowed length for any opaque byte
22
        // slices in the wire protocol.
23
        MaxSliceLength = 65535
24

25
        // MaxMsgBody is the largest payload any message is allowed to provide.
26
        // This is two less than the MaxSliceLength as each message has a 2
27
        // byte type that precedes the message body.
28
        MaxMsgBody = 65533
29
)
30

31
const (
32
        // tcp4AddrLen is the length of an IPv4 address
33
        // (4 bytes IP + 2 bytes port).
34
        tcp4AddrLen = 6
35

36
        // tcp6AddrLen is the length of an IPv6 address
37
        // (16 bytes IP + 2 bytes port).
38
        tcp6AddrLen = 18
39

40
        // v2OnionAddrLen is the length of a version 2 Tor onion service
41
        // address.
42
        v2OnionAddrLen = 12
43

44
        // v3OnionAddrLen is the length of a version 3 Tor onion service address
45
        // (35 bytes decoded onion + 2 bytes port).
46
        v3OnionAddrLen = 37
47

48
        // dnsAddrOverhead is the fixed overhead for a DNS address: 1 byte for
49
        // the hostname length and 2 bytes for the port.
50
        dnsAddrOverhead = 3
51
)
52

53
// PkScript is simple type definition which represents a raw serialized public
54
// key script.
55
type PkScript []byte
56

57
// addressType specifies the network protocol and version that should be used
58
// when connecting to a node at a particular address.
59
type addressType uint8
60

61
const (
62
        // noAddr denotes a blank address. An address of this type indicates
63
        // that a node doesn't have any advertised addresses.
64
        noAddr addressType = 0
65

66
        // tcp4Addr denotes an IPv4 TCP address.
67
        tcp4Addr addressType = 1
68

69
        // tcp6Addr denotes an IPv6 TCP address.
70
        tcp6Addr addressType = 2
71

72
        // v2OnionAddr denotes a version 2 Tor onion service address.
73
        v2OnionAddr addressType = 3
74

75
        // v3OnionAddr denotes a version 3 Tor (prop224) onion service address.
76
        v3OnionAddr addressType = 4
77

78
        // dnsAddr denotes a DNS address.
79
        dnsAddr addressType = 5
80
)
81

82
// WriteElement is a one-stop shop to write the big endian representation of
83
// any element which is to be serialized for the wire protocol.
84
//
85
// TODO(yy): rm this method once we finish dereferencing it from other
86
// packages.
87
func WriteElement(w *bytes.Buffer, element interface{}) error {
3,824✔
88
        switch e := element.(type) {
3,824✔
89
        case NodeAlias:
×
90
                if _, err := w.Write(e[:]); err != nil {
×
91
                        return err
×
92
                }
×
93

94
        case QueryEncoding:
×
95
                var b [1]byte
×
96
                b[0] = uint8(e)
×
97
                if _, err := w.Write(b[:]); err != nil {
×
98
                        return err
×
99
                }
×
100

101
        case uint8:
119✔
102
                var b [1]byte
119✔
103
                b[0] = e
119✔
104
                if _, err := w.Write(b[:]); err != nil {
119✔
105
                        return err
×
106
                }
×
107

108
        case FundingFlag:
×
109
                var b [1]byte
×
110
                b[0] = uint8(e)
×
111
                if _, err := w.Write(b[:]); err != nil {
×
112
                        return err
×
113
                }
×
114

115
        case uint16:
484✔
116
                var b [2]byte
484✔
117
                binary.BigEndian.PutUint16(b[:], e)
484✔
118
                if _, err := w.Write(b[:]); err != nil {
484✔
119
                        return err
×
120
                }
×
121

122
        case ChanUpdateMsgFlags:
×
123
                var b [1]byte
×
124
                b[0] = uint8(e)
×
125
                if _, err := w.Write(b[:]); err != nil {
×
126
                        return err
×
127
                }
×
128

129
        case ChanUpdateChanFlags:
×
130
                var b [1]byte
×
131
                b[0] = uint8(e)
×
132
                if _, err := w.Write(b[:]); err != nil {
×
133
                        return err
×
134
                }
×
135

136
        case MilliSatoshi:
×
137
                var b [8]byte
×
138
                binary.BigEndian.PutUint64(b[:], uint64(e))
×
139
                if _, err := w.Write(b[:]); err != nil {
×
140
                        return err
×
141
                }
×
142

143
        case btcutil.Amount:
110✔
144
                var b [8]byte
110✔
145
                binary.BigEndian.PutUint64(b[:], uint64(e))
110✔
146
                if _, err := w.Write(b[:]); err != nil {
110✔
147
                        return err
×
148
                }
×
149

150
        case uint32:
1,317✔
151
                var b [4]byte
1,317✔
152
                binary.BigEndian.PutUint32(b[:], e)
1,317✔
153
                if _, err := w.Write(b[:]); err != nil {
1,317✔
154
                        return err
×
155
                }
×
156

157
        case uint64:
49✔
158
                var b [8]byte
49✔
159
                binary.BigEndian.PutUint64(b[:], e)
49✔
160
                if _, err := w.Write(b[:]); err != nil {
49✔
161
                        return err
×
162
                }
×
163

164
        case *btcec.PublicKey:
645✔
165
                if e == nil {
645✔
166
                        return fmt.Errorf("cannot write nil pubkey")
×
167
                }
×
168

169
                var b [33]byte
645✔
170
                serializedPubkey := e.SerializeCompressed()
645✔
171
                copy(b[:], serializedPubkey)
645✔
172
                if _, err := w.Write(b[:]); err != nil {
645✔
173
                        return err
×
174
                }
×
175

176
        case []Sig:
×
177
                var b [2]byte
×
178
                numSigs := uint16(len(e))
×
179
                binary.BigEndian.PutUint16(b[:], numSigs)
×
180
                if _, err := w.Write(b[:]); err != nil {
×
181
                        return err
×
182
                }
×
183

184
                for _, sig := range e {
×
185
                        if err := WriteElement(w, sig); err != nil {
×
186
                                return err
×
187
                        }
×
188
                }
189

190
        case Sig:
×
191
                // Write buffer
×
192
                if _, err := w.Write(e.bytes[:]); err != nil {
×
193
                        return err
×
194
                }
×
195

196
        case PartialSig:
111✔
197
                if err := e.Encode(w); err != nil {
111✔
198
                        return err
×
199
                }
×
200

201
        case PingPayload:
×
202
                var l [2]byte
×
203
                binary.BigEndian.PutUint16(l[:], uint16(len(e)))
×
204
                if _, err := w.Write(l[:]); err != nil {
×
205
                        return err
×
206
                }
×
207

208
                if _, err := w.Write(e[:]); err != nil {
×
209
                        return err
×
210
                }
×
211

212
        case PongPayload:
×
213
                var l [2]byte
×
214
                binary.BigEndian.PutUint16(l[:], uint16(len(e)))
×
215
                if _, err := w.Write(l[:]); err != nil {
×
216
                        return err
×
217
                }
×
218

219
                if _, err := w.Write(e[:]); err != nil {
×
220
                        return err
×
221
                }
×
222

223
        case WarningData:
×
224
                var l [2]byte
×
225
                binary.BigEndian.PutUint16(l[:], uint16(len(e)))
×
226
                if _, err := w.Write(l[:]); err != nil {
×
227
                        return err
×
228
                }
×
229

230
                if _, err := w.Write(e[:]); err != nil {
×
231
                        return err
×
232
                }
×
233

234
        case ErrorData:
×
235
                var l [2]byte
×
236
                binary.BigEndian.PutUint16(l[:], uint16(len(e)))
×
237
                if _, err := w.Write(l[:]); err != nil {
×
238
                        return err
×
239
                }
×
240

241
                if _, err := w.Write(e[:]); err != nil {
×
242
                        return err
×
243
                }
×
244

245
        case OpaqueReason:
×
246
                var l [2]byte
×
247
                binary.BigEndian.PutUint16(l[:], uint16(len(e)))
×
248
                if _, err := w.Write(l[:]); err != nil {
×
249
                        return err
×
250
                }
×
251

252
                if _, err := w.Write(e[:]); err != nil {
×
253
                        return err
×
254
                }
×
255

256
        case [33]byte:
×
257
                if _, err := w.Write(e[:]); err != nil {
×
258
                        return err
×
259
                }
×
260

261
        case []byte:
399✔
262
                if _, err := w.Write(e[:]); err != nil {
399✔
263
                        return err
×
264
                }
×
265

266
        case PkScript:
×
267
                // The largest script we'll accept is a p2wsh which is exactly
×
268
                // 34 bytes long.
×
269
                scriptLength := len(e)
×
270
                if scriptLength > 34 {
×
271
                        return fmt.Errorf("'PkScript' too long")
×
272
                }
×
273

274
                if err := wire.WriteVarBytes(w, 0, e); err != nil {
×
275
                        return err
×
276
                }
×
277

278
        case *RawFeatureVector:
×
279
                if e == nil {
×
280
                        return fmt.Errorf("cannot write nil feature vector")
×
281
                }
×
282

283
                if err := e.Encode(w); err != nil {
×
284
                        return err
×
285
                }
×
286

287
        case wire.OutPoint:
110✔
288
                var h [32]byte
110✔
289
                copy(h[:], e.Hash[:])
110✔
290
                if _, err := w.Write(h[:]); err != nil {
110✔
291
                        return err
×
292
                }
×
293

294
                if e.Index > math.MaxUint16 {
110✔
295
                        return fmt.Errorf("index for outpoint (%v) is "+
×
296
                                "greater than max index of %v", e.Index,
×
297
                                math.MaxUint16)
×
298
                }
×
299

300
                var idx [2]byte
110✔
301
                binary.BigEndian.PutUint16(idx[:], uint16(e.Index))
110✔
302
                if _, err := w.Write(idx[:]); err != nil {
110✔
303
                        return err
×
304
                }
×
305

306
        case ChannelID:
×
307
                if _, err := w.Write(e[:]); err != nil {
×
308
                        return err
×
309
                }
×
310

311
        case FailCode:
×
312
                if err := WriteElement(w, uint16(e)); err != nil {
×
313
                        return err
×
314
                }
×
315

316
        case ShortChannelID:
110✔
317
                // Check that field fit in 3 bytes and write the blockHeight
110✔
318
                if e.BlockHeight > ((1 << 24) - 1) {
110✔
319
                        return errors.New("block height should fit in 3 bytes")
×
320
                }
×
321

322
                var blockHeight [4]byte
110✔
323
                binary.BigEndian.PutUint32(blockHeight[:], e.BlockHeight)
110✔
324

110✔
325
                if _, err := w.Write(blockHeight[1:]); err != nil {
110✔
326
                        return err
×
327
                }
×
328

329
                // Check that field fit in 3 bytes and write the txIndex
330
                if e.TxIndex > ((1 << 24) - 1) {
110✔
331
                        return errors.New("tx index should fit in 3 bytes")
×
332
                }
×
333

334
                var txIndex [4]byte
110✔
335
                binary.BigEndian.PutUint32(txIndex[:], e.TxIndex)
110✔
336
                if _, err := w.Write(txIndex[1:]); err != nil {
110✔
337
                        return err
×
338
                }
×
339

340
                // Write the txPosition
341
                var txPosition [2]byte
110✔
342
                binary.BigEndian.PutUint16(txPosition[:], e.TxPosition)
110✔
343
                if _, err := w.Write(txPosition[:]); err != nil {
110✔
344
                        return err
×
345
                }
×
346

347
        case *net.TCPAddr:
75✔
348
                if err := WriteTCPAddr(w, e); err != nil {
75✔
349
                        return err
×
350
                }
×
351

352
        case *tor.OnionAddr:
39✔
353
                if err := WriteOnionAddr(w, e); err != nil {
39✔
354
                        return err
×
355
                }
×
356

357
        case *DNSAddress:
36✔
358
                if err := WriteDNSAddress(w, e); err != nil {
36✔
NEW
359
                        return err
×
NEW
360
                }
×
361

362
        case *OpaqueAddrs:
36✔
363
                if err := WriteOpaqueAddrs(w, e); err != nil {
36✔
364
                        return err
×
365
                }
×
366

367
        case []net.Addr:
110✔
368
                // First, we'll encode all the addresses into an intermediate
110✔
369
                // buffer. We need to do this in order to compute the total
110✔
370
                // length of the addresses.
110✔
371
                var addrBuf bytes.Buffer
110✔
372
                for _, address := range e {
293✔
373
                        if err := WriteElement(&addrBuf, address); err != nil {
183✔
374
                                return err
×
375
                        }
×
376
                }
377

378
                // With the addresses fully encoded, we can now write out the
379
                // number of bytes needed to encode them.
380
                addrLen := addrBuf.Len()
110✔
381
                if err := WriteElement(w, uint16(addrLen)); err != nil {
110✔
382
                        return err
×
383
                }
×
384

385
                // Finally, we'll write out the raw addresses themselves, but
386
                // only if we have any bytes to write.
387
                if addrLen > 0 {
149✔
388
                        if _, err := w.Write(addrBuf.Bytes()); err != nil {
39✔
389
                                return err
×
390
                        }
×
391
                }
392

393
        case color.RGBA:
×
394
                if err := WriteElements(w, e.R, e.G, e.B); err != nil {
×
395
                        return err
×
396
                }
×
397

398
        case DeliveryAddress:
×
399
                var length [2]byte
×
400
                binary.BigEndian.PutUint16(length[:], uint16(len(e)))
×
401
                if _, err := w.Write(length[:]); err != nil {
×
402
                        return err
×
403
                }
×
404
                if _, err := w.Write(e[:]); err != nil {
×
405
                        return err
×
406
                }
×
407

408
        case bool:
110✔
409
                var b [1]byte
110✔
410
                if e {
178✔
411
                        b[0] = 1
68✔
412
                }
68✔
413
                if _, err := w.Write(b[:]); err != nil {
110✔
414
                        return err
×
415
                }
×
416

417
        case ExtraOpaqueData:
×
418
                return e.Encode(w)
×
419

420
        default:
×
421
                return fmt.Errorf("unknown type in WriteElement: %T", e)
×
422
        }
423

424
        return nil
3,824✔
425
}
426

427
// WriteElements is writes each element in the elements slice to the passed
428
// buffer using WriteElement.
429
//
430
// TODO(yy): rm this method once we finish dereferencing it from other
431
// packages.
432
func WriteElements(buf *bytes.Buffer, elements ...interface{}) error {
378✔
433
        for _, element := range elements {
3,804✔
434
                err := WriteElement(buf, element)
3,426✔
435
                if err != nil {
3,426✔
436
                        return err
×
437
                }
×
438
        }
439
        return nil
378✔
440
}
441

442
// ReadElement is a one-stop utility function to deserialize any datastructure
443
// encoded using the serialization format of lnwire.
444
func ReadElement(r io.Reader, element interface{}) error {
101,096✔
445
        var err error
101,096✔
446
        switch e := element.(type) {
101,096✔
447
        case *bool:
284✔
448
                var b [1]byte
284✔
449
                if _, err := io.ReadFull(r, b[:]); err != nil {
285✔
450
                        return err
1✔
451
                }
1✔
452

453
                if b[0] == 1 {
420✔
454
                        *e = true
137✔
455
                }
137✔
456

457
        case *NodeAlias:
389✔
458
                var a [32]byte
389✔
459
                if _, err := io.ReadFull(r, a[:]); err != nil {
391✔
460
                        return err
2✔
461
                }
2✔
462

463
                alias, err := NewNodeAlias(string(a[:]))
387✔
464
                if err != nil {
397✔
465
                        return err
10✔
466
                }
10✔
467
                *e = alias
377✔
468

469
        case *QueryEncoding:
×
470
                var b [1]uint8
×
471
                if _, err := r.Read(b[:]); err != nil {
×
472
                        return err
×
473
                }
×
474
                *e = QueryEncoding(b[0])
×
475

476
        case *uint8:
2,690✔
477
                var b [1]uint8
2,690✔
478
                if _, err := r.Read(b[:]); err != nil {
2,694✔
479
                        return err
4✔
480
                }
4✔
481
                *e = b[0]
2,686✔
482

483
        case *FundingFlag:
242✔
484
                var b [1]uint8
242✔
485
                if _, err := r.Read(b[:]); err != nil {
243✔
486
                        return err
1✔
487
                }
1✔
488
                *e = FundingFlag(b[0])
241✔
489

490
        case *uint16:
5,198✔
491
                var b [2]byte
5,198✔
492
                if _, err := io.ReadFull(r, b[:]); err != nil {
5,224✔
493
                        return err
26✔
494
                }
26✔
495
                *e = binary.BigEndian.Uint16(b[:])
5,172✔
496

497
        case *ChanUpdateMsgFlags:
358✔
498
                var b [1]uint8
358✔
499
                if _, err := r.Read(b[:]); err != nil {
365✔
500
                        return err
7✔
501
                }
7✔
502
                *e = ChanUpdateMsgFlags(b[0])
351✔
503

504
        case *ChanUpdateChanFlags:
351✔
505
                var b [1]uint8
351✔
506
                if _, err := r.Read(b[:]); err != nil {
358✔
507
                        return err
7✔
508
                }
7✔
509
                *e = ChanUpdateChanFlags(b[0])
344✔
510

511
        case *uint32:
12,164✔
512
                var b [4]byte
12,164✔
513
                if _, err := io.ReadFull(r, b[:]); err != nil {
12,227✔
514
                        return err
63✔
515
                }
63✔
516
                *e = binary.BigEndian.Uint32(b[:])
12,101✔
517

518
        case *uint64:
4,631✔
519
                var b [8]byte
4,631✔
520
                if _, err := io.ReadFull(r, b[:]); err != nil {
4,642✔
521
                        return err
11✔
522
                }
11✔
523
                *e = binary.BigEndian.Uint64(b[:])
4,620✔
524

525
        case *MilliSatoshi:
4,349✔
526
                var b [8]byte
4,349✔
527
                if _, err := io.ReadFull(r, b[:]); err != nil {
4,372✔
528
                        return err
23✔
529
                }
23✔
530
                *e = MilliSatoshi(int64(binary.BigEndian.Uint64(b[:])))
4,326✔
531

532
        case *btcutil.Amount:
1,768✔
533
                var b [8]byte
1,768✔
534
                if _, err := io.ReadFull(r, b[:]); err != nil {
1,773✔
535
                        return err
5✔
536
                }
5✔
537
                *e = btcutil.Amount(int64(binary.BigEndian.Uint64(b[:])))
1,763✔
538

539
        case **btcec.PublicKey:
3,459✔
540
                var b [btcec.PubKeyBytesLenCompressed]byte
3,459✔
541
                if _, err = io.ReadFull(r, b[:]); err != nil {
3,477✔
542
                        return err
18✔
543
                }
18✔
544

545
                pubKey, err := btcec.ParsePubKey(b[:])
3,441✔
546
                if err != nil {
3,466✔
547
                        return err
25✔
548
                }
25✔
549
                *e = pubKey
3,416✔
550

551
        case *RawFeatureVector:
158✔
552
                f := NewRawFeatureVector()
158✔
553
                err = f.Decode(r)
158✔
554
                if err != nil {
160✔
555
                        return err
2✔
556
                }
2✔
557
                *e = *f
156✔
558

559
        case **RawFeatureVector:
912✔
560
                f := NewRawFeatureVector()
912✔
561
                err = f.Decode(r)
912✔
562
                if err != nil {
930✔
563
                        return err
18✔
564
                }
18✔
565
                *e = f
894✔
566

567
        case *[]Sig:
2,335✔
568
                var l [2]byte
2,335✔
569
                if _, err := io.ReadFull(r, l[:]); err != nil {
2,336✔
570
                        return err
1✔
571
                }
1✔
572
                numSigs := binary.BigEndian.Uint16(l[:])
2,334✔
573

2,334✔
574
                var sigs []Sig
2,334✔
575
                if numSigs > 0 {
3,142✔
576
                        sigs = make([]Sig, numSigs)
808✔
577
                        for i := 0; i < int(numSigs); i++ {
8,306✔
578
                                if err := ReadElement(r, &sigs[i]); err != nil {
7,507✔
579
                                        return err
9✔
580
                                }
9✔
581
                        }
582
                }
583
                *e = sigs
2,325✔
584

585
        case *Sig:
12,819✔
586
                if _, err := io.ReadFull(r, e.bytes[:]); err != nil {
12,883✔
587
                        return err
64✔
588
                }
64✔
589

590
        case *OpaqueReason:
570✔
591
                var l [2]byte
570✔
592
                if _, err := io.ReadFull(r, l[:]); err != nil {
571✔
593
                        return err
1✔
594
                }
1✔
595
                reasonLen := binary.BigEndian.Uint16(l[:])
569✔
596

569✔
597
                *e = OpaqueReason(make([]byte, reasonLen))
569✔
598
                if _, err := io.ReadFull(r, *e); err != nil {
570✔
599
                        return err
1✔
600
                }
1✔
601

602
        case *WarningData:
111✔
603
                var l [2]byte
111✔
604
                if _, err := io.ReadFull(r, l[:]); err != nil {
113✔
605
                        return err
2✔
606
                }
2✔
607
                errorLen := binary.BigEndian.Uint16(l[:])
109✔
608

109✔
609
                *e = WarningData(make([]byte, errorLen))
109✔
610
                if _, err := io.ReadFull(r, *e); err != nil {
110✔
611
                        return err
1✔
612
                }
1✔
613

614
        case *ErrorData:
115✔
615
                var l [2]byte
115✔
616
                if _, err := io.ReadFull(r, l[:]); err != nil {
116✔
617
                        return err
1✔
618
                }
1✔
619
                errorLen := binary.BigEndian.Uint16(l[:])
114✔
620

114✔
621
                *e = ErrorData(make([]byte, errorLen))
114✔
622
                if _, err := io.ReadFull(r, *e); err != nil {
115✔
623
                        return err
1✔
624
                }
1✔
625

626
        case *PingPayload:
111✔
627
                var l [2]byte
111✔
628
                if _, err := io.ReadFull(r, l[:]); err != nil {
112✔
629
                        return err
1✔
630
                }
1✔
631
                pingLen := binary.BigEndian.Uint16(l[:])
110✔
632

110✔
633
                *e = PingPayload(make([]byte, pingLen))
110✔
634
                if _, err := io.ReadFull(r, *e); err != nil {
111✔
635
                        return err
1✔
636
                }
1✔
637

638
        case *PongPayload:
109✔
639
                var l [2]byte
109✔
640
                if _, err := io.ReadFull(r, l[:]); err != nil {
110✔
641
                        return err
1✔
642
                }
1✔
643
                pongLen := binary.BigEndian.Uint16(l[:])
108✔
644

108✔
645
                *e = PongPayload(make([]byte, pongLen))
108✔
646
                if _, err := io.ReadFull(r, *e); err != nil {
110✔
647
                        return err
2✔
648
                }
2✔
649

650
        case *[33]byte:
904✔
651
                if _, err := io.ReadFull(r, e[:]); err != nil {
909✔
652
                        return err
5✔
653
                }
5✔
654

655
        case []byte:
10,963✔
656
                if _, err := io.ReadFull(r, e); err != nil {
11,014✔
657
                        return err
51✔
658
                }
51✔
659

660
        case *PkScript:
×
661
                pkScript, err := wire.ReadVarBytes(r, 0, 34, "pkscript")
×
662
                if err != nil {
×
663
                        return err
×
664
                }
×
665
                *e = pkScript
×
666

667
        case *wire.OutPoint:
324✔
668
                var h [32]byte
324✔
669
                if _, err = io.ReadFull(r, h[:]); err != nil {
325✔
670
                        return err
1✔
671
                }
1✔
672
                hash, err := chainhash.NewHash(h[:])
323✔
673
                if err != nil {
323✔
674
                        return err
×
675
                }
×
676

677
                var idxBytes [2]byte
323✔
678
                _, err = io.ReadFull(r, idxBytes[:])
323✔
679
                if err != nil {
324✔
680
                        return err
1✔
681
                }
1✔
682
                index := binary.BigEndian.Uint16(idxBytes[:])
322✔
683

322✔
684
                *e = wire.OutPoint{
322✔
685
                        Hash:  *hash,
322✔
686
                        Index: uint32(index),
322✔
687
                }
322✔
688

689
        case *FailCode:
134✔
690
                if err := ReadElement(r, (*uint16)(e)); err != nil {
135✔
691
                        return err
1✔
692
                }
1✔
693

694
        case *ChannelID:
9,513✔
695
                if _, err := io.ReadFull(r, e[:]); err != nil {
9,552✔
696
                        return err
39✔
697
                }
39✔
698

699
        case *ShortChannelID:
12,077✔
700
                var blockHeight [4]byte
12,077✔
701
                if _, err = io.ReadFull(r, blockHeight[1:]); err != nil {
13,261✔
702
                        return err
1,184✔
703
                }
1,184✔
704

705
                var txIndex [4]byte
10,893✔
706
                if _, err = io.ReadFull(r, txIndex[1:]); err != nil {
11,083✔
707
                        return err
190✔
708
                }
190✔
709

710
                var txPosition [2]byte
10,703✔
711
                if _, err = io.ReadFull(r, txPosition[:]); err != nil {
10,787✔
712
                        return err
84✔
713
                }
84✔
714

715
                *e = ShortChannelID{
10,619✔
716
                        BlockHeight: binary.BigEndian.Uint32(blockHeight[:]),
10,619✔
717
                        TxIndex:     binary.BigEndian.Uint32(txIndex[:]),
10,619✔
718
                        TxPosition:  binary.BigEndian.Uint16(txPosition[:]),
10,619✔
719
                }
10,619✔
720

721
        case *[]net.Addr:
530✔
722
                addresses, err := ReadAddresses(r)
530✔
723
                if err != nil {
556✔
724
                        return fmt.Errorf("unable to read addresses: %w", err)
26✔
725
                }
26✔
726

727
                *e = addresses
504✔
728

729
        case *color.RGBA:
391✔
730
                err := ReadElements(r,
391✔
731
                        &e.R,
391✔
732
                        &e.G,
391✔
733
                        &e.B,
391✔
734
                )
391✔
735
                if err != nil {
393✔
736
                        return err
2✔
737
                }
2✔
738

739
        case *DeliveryAddress:
697✔
740
                var addrLen [2]byte
697✔
741
                if _, err = io.ReadFull(r, addrLen[:]); err != nil {
706✔
742
                        return err
9✔
743
                }
9✔
744
                length := binary.BigEndian.Uint16(addrLen[:])
688✔
745

688✔
746
                var addrBytes [deliveryAddressMaxSize]byte
688✔
747

688✔
748
                if length > deliveryAddressMaxSize {
793✔
749
                        return fmt.Errorf(
105✔
750
                                "cannot read %d bytes into addrBytes", length,
105✔
751
                        )
105✔
752
                }
105✔
753
                if _, err = io.ReadFull(r, addrBytes[:length]); err != nil {
584✔
754
                        return err
1✔
755
                }
1✔
756
                *e = addrBytes[:length]
582✔
757

758
        case *PartialSig:
123✔
759
                var sig PartialSig
123✔
760
                if err = sig.Decode(r); err != nil {
124✔
761
                        return err
1✔
762
                }
1✔
763
                *e = sig
122✔
764

765
        case *ExtraOpaqueData:
12,395✔
766
                return e.Decode(r)
12,395✔
767

768
        default:
×
769
                return fmt.Errorf("unknown type in ReadElement: %T", e)
×
770
        }
771

772
        return nil
86,695✔
773
}
774

775
// ReadElements deserializes a variable number of elements into the passed
776
// io.Reader, with each element being deserialized according to the ReadElement
777
// function.
778
func ReadElements(r io.Reader, elements ...interface{}) error {
36,418✔
779
        for _, element := range elements {
127,623✔
780
                err := ReadElement(r, element)
91,205✔
781
                if err != nil {
93,165✔
782
                        return err
1,960✔
783
                }
1,960✔
784
        }
785
        return nil
34,458✔
786
}
787

788
// ReadAddresses reads encoded network addresses.
789
//
790
//nolint:funlen
791
func ReadAddresses(r io.Reader) ([]net.Addr, error) {
530✔
792
        // First, we'll read the number of total bytes that have been
530✔
793
        // used to encode the set of addresses.
530✔
794
        var numAddrsBytes [2]byte
530✔
795
        if _, err := io.ReadFull(r, numAddrsBytes[:]); err != nil {
538✔
796
                return nil, err
8✔
797
        }
8✔
798
        addrsLen := binary.BigEndian.Uint16(numAddrsBytes[:])
522✔
799

522✔
800
        // With the number of addresses, read, we'll now pull in the
522✔
801
        // buffer of the encoded addresses into memory.
522✔
802
        addrs := make([]byte, addrsLen)
522✔
803
        if _, err := io.ReadFull(r, addrs); err != nil {
523✔
804
                return nil, err
1✔
805
        }
1✔
806
        addrBuf := bytes.NewReader(addrs)
521✔
807

521✔
808
        // Finally, we'll parse the remaining address payload in
521✔
809
        // series, using the first byte to denote how to decode the
521✔
810
        // address itself.
521✔
811
        var (
521✔
812
                addresses     []net.Addr
521✔
813
                addrBytesRead uint16
521✔
814
        )
521✔
815

521✔
816
        for addrBytesRead < addrsLen {
8,497✔
817
                var descriptor [1]byte
7,976✔
818
                if _, err := io.ReadFull(addrBuf, descriptor[:]); err != nil {
7,976✔
NEW
819
                        return nil, err
×
NEW
820
                }
×
821

822
                addrBytesRead++
7,976✔
823

7,976✔
824
                var address net.Addr
7,976✔
825
                switch aType := addressType(descriptor[0]); aType {
7,976✔
826
                case noAddr:
1,046✔
827
                        continue
1,046✔
828

829
                case tcp4Addr:
2,712✔
830
                        var ip [4]byte
2,712✔
831
                        if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
2,714✔
832
                                return nil, err
2✔
833
                        }
2✔
834

835
                        var port [2]byte
2,710✔
836
                        if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
2,711✔
837
                                return nil, err
1✔
838
                        }
1✔
839

840
                        address = &net.TCPAddr{
2,709✔
841
                                IP:   net.IP(ip[:]),
2,709✔
842
                                Port: int(binary.BigEndian.Uint16(port[:])),
2,709✔
843
                        }
2,709✔
844
                        addrBytesRead += tcp4AddrLen
2,709✔
845

846
                case tcp6Addr:
2,383✔
847
                        var ip [16]byte
2,383✔
848
                        if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
2,387✔
849
                                return nil, err
4✔
850
                        }
4✔
851

852
                        var port [2]byte
2,379✔
853
                        if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
2,380✔
854
                                return nil, err
1✔
855
                        }
1✔
856

857
                        address = &net.TCPAddr{
2,378✔
858
                                IP:   net.IP(ip[:]),
2,378✔
859
                                Port: int(binary.BigEndian.Uint16(port[:])),
2,378✔
860
                        }
2,378✔
861
                        addrBytesRead += tcp6AddrLen
2,378✔
862

863
                case v2OnionAddr:
1,163✔
864
                        var h [tor.V2DecodedLen]byte
1,163✔
865
                        if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
1,166✔
866
                                return nil, err
3✔
867
                        }
3✔
868

869
                        var p [2]byte
1,160✔
870
                        if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
1,161✔
871
                                return nil, err
1✔
872
                        }
1✔
873

874
                        onionService := tor.Base32Encoding.EncodeToString(h[:])
1,159✔
875
                        onionService += tor.OnionSuffix
1,159✔
876
                        port := int(binary.BigEndian.Uint16(p[:]))
1,159✔
877

1,159✔
878
                        address = &tor.OnionAddr{
1,159✔
879
                                OnionService: onionService,
1,159✔
880
                                Port:         port,
1,159✔
881
                        }
1,159✔
882
                        addrBytesRead += v2OnionAddrLen
1,159✔
883

884
                case v3OnionAddr:
396✔
885
                        var h [tor.V3DecodedLen]byte
396✔
886
                        if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
399✔
887
                                return nil, err
3✔
888
                        }
3✔
889

890
                        var p [2]byte
393✔
891
                        if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
394✔
892
                                return nil, err
1✔
893
                        }
1✔
894

895
                        onionService := tor.Base32Encoding.EncodeToString(h[:])
392✔
896
                        onionService += tor.OnionSuffix
392✔
897
                        port := int(binary.BigEndian.Uint16(p[:]))
392✔
898

392✔
899
                        address = &tor.OnionAddr{
392✔
900
                                OnionService: onionService,
392✔
901
                                Port:         port,
392✔
902
                        }
392✔
903
                        addrBytesRead += v3OnionAddrLen
392✔
904

905
                case dnsAddr:
25✔
906
                        var hostnameLen [1]byte
25✔
907
                        _, err := io.ReadFull(addrBuf, hostnameLen[:])
25✔
908
                        if err != nil {
25✔
NEW
909
                                return nil, err
×
NEW
910
                        }
×
911

912
                        hostname := make([]byte, hostnameLen[0])
25✔
913
                        _, err = io.ReadFull(addrBuf, hostname)
25✔
914
                        if err != nil {
26✔
915
                                return nil, err
1✔
916
                        }
1✔
917

918
                        var port [2]byte
24✔
919
                        _, err = io.ReadFull(addrBuf, port[:])
24✔
920
                        if err != nil {
24✔
NEW
921
                                return nil, err
×
NEW
922
                        }
×
923

924
                        address = &DNSAddress{
24✔
925
                                Hostname: string(hostname),
24✔
926
                                Port: binary.BigEndian.Uint16(
24✔
927
                                        port[:],
24✔
928
                                ),
24✔
929
                        }
24✔
930
                        addrBytesRead += dnsAddrOverhead +
24✔
931
                                uint16(len(hostname))
24✔
932

933
                default:
260✔
934
                        // If we don't understand this address type,
260✔
935
                        // we just store it along with the remaining
260✔
936
                        // address bytes as type OpaqueAddrs. We need
260✔
937
                        // to hold onto the bytes so that we can still
260✔
938
                        // write them back to the wire when we
260✔
939
                        // propagate this message.
260✔
940
                        payloadLen := 1 + addrsLen - addrBytesRead
260✔
941
                        payload := make([]byte, payloadLen)
260✔
942

260✔
943
                        // First write a byte for the address type that
260✔
944
                        // we already read.
260✔
945
                        payload[0] = byte(aType)
260✔
946

260✔
947
                        // Now append the rest of the address bytes.
260✔
948
                        _, err := io.ReadFull(addrBuf, payload[1:])
260✔
949
                        if err != nil {
260✔
NEW
950
                                return nil, err
×
NEW
951
                        }
×
952

953
                        address = &OpaqueAddrs{
260✔
954
                                Payload: payload,
260✔
955
                        }
260✔
956
                        addrBytesRead = addrsLen
260✔
957
                }
958

959
                addresses = append(addresses, address)
6,913✔
960
        }
961

962
        return addresses, nil
504✔
963
}
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