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

lightningnetwork / lnd / 16683051882

01 Aug 2025 07:03PM UTC coverage: 54.949% (-12.1%) from 67.047%
16683051882

Pull #9455

github

web-flow
Merge 3f1f50be8 into 37523b6cb
Pull Request #9455: discovery+lnwire: add support for DNS host name in NodeAnnouncement msg

144 of 226 new or added lines in 7 files covered. (63.72%)

23852 existing lines in 290 files now uncovered.

108751 of 197912 relevant lines covered (54.95%)

22080.83 hits per line

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

70.04
/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
        // noAddrLength is the length of a no address (empty).
31
        noAddrLength = 0
32

33
        // tcp4AddrLength is the length of an IPv4 address
34
        // (4 bytes IP + 2 bytes port).
35
        tcp4AddrLength = 6
36

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

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

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

50
// PkScript is simple type definition which represents a raw serialized public
51
// key script.
52
type PkScript []byte
53

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

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

63
        // tcp4Addr denotes an IPv4 TCP address.
64
        tcp4Addr addressType = 1
65

66
        // tcp6Addr denotes an IPv6 TCP address.
67
        tcp6Addr addressType = 2
68

69
        // v2OnionAddr denotes a version 2 Tor onion service address.
70
        v2OnionAddr addressType = 3
71

72
        // v3OnionAddr denotes a version 3 Tor (prop224) onion service address.
73
        v3OnionAddr addressType = 4
74

75
        // dnsHostnameAddr denotes a DNS hostname address.
76
        dnsHostnameAddr addressType = 5
77
)
78

79
// AddrLen returns the number of bytes that it takes to encode the target
80
// address.
81
func (a addressType) AddrLen(length uint16) uint16 {
7,700✔
82
        return length
7,700✔
83
}
7,700✔
84

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

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

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

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

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

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

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

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

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

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

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

167
        case *btcec.PublicKey:
642✔
168
                if e == nil {
642✔
169
                        return fmt.Errorf("cannot write nil pubkey")
×
170
                }
×
171

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

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

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

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

199
        case PartialSig:
111✔
200
                if err := e.Encode(w); err != nil {
111✔
201
                        return err
×
202
                }
×
203

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

211
                if _, err := w.Write(e[:]); err != nil {
×
212
                        return err
×
213
                }
×
214

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

222
                if _, err := w.Write(e[:]); err != nil {
×
223
                        return err
×
224
                }
×
225

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

233
                if _, err := w.Write(e[:]); err != nil {
×
234
                        return err
×
235
                }
×
236

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

244
                if _, err := w.Write(e[:]); err != nil {
×
245
                        return err
×
246
                }
×
247

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

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

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

264
        case []byte:
395✔
265
                if _, err := w.Write(e[:]); err != nil {
395✔
266
                        return err
×
267
                }
×
268

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

277
                if err := wire.WriteVarBytes(w, 0, e); err != nil {
×
278
                        return err
×
279
                }
×
280

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

286
                if err := e.Encode(w); err != nil {
×
287
                        return err
×
288
                }
×
289

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

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

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

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

314
        case FailCode:
×
315
                if err := WriteElement(w, uint16(e)); err != nil {
×
316
                        return err
×
317
                }
×
318

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

325
                var blockHeight [4]byte
107✔
326
                binary.BigEndian.PutUint32(blockHeight[:], e.BlockHeight)
107✔
327

107✔
328
                if _, err := w.Write(blockHeight[1:]); err != nil {
107✔
329
                        return err
×
330
                }
×
331

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

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

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

350
        case *net.TCPAddr:
72✔
351
                if err := WriteTCPAddr(w, e); err != nil {
72✔
352
                        return err
×
353
                }
×
354

355
        case *tor.OnionAddr:
36✔
356
                if err := WriteOnionAddr(w, e); err != nil {
36✔
357
                        return err
×
358
                }
×
359

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

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

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

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

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

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

406
        case bool:
107✔
407
                var b [1]byte
107✔
408
                if e {
181✔
409
                        b[0] = 1
74✔
410
                }
74✔
411
                if _, err := w.Write(b[:]); err != nil {
107✔
412
                        return err
×
413
                }
×
414

415
        case ExtraOpaqueData:
×
416
                return e.Encode(w)
×
417

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

422
        return nil
3,781✔
423
}
424

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

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

451
                if b[0] == 1 {
424✔
452
                        *e = true
144✔
453
                }
144✔
454

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

461
                alias, err := NewNodeAlias(string(a[:]))
384✔
462
                if err != nil {
394✔
463
                        return err
10✔
464
                }
10✔
465
                *e = alias
374✔
466

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

474
        case *uint8:
2,687✔
475
                var b [1]uint8
2,687✔
476
                if _, err := r.Read(b[:]); err != nil {
2,691✔
477
                        return err
4✔
478
                }
4✔
479
                *e = b[0]
2,683✔
480

481
        case *FundingFlag:
239✔
482
                var b [1]uint8
239✔
483
                if _, err := r.Read(b[:]); err != nil {
240✔
484
                        return err
1✔
485
                }
1✔
486
                *e = FundingFlag(b[0])
238✔
487

488
        case *uint16:
5,180✔
489
                var b [2]byte
5,180✔
490
                if _, err := io.ReadFull(r, b[:]); err != nil {
5,206✔
491
                        return err
26✔
492
                }
26✔
493
                *e = binary.BigEndian.Uint16(b[:])
5,154✔
494

495
        case *ChanUpdateMsgFlags:
355✔
496
                var b [1]uint8
355✔
497
                if _, err := r.Read(b[:]); err != nil {
362✔
498
                        return err
7✔
499
                }
7✔
500
                *e = ChanUpdateMsgFlags(b[0])
348✔
501

502
        case *ChanUpdateChanFlags:
348✔
503
                var b [1]uint8
348✔
504
                if _, err := r.Read(b[:]); err != nil {
355✔
505
                        return err
7✔
506
                }
7✔
507
                *e = ChanUpdateChanFlags(b[0])
341✔
508

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

516
        case *uint64:
4,477✔
517
                var b [8]byte
4,477✔
518
                if _, err := io.ReadFull(r, b[:]); err != nil {
4,488✔
519
                        return err
11✔
520
                }
11✔
521
                *e = binary.BigEndian.Uint64(b[:])
4,466✔
522

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

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

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

543
                pubKey, err := btcec.ParsePubKey(b[:])
3,438✔
544
                if err != nil {
3,463✔
545
                        return err
25✔
546
                }
25✔
547
                *e = pubKey
3,413✔
548

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

557
        case **RawFeatureVector:
909✔
558
                f := NewRawFeatureVector()
909✔
559
                err = f.Decode(r)
909✔
560
                if err != nil {
927✔
561
                        return err
18✔
562
                }
18✔
563
                *e = f
891✔
564

565
        case *[]Sig:
2,221✔
566
                var l [2]byte
2,221✔
567
                if _, err := io.ReadFull(r, l[:]); err != nil {
2,222✔
568
                        return err
1✔
569
                }
1✔
570
                numSigs := binary.BigEndian.Uint16(l[:])
2,220✔
571

2,220✔
572
                var sigs []Sig
2,220✔
573
                if numSigs > 0 {
2,994✔
574
                        sigs = make([]Sig, numSigs)
774✔
575
                        for i := 0; i < int(numSigs); i++ {
8,388✔
576
                                if err := ReadElement(r, &sigs[i]); err != nil {
7,623✔
577
                                        return err
9✔
578
                                }
9✔
579
                        }
580
                }
581
                *e = sigs
2,211✔
582

583
        case *Sig:
12,824✔
584
                if _, err := io.ReadFull(r, e.bytes[:]); err != nil {
12,888✔
585
                        return err
64✔
586
                }
64✔
587

588
        case *OpaqueReason:
567✔
589
                var l [2]byte
567✔
590
                if _, err := io.ReadFull(r, l[:]); err != nil {
568✔
591
                        return err
1✔
592
                }
1✔
593
                reasonLen := binary.BigEndian.Uint16(l[:])
566✔
594

566✔
595
                *e = OpaqueReason(make([]byte, reasonLen))
566✔
596
                if _, err := io.ReadFull(r, *e); err != nil {
567✔
597
                        return err
1✔
598
                }
1✔
599

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

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

612
        case *ErrorData:
112✔
613
                var l [2]byte
112✔
614
                if _, err := io.ReadFull(r, l[:]); err != nil {
113✔
615
                        return err
1✔
616
                }
1✔
617
                errorLen := binary.BigEndian.Uint16(l[:])
111✔
618

111✔
619
                *e = ErrorData(make([]byte, errorLen))
111✔
620
                if _, err := io.ReadFull(r, *e); err != nil {
112✔
621
                        return err
1✔
622
                }
1✔
623

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

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

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

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

648
        case *[33]byte:
901✔
649
                if _, err := io.ReadFull(r, e[:]); err != nil {
906✔
650
                        return err
5✔
651
                }
5✔
652

653
        case []byte:
10,751✔
654
                if _, err := io.ReadFull(r, e); err != nil {
10,802✔
655
                        return err
51✔
656
                }
51✔
657

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

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

675
                var idxBytes [2]byte
320✔
676
                _, err = io.ReadFull(r, idxBytes[:])
320✔
677
                if err != nil {
321✔
678
                        return err
1✔
679
                }
1✔
680
                index := binary.BigEndian.Uint16(idxBytes[:])
319✔
681

319✔
682
                *e = wire.OutPoint{
319✔
683
                        Hash:  *hash,
319✔
684
                        Index: uint32(index),
319✔
685
                }
319✔
686

687
        case *FailCode:
131✔
688
                if err := ReadElement(r, (*uint16)(e)); err != nil {
132✔
689
                        return err
1✔
690
                }
1✔
691

692
        case *ChannelID:
9,263✔
693
                if _, err := io.ReadFull(r, e[:]); err != nil {
9,302✔
694
                        return err
39✔
695
                }
39✔
696

697
        case *ShortChannelID:
12,156✔
698
                var blockHeight [4]byte
12,156✔
699
                if _, err = io.ReadFull(r, blockHeight[1:]); err != nil {
13,354✔
700
                        return err
1,198✔
701
                }
1,198✔
702

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

708
                var txPosition [2]byte
10,768✔
709
                if _, err = io.ReadFull(r, txPosition[:]); err != nil {
10,852✔
710
                        return err
84✔
711
                }
84✔
712

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

719
        case *[]net.Addr:
526✔
720
                // First, we'll read the number of total bytes that have been
526✔
721
                // used to encode the set of addresses.
526✔
722
                var numAddrsBytes [2]byte
526✔
723
                if _, err = io.ReadFull(r, numAddrsBytes[:]); err != nil {
534✔
724
                        return err
8✔
725
                }
8✔
726
                addrsLen := binary.BigEndian.Uint16(numAddrsBytes[:])
518✔
727

518✔
728
                // With the number of addresses, read, we'll now pull in the
518✔
729
                // buffer of the encoded addresses into memory.
518✔
730
                addrs := make([]byte, addrsLen)
518✔
731
                if _, err := io.ReadFull(r, addrs[:]); err != nil {
519✔
732
                        return err
1✔
733
                }
1✔
734
                addrBuf := bytes.NewReader(addrs)
517✔
735

517✔
736
                // Finally, we'll parse the remaining address payload in
517✔
737
                // series, using the first byte to denote how to decode the
517✔
738
                // address itself.
517✔
739
                var (
517✔
740
                        addresses       []net.Addr
517✔
741
                        addrBytesRead   uint16
517✔
742
                        dnsAddrIncluded bool
517✔
743
                )
517✔
744

517✔
745
                for addrBytesRead < addrsLen {
8,495✔
746
                        var descriptor [1]byte
7,978✔
747
                        if _, err = io.ReadFull(addrBuf, descriptor[:]); err != nil {
7,978✔
748
                                return err
×
749
                        }
×
750

751
                        addrBytesRead++
7,978✔
752

7,978✔
753
                        var address net.Addr
7,978✔
754
                        switch aType := addressType(descriptor[0]); aType {
7,978✔
755
                        case noAddr:
1,046✔
756
                                addrBytesRead += aType.AddrLen(noAddrLength)
1,046✔
757
                                continue
1,046✔
758

759
                        case tcp4Addr:
2,713✔
760
                                var ip [4]byte
2,713✔
761
                                if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
2,715✔
762
                                        return err
2✔
763
                                }
2✔
764

765
                                var port [2]byte
2,711✔
766
                                if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
2,712✔
767
                                        return err
1✔
768
                                }
1✔
769

770
                                address = &net.TCPAddr{
2,710✔
771
                                        IP:   net.IP(ip[:]),
2,710✔
772
                                        Port: int(binary.BigEndian.Uint16(port[:])),
2,710✔
773
                                }
2,710✔
774
                                addrBytesRead += aType.AddrLen(tcp4AddrLength)
2,710✔
775

776
                        case tcp6Addr:
2,403✔
777
                                var ip [16]byte
2,403✔
778
                                if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
2,407✔
779
                                        return err
4✔
780
                                }
4✔
781

782
                                var port [2]byte
2,399✔
783
                                if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
2,400✔
784
                                        return err
1✔
785
                                }
1✔
786

787
                                address = &net.TCPAddr{
2,398✔
788
                                        IP:   net.IP(ip[:]),
2,398✔
789
                                        Port: int(binary.BigEndian.Uint16(port[:])),
2,398✔
790
                                }
2,398✔
791
                                addrBytesRead += aType.AddrLen(tcp6AddrLength)
2,398✔
792

793
                        case v2OnionAddr:
1,159✔
794
                                var h [tor.V2DecodedLen]byte
1,159✔
795
                                if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
1,162✔
796
                                        return err
3✔
797
                                }
3✔
798

799
                                var p [2]byte
1,156✔
800
                                if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
1,157✔
801
                                        return err
1✔
802
                                }
1✔
803

804
                                onionService := tor.Base32Encoding.EncodeToString(h[:])
1,155✔
805
                                onionService += tor.OnionSuffix
1,155✔
806
                                port := int(binary.BigEndian.Uint16(p[:]))
1,155✔
807

1,155✔
808
                                address = &tor.OnionAddr{
1,155✔
809
                                        OnionService: onionService,
1,155✔
810
                                        Port:         port,
1,155✔
811
                                }
1,155✔
812
                                addrBytesRead += aType.AddrLen(
1,155✔
813
                                        OnionV2AddrLength,
1,155✔
814
                                )
1,155✔
815

816
                        case v3OnionAddr:
393✔
817
                                var h [tor.V3DecodedLen]byte
393✔
818
                                if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
396✔
819
                                        return err
3✔
820
                                }
3✔
821

822
                                var p [2]byte
390✔
823
                                if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
391✔
824
                                        return err
1✔
825
                                }
1✔
826

827
                                onionService := tor.Base32Encoding.EncodeToString(h[:])
389✔
828
                                onionService += tor.OnionSuffix
389✔
829
                                port := int(binary.BigEndian.Uint16(p[:]))
389✔
830

389✔
831
                                address = &tor.OnionAddr{
389✔
832
                                        OnionService: onionService,
389✔
833
                                        Port:         port,
389✔
834
                                }
389✔
835
                                addrBytesRead += aType.AddrLen(
389✔
836
                                        OnionV3AddrLength,
389✔
837
                                )
389✔
838

839
                        case dnsHostnameAddr:
4✔
840
                                if dnsAddrIncluded {
5✔
841
                                        return ErrMultipleDNSAddresses
1✔
842
                                }
1✔
843
                                dnsAddrIncluded = true
3✔
844

3✔
845
                                // Read hostname length byte.
3✔
846
                                var hostnameLen [1]byte
3✔
847
                                _, err := io.ReadFull(addrBuf, hostnameLen[:])
3✔
848
                                if err != nil {
3✔
NEW
849
                                        return err
×
NEW
850
                                }
×
851

852
                                // Now read the hostname itself.
853
                                hostname := make([]byte, hostnameLen[0])
3✔
854
                                _, err = io.ReadFull(addrBuf, hostname)
3✔
855
                                if err != nil {
4✔
856
                                        return err
1✔
857
                                }
1✔
858

859
                                // Read port.
860
                                var port [2]byte
2✔
861
                                _, err = io.ReadFull(addrBuf, port[:])
2✔
862
                                if err != nil {
2✔
NEW
863
                                        return err
×
NEW
864
                                }
×
865

866
                                dnsAddr, err := NewDNSAddr(
2✔
867
                                        string(hostname),
2✔
868
                                        binary.BigEndian.Uint16(port[:]),
2✔
869
                                )
2✔
870
                                if err != nil {
2✔
NEW
871
                                        return err
×
NEW
872
                                }
×
873

874
                                address = dnsAddr
2✔
875

2✔
876
                                // Construct lengths for bytes read. This
2✔
877
                                // includes 1 byte for descriptor, hostname
2✔
878
                                // variable length, and 2 bytes for port.
2✔
879
                                length := 1 + uint16(hostnameLen[0]) + 2
2✔
880

2✔
881
                                addrBytesRead += aType.AddrLen(length)
2✔
882

883
                        default:
260✔
884
                                // If we don't understand this address type,
260✔
885
                                // we just store it along with the remaining
260✔
886
                                // address bytes as type OpaqueAddrs. We need
260✔
887
                                // to hold onto the bytes so that we can still
260✔
888
                                // write them back to the wire when we
260✔
889
                                // propagate this message.
260✔
890
                                payloadLen := 1 + addrsLen - addrBytesRead
260✔
891
                                payload := make([]byte, payloadLen)
260✔
892

260✔
893
                                // First write a byte for the address type that
260✔
894
                                // we already read.
260✔
895
                                payload[0] = byte(aType)
260✔
896

260✔
897
                                // Now append the rest of the address bytes.
260✔
898
                                _, err := io.ReadFull(addrBuf, payload[1:])
260✔
899
                                if err != nil {
260✔
900
                                        return err
×
901
                                }
×
902

903
                                address = &OpaqueAddrs{
260✔
904
                                        Payload: payload,
260✔
905
                                }
260✔
906
                                addrBytesRead = addrsLen
260✔
907
                        }
908

909
                        addresses = append(addresses, address)
6,914✔
910
                }
911

912
                *e = addresses
499✔
913

914
        case *color.RGBA:
388✔
915
                err := ReadElements(r,
388✔
916
                        &e.R,
388✔
917
                        &e.G,
388✔
918
                        &e.B,
388✔
919
                )
388✔
920
                if err != nil {
390✔
921
                        return err
2✔
922
                }
2✔
923

924
        case *DeliveryAddress:
694✔
925
                var addrLen [2]byte
694✔
926
                if _, err = io.ReadFull(r, addrLen[:]); err != nil {
703✔
927
                        return err
9✔
928
                }
9✔
929
                length := binary.BigEndian.Uint16(addrLen[:])
685✔
930

685✔
931
                var addrBytes [deliveryAddressMaxSize]byte
685✔
932

685✔
933
                if length > deliveryAddressMaxSize {
790✔
934
                        return fmt.Errorf(
105✔
935
                                "cannot read %d bytes into addrBytes", length,
105✔
936
                        )
105✔
937
                }
105✔
938
                if _, err = io.ReadFull(r, addrBytes[:length]); err != nil {
581✔
939
                        return err
1✔
940
                }
1✔
941
                *e = addrBytes[:length]
579✔
942

943
        case *PartialSig:
123✔
944
                var sig PartialSig
123✔
945
                if err = sig.Decode(r); err != nil {
124✔
946
                        return err
1✔
947
                }
1✔
948
                *e = sig
122✔
949

950
        case *ExtraOpaqueData:
12,145✔
951
                return e.Decode(r)
12,145✔
952

953
        default:
×
954
                return fmt.Errorf("unknown type in ReadElement: %T", e)
×
955
        }
956

957
        return nil
85,987✔
958
}
959

960
// ReadElements deserializes a variable number of elements into the passed
961
// io.Reader, with each element being deserialized according to the ReadElement
962
// function.
963
func ReadElements(r io.Reader, elements ...interface{}) error {
36,279✔
964
        for _, element := range elements {
126,470✔
965
                err := ReadElement(r, element)
90,191✔
966
                if err != nil {
92,165✔
967
                        return err
1,974✔
968
                }
1,974✔
969
        }
970
        return nil
34,305✔
971
}
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