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

lightningnetwork / lnd / 11216766535

07 Oct 2024 01:37PM UTC coverage: 57.817% (-1.0%) from 58.817%
11216766535

Pull #9148

github

ProofOfKeags
lnwire: remove kickoff feerate from propose/commit
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

571 of 879 new or added lines in 16 files covered. (64.96%)

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 hits per line

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

64.14
/lnwire/lnwire.go
1
package lnwire
2

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

12
        "github.com/btcsuite/btcd/btcec/v2"
13
        "github.com/btcsuite/btcd/btcutil"
14
        "github.com/btcsuite/btcd/chaincfg/chainhash"
15
        "github.com/btcsuite/btcd/wire"
16
        "github.com/go-errors/errors"
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
// PkScript is simple type definition which represents a raw serialized public
32
// key script.
33
type PkScript []byte
34

35
// addressType specifies the network protocol and version that should be used
36
// when connecting to a node at a particular address.
37
type addressType uint8
38

39
const (
40
        // noAddr denotes a blank address. An address of this type indicates
41
        // that a node doesn't have any advertised addresses.
42
        noAddr addressType = 0
43

44
        // tcp4Addr denotes an IPv4 TCP address.
45
        tcp4Addr addressType = 1
46

47
        // tcp6Addr denotes an IPv6 TCP address.
48
        tcp6Addr addressType = 2
49

50
        // v2OnionAddr denotes a version 2 Tor onion service address.
51
        v2OnionAddr addressType = 3
52

53
        // v3OnionAddr denotes a version 3 Tor (prop224) onion service address.
54
        v3OnionAddr addressType = 4
55
)
56

57
// AddrLen returns the number of bytes that it takes to encode the target
58
// address.
59
func (a addressType) AddrLen() uint16 {
10,755✔
60
        switch a {
10,755✔
61
        case noAddr:
1,046✔
62
                return 0
1,046✔
63
        case tcp4Addr:
3,342✔
64
                return 6
3,342✔
65
        case tcp6Addr:
3,866✔
66
                return 18
3,866✔
67
        case v2OnionAddr:
1,730✔
68
                return 12
1,730✔
69
        case v3OnionAddr:
771✔
70
                return 37
771✔
71
        default:
×
72
                return 0
×
73
        }
74
}
75

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

88
        case QueryEncoding:
×
89
                var b [1]byte
×
90
                b[0] = uint8(e)
×
91
                if _, err := w.Write(b[:]); err != nil {
×
92
                        return err
×
93
                }
×
94

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

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

109
        case uint16:
312✔
110
                var b [2]byte
312✔
111
                binary.BigEndian.PutUint16(b[:], e)
312✔
112
                if _, err := w.Write(b[:]); err != nil {
312✔
113
                        return err
×
114
                }
×
115

116
        case ChanUpdateMsgFlags:
×
117
                var b [1]byte
×
118
                b[0] = uint8(e)
×
119
                if _, err := w.Write(b[:]); err != nil {
×
120
                        return err
×
121
                }
×
122

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

130
        case MilliSatoshi:
×
131
                var b [8]byte
×
132
                binary.BigEndian.PutUint64(b[:], uint64(e))
×
133
                if _, err := w.Write(b[:]); err != nil {
×
134
                        return err
×
135
                }
×
136

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

144
        case uint32:
946✔
145
                var b [4]byte
946✔
146
                binary.BigEndian.PutUint32(b[:], e)
946✔
147
                if _, err := w.Write(b[:]); err != nil {
946✔
148
                        return err
×
149
                }
×
150

151
        case uint64:
×
152
                var b [8]byte
×
153
                binary.BigEndian.PutUint64(b[:], e)
×
154
                if _, err := w.Write(b[:]); err != nil {
×
155
                        return err
×
156
                }
×
157

158
        case *btcec.PublicKey:
468✔
159
                if e == nil {
468✔
160
                        return fmt.Errorf("cannot write nil pubkey")
×
161
                }
×
162

163
                var b [33]byte
468✔
164
                serializedPubkey := e.SerializeCompressed()
468✔
165
                copy(b[:], serializedPubkey)
468✔
166
                if _, err := w.Write(b[:]); err != nil {
468✔
167
                        return err
×
168
                }
×
169

170
        case []Sig:
×
171
                var b [2]byte
×
172
                numSigs := uint16(len(e))
×
173
                binary.BigEndian.PutUint16(b[:], numSigs)
×
174
                if _, err := w.Write(b[:]); err != nil {
×
175
                        return err
×
176
                }
×
177

178
                for _, sig := range e {
×
179
                        if err := WriteElement(w, sig); err != nil {
×
180
                                return err
×
181
                        }
×
182
                }
183

184
        case Sig:
×
185
                // Write buffer
×
186
                if _, err := w.Write(e.bytes[:]); err != nil {
×
187
                        return err
×
188
                }
×
189

190
        case PartialSig:
100✔
191
                if err := e.Encode(w); err != nil {
100✔
192
                        return err
×
193
                }
×
194

195
        case PingPayload:
×
196
                var l [2]byte
×
197
                binary.BigEndian.PutUint16(l[:], uint16(len(e)))
×
198
                if _, err := w.Write(l[:]); err != nil {
×
199
                        return err
×
200
                }
×
201

202
                if _, err := w.Write(e[:]); err != nil {
×
203
                        return err
×
204
                }
×
205

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

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

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

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

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

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

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

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

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

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

260
        case PkScript:
×
261
                // The largest script we'll accept is a p2wsh which is exactly
×
262
                // 34 bytes long.
×
263
                scriptLength := len(e)
×
264
                if scriptLength > 34 {
×
265
                        return fmt.Errorf("'PkScript' too long")
×
266
                }
×
267

268
                if err := wire.WriteVarBytes(w, 0, e); err != nil {
×
269
                        return err
×
270
                }
×
271

272
        case *RawFeatureVector:
×
273
                if e == nil {
×
274
                        return fmt.Errorf("cannot write nil feature vector")
×
275
                }
×
276

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

281
        case wire.OutPoint:
78✔
282
                var h [32]byte
78✔
283
                copy(h[:], e.Hash[:])
78✔
284
                if _, err := w.Write(h[:]); err != nil {
78✔
285
                        return err
×
286
                }
×
287

288
                if e.Index > math.MaxUint16 {
78✔
289
                        return fmt.Errorf("index for outpoint (%v) is "+
×
290
                                "greater than max index of %v", e.Index,
×
291
                                math.MaxUint16)
×
292
                }
×
293

294
                var idx [2]byte
78✔
295
                binary.BigEndian.PutUint16(idx[:], uint16(e.Index))
78✔
296
                if _, err := w.Write(idx[:]); err != nil {
78✔
297
                        return err
×
298
                }
×
299

300
        case ChannelID:
×
301
                if _, err := w.Write(e[:]); err != nil {
×
302
                        return err
×
303
                }
×
304

305
        case FailCode:
×
306
                if err := WriteElement(w, uint16(e)); err != nil {
×
307
                        return err
×
308
                }
×
309

310
        case ShortChannelID:
78✔
311
                // Check that field fit in 3 bytes and write the blockHeight
78✔
312
                if e.BlockHeight > ((1 << 24) - 1) {
78✔
313
                        return errors.New("block height should fit in 3 bytes")
×
314
                }
×
315

316
                var blockHeight [4]byte
78✔
317
                binary.BigEndian.PutUint32(blockHeight[:], e.BlockHeight)
78✔
318

78✔
319
                if _, err := w.Write(blockHeight[1:]); err != nil {
78✔
320
                        return err
×
321
                }
×
322

323
                // Check that field fit in 3 bytes and write the txIndex
324
                if e.TxIndex > ((1 << 24) - 1) {
78✔
325
                        return errors.New("tx index should fit in 3 bytes")
×
326
                }
×
327

328
                var txIndex [4]byte
78✔
329
                binary.BigEndian.PutUint32(txIndex[:], e.TxIndex)
78✔
330
                if _, err := w.Write(txIndex[1:]); err != nil {
78✔
331
                        return err
×
332
                }
×
333

334
                // Write the txPosition
335
                var txPosition [2]byte
78✔
336
                binary.BigEndian.PutUint16(txPosition[:], e.TxPosition)
78✔
337
                if _, err := w.Write(txPosition[:]); err != nil {
78✔
338
                        return err
×
339
                }
×
340

341
        case *net.TCPAddr:
38✔
342
                if e == nil {
38✔
343
                        return fmt.Errorf("cannot write nil TCPAddr")
×
344
                }
×
345

346
                if e.IP.To4() != nil {
76✔
347
                        var descriptor [1]byte
38✔
348
                        descriptor[0] = uint8(tcp4Addr)
38✔
349
                        if _, err := w.Write(descriptor[:]); err != nil {
38✔
350
                                return err
×
351
                        }
×
352

353
                        var ip [4]byte
38✔
354
                        copy(ip[:], e.IP.To4())
38✔
355
                        if _, err := w.Write(ip[:]); err != nil {
38✔
356
                                return err
×
357
                        }
×
358
                } else {
×
359
                        var descriptor [1]byte
×
360
                        descriptor[0] = uint8(tcp6Addr)
×
361
                        if _, err := w.Write(descriptor[:]); err != nil {
×
362
                                return err
×
363
                        }
×
364
                        var ip [16]byte
×
365
                        copy(ip[:], e.IP.To16())
×
366
                        if _, err := w.Write(ip[:]); err != nil {
×
367
                                return err
×
368
                        }
×
369
                }
370
                var port [2]byte
38✔
371
                binary.BigEndian.PutUint16(port[:], uint16(e.Port))
38✔
372
                if _, err := w.Write(port[:]); err != nil {
38✔
373
                        return err
×
374
                }
×
375

376
        case *tor.OnionAddr:
×
377
                if e == nil {
×
378
                        return errors.New("cannot write nil onion address")
×
379
                }
×
380

381
                var suffixIndex int
×
382
                switch len(e.OnionService) {
×
383
                case tor.V2Len:
×
384
                        descriptor := []byte{byte(v2OnionAddr)}
×
385
                        if _, err := w.Write(descriptor); err != nil {
×
386
                                return err
×
387
                        }
×
388
                        suffixIndex = tor.V2Len - tor.OnionSuffixLen
×
389
                case tor.V3Len:
×
390
                        descriptor := []byte{byte(v3OnionAddr)}
×
391
                        if _, err := w.Write(descriptor); err != nil {
×
392
                                return err
×
393
                        }
×
394
                        suffixIndex = tor.V3Len - tor.OnionSuffixLen
×
395
                default:
×
396
                        return errors.New("unknown onion service length")
×
397
                }
398

399
                host, err := tor.Base32Encoding.DecodeString(
×
400
                        e.OnionService[:suffixIndex],
×
401
                )
×
402
                if err != nil {
×
403
                        return err
×
404
                }
×
405
                if _, err := w.Write(host); err != nil {
×
406
                        return err
×
407
                }
×
408

409
                var port [2]byte
×
410
                binary.BigEndian.PutUint16(port[:], uint16(e.Port))
×
411
                if _, err := w.Write(port[:]); err != nil {
×
412
                        return err
×
413
                }
×
414

415
        case []net.Addr:
78✔
416
                // First, we'll encode all the addresses into an intermediate
78✔
417
                // buffer. We need to do this in order to compute the total
78✔
418
                // length of the addresses.
78✔
419
                var addrBuf bytes.Buffer
78✔
420
                for _, address := range e {
116✔
421
                        if err := WriteElement(&addrBuf, address); err != nil {
38✔
422
                                return err
×
423
                        }
×
424
                }
425

426
                // With the addresses fully encoded, we can now write out the
427
                // number of bytes needed to encode them.
428
                addrLen := addrBuf.Len()
78✔
429
                if err := WriteElement(w, uint16(addrLen)); err != nil {
78✔
430
                        return err
×
431
                }
×
432

433
                // Finally, we'll write out the raw addresses themselves, but
434
                // only if we have any bytes to write.
435
                if addrLen > 0 {
97✔
436
                        if _, err := w.Write(addrBuf.Bytes()); err != nil {
19✔
437
                                return err
×
438
                        }
×
439
                }
440

441
        case color.RGBA:
×
442
                if err := WriteElements(w, e.R, e.G, e.B); err != nil {
×
443
                        return err
×
444
                }
×
445

446
        case DeliveryAddress:
×
447
                var length [2]byte
×
448
                binary.BigEndian.PutUint16(length[:], uint16(len(e)))
×
449
                if _, err := w.Write(length[:]); err != nil {
×
450
                        return err
×
451
                }
×
452
                if _, err := w.Write(e[:]); err != nil {
×
453
                        return err
×
454
                }
×
455

456
        case bool:
78✔
457
                var b [1]byte
78✔
458
                if e {
123✔
459
                        b[0] = 1
45✔
460
                }
45✔
461
                if _, err := w.Write(b[:]); err != nil {
78✔
462
                        return err
×
463
                }
×
464

465
        case ExtraOpaqueData:
×
466
                return e.Encode(w)
×
467

468
        default:
×
469
                return fmt.Errorf("unknown type in WriteElement: %T", e)
×
470
        }
471

472
        return nil
2,574✔
473
}
474

475
// WriteElements is writes each element in the elements slice to the passed
476
// buffer using WriteElement.
477
//
478
// TODO(yy): rm this method once we finish dereferencing it from other
479
// packages.
480
func WriteElements(buf *bytes.Buffer, elements ...interface{}) error {
174✔
481
        for _, element := range elements {
2,532✔
482
                err := WriteElement(buf, element)
2,358✔
483
                if err != nil {
2,358✔
484
                        return err
×
485
                }
×
486
        }
487
        return nil
174✔
488
}
489

490
// ReadElement is a one-stop utility function to deserialize any datastructure
491
// encoded using the serialization format of lnwire.
492
func ReadElement(r io.Reader, element interface{}) error {
1,045,498✔
493
        var err error
1,045,498✔
494
        switch e := element.(type) {
1,045,498✔
495
        case *bool:
230✔
496
                var b [1]byte
230✔
497
                if _, err := io.ReadFull(r, b[:]); err != nil {
230✔
UNCOV
498
                        return err
×
UNCOV
499
                }
×
500

501
                if b[0] == 1 {
345✔
502
                        *e = true
115✔
503
                }
115✔
504

505
        case *NodeAlias:
423✔
506
                var a [32]byte
423✔
507
                if _, err := io.ReadFull(r, a[:]); err != nil {
425✔
508
                        return err
2✔
509
                }
2✔
510

511
                alias, err := NewNodeAlias(string(a[:]))
421✔
512
                if err != nil {
431✔
513
                        return err
10✔
514
                }
10✔
515
                *e = alias
411✔
516

517
        case *QueryEncoding:
×
518
                var b [1]uint8
×
519
                if _, err := r.Read(b[:]); err != nil {
×
520
                        return err
×
521
                }
×
522
                *e = QueryEncoding(b[0])
×
523

524
        case *uint8:
2,768✔
525
                var b [1]uint8
2,768✔
526
                if _, err := r.Read(b[:]); err != nil {
2,772✔
527
                        return err
4✔
528
                }
4✔
529
                *e = b[0]
2,764✔
530

531
        case *FundingFlag:
239✔
532
                var b [1]uint8
239✔
533
                if _, err := r.Read(b[:]); err != nil {
240✔
534
                        return err
1✔
535
                }
1✔
536
                *e = FundingFlag(b[0])
238✔
537

538
        case *uint16:
5,386✔
539
                var b [2]byte
5,386✔
540
                if _, err := io.ReadFull(r, b[:]); err != nil {
5,412✔
541
                        return err
26✔
542
                }
26✔
543
                *e = binary.BigEndian.Uint16(b[:])
5,360✔
544

545
        case *ChanUpdateMsgFlags:
501✔
546
                var b [1]uint8
501✔
547
                if _, err := r.Read(b[:]); err != nil {
508✔
548
                        return err
7✔
549
                }
7✔
550
                *e = ChanUpdateMsgFlags(b[0])
494✔
551

552
        case *ChanUpdateChanFlags:
494✔
553
                var b [1]uint8
494✔
554
                if _, err := r.Read(b[:]); err != nil {
501✔
555
                        return err
7✔
556
                }
7✔
557
                *e = ChanUpdateChanFlags(b[0])
487✔
558

559
        case *uint32:
200,188✔
560
                var b [4]byte
200,188✔
561
                if _, err := io.ReadFull(r, b[:]); err != nil {
200,252✔
562
                        return err
64✔
563
                }
64✔
564
                *e = binary.BigEndian.Uint32(b[:])
200,124✔
565

566
        case *uint64:
11,782✔
567
                var b [8]byte
11,782✔
568
                if _, err := io.ReadFull(r, b[:]); err != nil {
11,793✔
569
                        return err
11✔
570
                }
11✔
571
                *e = binary.BigEndian.Uint64(b[:])
11,771✔
572

573
        case *MilliSatoshi:
10,106✔
574
                var b [8]byte
10,106✔
575
                if _, err := io.ReadFull(r, b[:]); err != nil {
10,129✔
576
                        return err
23✔
577
                }
23✔
578
                *e = MilliSatoshi(int64(binary.BigEndian.Uint64(b[:])))
10,083✔
579

580
        case *btcutil.Amount:
1,716✔
581
                var b [8]byte
1,716✔
582
                if _, err := io.ReadFull(r, b[:]); err != nil {
1,723✔
583
                        return err
7✔
584
                }
7✔
585
                *e = btcutil.Amount(int64(binary.BigEndian.Uint64(b[:])))
1,709✔
586

587
        case **btcec.PublicKey:
3,363✔
588
                var b [btcec.PubKeyBytesLenCompressed]byte
3,363✔
589
                if _, err = io.ReadFull(r, b[:]); err != nil {
3,381✔
590
                        return err
18✔
591
                }
18✔
592

593
                pubKey, err := btcec.ParsePubKey(b[:])
3,345✔
594
                if err != nil {
3,369✔
595
                        return err
24✔
596
                }
24✔
597
                *e = pubKey
3,321✔
598

599
        case *RawFeatureVector:
158✔
600
                f := NewRawFeatureVector()
158✔
601
                err = f.Decode(r)
158✔
602
                if err != nil {
160✔
603
                        return err
2✔
604
                }
2✔
605
                *e = *f
156✔
606

607
        case **RawFeatureVector:
954✔
608
                f := NewRawFeatureVector()
954✔
609
                err = f.Decode(r)
954✔
610
                if err != nil {
972✔
611
                        return err
18✔
612
                }
18✔
613
                *e = f
936✔
614

615
        case *[]Sig:
3,628✔
616
                var l [2]byte
3,628✔
617
                if _, err := io.ReadFull(r, l[:]); err != nil {
3,629✔
618
                        return err
1✔
619
                }
1✔
620
                numSigs := binary.BigEndian.Uint16(l[:])
3,627✔
621

3,627✔
622
                var sigs []Sig
3,627✔
623
                if numSigs > 0 {
5,285✔
624
                        sigs = make([]Sig, numSigs)
1,658✔
625
                        for i := 0; i < int(numSigs); i++ {
266,646✔
626
                                if err := ReadElement(r, &sigs[i]); err != nil {
264,997✔
627
                                        return err
9✔
628
                                }
9✔
629
                        }
630
                }
631
                *e = sigs
3,618✔
632

633
        case *Sig:
271,586✔
634
                if _, err := io.ReadFull(r, e.bytes[:]); err != nil {
271,646✔
635
                        return err
60✔
636
                }
60✔
637

638
        case *OpaqueReason:
567✔
639
                var l [2]byte
567✔
640
                if _, err := io.ReadFull(r, l[:]); err != nil {
568✔
641
                        return err
1✔
642
                }
1✔
643
                reasonLen := binary.BigEndian.Uint16(l[:])
566✔
644

566✔
645
                *e = OpaqueReason(make([]byte, reasonLen))
566✔
646
                if _, err := io.ReadFull(r, *e); err != nil {
567✔
647
                        return err
1✔
648
                }
1✔
649

650
        case *WarningData:
111✔
651
                var l [2]byte
111✔
652
                if _, err := io.ReadFull(r, l[:]); err != nil {
113✔
653
                        return err
2✔
654
                }
2✔
655
                errorLen := binary.BigEndian.Uint16(l[:])
109✔
656

109✔
657
                *e = WarningData(make([]byte, errorLen))
109✔
658
                if _, err := io.ReadFull(r, *e); err != nil {
110✔
659
                        return err
1✔
660
                }
1✔
661

662
        case *ErrorData:
112✔
663
                var l [2]byte
112✔
664
                if _, err := io.ReadFull(r, l[:]); err != nil {
113✔
665
                        return err
1✔
666
                }
1✔
667
                errorLen := binary.BigEndian.Uint16(l[:])
111✔
668

111✔
669
                *e = ErrorData(make([]byte, errorLen))
111✔
670
                if _, err := io.ReadFull(r, *e); err != nil {
112✔
671
                        return err
1✔
672
                }
1✔
673

674
        case *PingPayload:
111✔
675
                var l [2]byte
111✔
676
                if _, err := io.ReadFull(r, l[:]); err != nil {
112✔
677
                        return err
1✔
678
                }
1✔
679
                pingLen := binary.BigEndian.Uint16(l[:])
110✔
680

110✔
681
                *e = PingPayload(make([]byte, pingLen))
110✔
682
                if _, err := io.ReadFull(r, *e); err != nil {
111✔
683
                        return err
1✔
684
                }
1✔
685

686
        case *PongPayload:
109✔
687
                var l [2]byte
109✔
688
                if _, err := io.ReadFull(r, l[:]); err != nil {
110✔
689
                        return err
1✔
690
                }
1✔
691
                pongLen := binary.BigEndian.Uint16(l[:])
108✔
692

108✔
693
                *e = PongPayload(make([]byte, pongLen))
108✔
694
                if _, err := io.ReadFull(r, *e); err != nil {
110✔
695
                        return err
2✔
696
                }
2✔
697

698
        case *[33]byte:
970✔
699
                if _, err := io.ReadFull(r, e[:]); err != nil {
975✔
700
                        return err
5✔
701
                }
5✔
702

703
        case []byte:
23,554✔
704
                if _, err := io.ReadFull(r, e); err != nil {
23,601✔
705
                        return err
47✔
706
                }
47✔
707

708
        case *PkScript:
×
709
                pkScript, err := wire.ReadVarBytes(r, 0, 34, "pkscript")
×
710
                if err != nil {
×
711
                        return err
×
712
                }
×
713
                *e = pkScript
×
714

715
        case *wire.OutPoint:
301✔
716
                var h [32]byte
301✔
717
                if _, err = io.ReadFull(r, h[:]); err != nil {
302✔
718
                        return err
1✔
719
                }
1✔
720
                hash, err := chainhash.NewHash(h[:])
300✔
721
                if err != nil {
300✔
722
                        return err
×
723
                }
×
724

725
                var idxBytes [2]byte
300✔
726
                _, err = io.ReadFull(r, idxBytes[:])
300✔
727
                if err != nil {
301✔
728
                        return err
1✔
729
                }
1✔
730
                index := binary.BigEndian.Uint16(idxBytes[:])
299✔
731

299✔
732
                *e = wire.OutPoint{
299✔
733
                        Hash:  *hash,
299✔
734
                        Index: uint32(index),
299✔
735
                }
299✔
736

737
        case *FailCode:
131✔
738
                if err := ReadElement(r, (*uint16)(e)); err != nil {
132✔
739
                        return err
1✔
740
                }
1✔
741

742
        case *ChannelID:
17,977✔
743
                if _, err := io.ReadFull(r, e[:]); err != nil {
18,011✔
744
                        return err
34✔
745
                }
34✔
746

747
        case *ShortChannelID:
466,488✔
748
                var blockHeight [4]byte
466,488✔
749
                if _, err = io.ReadFull(r, blockHeight[1:]); err != nil {
467,694✔
750
                        return err
1,206✔
751
                }
1,206✔
752

753
                var txIndex [4]byte
465,282✔
754
                if _, err = io.ReadFull(r, txIndex[1:]); err != nil {
465,471✔
755
                        return err
189✔
756
                }
189✔
757

758
                var txPosition [2]byte
465,093✔
759
                if _, err = io.ReadFull(r, txPosition[:]); err != nil {
465,176✔
760
                        return err
83✔
761
                }
83✔
762

763
                *e = ShortChannelID{
465,010✔
764
                        BlockHeight: binary.BigEndian.Uint32(blockHeight[:]),
465,010✔
765
                        TxIndex:     binary.BigEndian.Uint32(txIndex[:]),
465,010✔
766
                        TxPosition:  binary.BigEndian.Uint16(txPosition[:]),
465,010✔
767
                }
465,010✔
768

769
        case *[]net.Addr:
542✔
770
                // First, we'll read the number of total bytes that have been
542✔
771
                // used to encode the set of addresses.
542✔
772
                var numAddrsBytes [2]byte
542✔
773
                if _, err = io.ReadFull(r, numAddrsBytes[:]); err != nil {
550✔
774
                        return err
8✔
775
                }
8✔
776
                addrsLen := binary.BigEndian.Uint16(numAddrsBytes[:])
534✔
777

534✔
778
                // With the number of addresses, read, we'll now pull in the
534✔
779
                // buffer of the encoded addresses into memory.
534✔
780
                addrs := make([]byte, addrsLen)
534✔
781
                if _, err := io.ReadFull(r, addrs[:]); err != nil {
535✔
782
                        return err
1✔
783
                }
1✔
784
                addrBuf := bytes.NewReader(addrs)
533✔
785

533✔
786
                // Finally, we'll parse the remaining address payload in
533✔
787
                // series, using the first byte to denote how to decode the
533✔
788
                // address itself.
533✔
789
                var (
533✔
790
                        addresses     []net.Addr
533✔
791
                        addrBytesRead uint16
533✔
792
                )
533✔
793

533✔
794
                for addrBytesRead < addrsLen {
11,673✔
795
                        var descriptor [1]byte
11,140✔
796
                        if _, err = io.ReadFull(addrBuf, descriptor[:]); err != nil {
11,140✔
797
                                return err
×
798
                        }
×
799

800
                        addrBytesRead++
11,140✔
801

11,140✔
802
                        var address net.Addr
11,140✔
803
                        switch aType := addressType(descriptor[0]); aType {
11,140✔
804
                        case noAddr:
1,046✔
805
                                addrBytesRead += aType.AddrLen()
1,046✔
806
                                continue
1,046✔
807

808
                        case tcp4Addr:
3,345✔
809
                                var ip [4]byte
3,345✔
810
                                if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
3,347✔
811
                                        return err
2✔
812
                                }
2✔
813

814
                                var port [2]byte
3,343✔
815
                                if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
3,344✔
816
                                        return err
1✔
817
                                }
1✔
818

819
                                address = &net.TCPAddr{
3,342✔
820
                                        IP:   net.IP(ip[:]),
3,342✔
821
                                        Port: int(binary.BigEndian.Uint16(port[:])),
3,342✔
822
                                }
3,342✔
823
                                addrBytesRead += aType.AddrLen()
3,342✔
824

825
                        case tcp6Addr:
3,871✔
826
                                var ip [16]byte
3,871✔
827
                                if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
3,875✔
828
                                        return err
4✔
829
                                }
4✔
830

831
                                var port [2]byte
3,867✔
832
                                if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
3,868✔
833
                                        return err
1✔
834
                                }
1✔
835

836
                                address = &net.TCPAddr{
3,866✔
837
                                        IP:   net.IP(ip[:]),
3,866✔
838
                                        Port: int(binary.BigEndian.Uint16(port[:])),
3,866✔
839
                                }
3,866✔
840
                                addrBytesRead += aType.AddrLen()
3,866✔
841

842
                        case v2OnionAddr:
1,734✔
843
                                var h [tor.V2DecodedLen]byte
1,734✔
844
                                if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
1,737✔
845
                                        return err
3✔
846
                                }
3✔
847

848
                                var p [2]byte
1,731✔
849
                                if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
1,732✔
850
                                        return err
1✔
851
                                }
1✔
852

853
                                onionService := tor.Base32Encoding.EncodeToString(h[:])
1,730✔
854
                                onionService += tor.OnionSuffix
1,730✔
855
                                port := int(binary.BigEndian.Uint16(p[:]))
1,730✔
856

1,730✔
857
                                address = &tor.OnionAddr{
1,730✔
858
                                        OnionService: onionService,
1,730✔
859
                                        Port:         port,
1,730✔
860
                                }
1,730✔
861
                                addrBytesRead += aType.AddrLen()
1,730✔
862

863
                        case v3OnionAddr:
775✔
864
                                var h [tor.V3DecodedLen]byte
775✔
865
                                if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
778✔
866
                                        return err
3✔
867
                                }
3✔
868

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

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

771✔
878
                                address = &tor.OnionAddr{
771✔
879
                                        OnionService: onionService,
771✔
880
                                        Port:         port,
771✔
881
                                }
771✔
882
                                addrBytesRead += aType.AddrLen()
771✔
883

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

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

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

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

910
                        addresses = append(addresses, address)
10,078✔
911
                }
912

913
                *e = addresses
517✔
914

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

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

183✔
932
                var addrBytes [deliveryAddressMaxSize]byte
183✔
933

183✔
934
                if length > deliveryAddressMaxSize {
187✔
935
                        return fmt.Errorf(
4✔
936
                                "cannot read %d bytes into addrBytes", length,
4✔
937
                        )
4✔
938
                }
4✔
939
                if _, err = io.ReadFull(r, addrBytes[:length]); err != nil {
180✔
940
                        return err
1✔
941
                }
1✔
942
                *e = addrBytes[:length]
178✔
943

944
        case *PartialSig:
100✔
945
                var sig PartialSig
100✔
946
                if err = sig.Decode(r); err != nil {
100✔
947
                        return err
×
948
                }
×
949
                *e = sig
100✔
950

951
        case *ExtraOpaqueData:
20,293✔
952
                return e.Decode(r)
20,293✔
953

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

958
        return nil
1,023,298✔
959
}
960

961
// ReadElements deserializes a variable number of elements into the passed
962
// io.Reader, with each element being deserialized according to the ReadElement
963
// function.
964
func ReadElements(r io.Reader, elements ...interface{}) error {
589,662✔
965
        for _, element := range elements {
1,368,108✔
966
                err := ReadElement(r, element)
778,446✔
967
                if err != nil {
780,310✔
968
                        return err
1,864✔
969
                }
1,864✔
970
        }
971
        return nil
587,798✔
972
}
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