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

lightningnetwork / lnd / 15248693013

26 May 2025 07:27AM UTC coverage: 69.015% (+10.4%) from 58.596%
15248693013

push

github

web-flow
Merge pull request #9864 from ziggie1984/update-sqlc

sqlc: update sqlc compiler to 1.29.0

134050 of 194234 relevant lines covered (69.01%)

22056.82 hits per line

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

69.29
/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 {
7,718✔
60
        switch a {
7,718✔
61
        case noAddr:
1,046✔
62
                return 0
1,046✔
63
        case tcp4Addr:
2,730✔
64
                return 6
2,730✔
65
        case tcp6Addr:
2,401✔
66
                return 18
2,401✔
67
        case v2OnionAddr:
1,158✔
68
                return 12
1,158✔
69
        case v3OnionAddr:
392✔
70
                return 37
392✔
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 {
3,802✔
82
        switch e := element.(type) {
3,802✔
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:
119✔
96
                var b [1]byte
119✔
97
                b[0] = e
119✔
98
                if _, err := w.Write(b[:]); err != nil {
119✔
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:
487✔
110
                var b [2]byte
487✔
111
                binary.BigEndian.PutUint16(b[:], e)
487✔
112
                if _, err := w.Write(b[:]); err != nil {
487✔
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:
110✔
138
                var b [8]byte
110✔
139
                binary.BigEndian.PutUint64(b[:], uint64(e))
110✔
140
                if _, err := w.Write(b[:]); err != nil {
110✔
141
                        return err
×
142
                }
×
143

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

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

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

163
                var b [33]byte
645✔
164
                serializedPubkey := e.SerializeCompressed()
645✔
165
                copy(b[:], serializedPubkey)
645✔
166
                if _, err := w.Write(b[:]); err != nil {
645✔
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:
111✔
191
                if err := e.Encode(w); err != nil {
111✔
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:
403✔
256
                if _, err := w.Write(e[:]); err != nil {
403✔
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:
110✔
282
                var h [32]byte
110✔
283
                copy(h[:], e.Hash[:])
110✔
284
                if _, err := w.Write(h[:]); err != nil {
110✔
285
                        return err
×
286
                }
×
287

288
                if e.Index > math.MaxUint16 {
110✔
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
110✔
295
                binary.BigEndian.PutUint16(idx[:], uint16(e.Index))
110✔
296
                if _, err := w.Write(idx[:]); err != nil {
110✔
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:
110✔
311
                // Check that field fit in 3 bytes and write the blockHeight
110✔
312
                if e.BlockHeight > ((1 << 24) - 1) {
110✔
313
                        return errors.New("block height should fit in 3 bytes")
×
314
                }
×
315

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

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

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

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

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

341
        case *net.TCPAddr:
75✔
342
                if err := WriteTCPAddr(w, e); err != nil {
75✔
343
                        return err
×
344
                }
×
345

346
        case *tor.OnionAddr:
39✔
347
                if err := WriteOnionAddr(w, e); err != nil {
39✔
348
                        return err
×
349
                }
×
350

351
        case *OpaqueAddrs:
36✔
352
                if err := WriteOpaqueAddrs(w, e); err != nil {
36✔
353
                        return err
×
354
                }
×
355

356
        case []net.Addr:
110✔
357
                // First, we'll encode all the addresses into an intermediate
110✔
358
                // buffer. We need to do this in order to compute the total
110✔
359
                // length of the addresses.
110✔
360
                var addrBuf bytes.Buffer
110✔
361
                for _, address := range e {
257✔
362
                        if err := WriteElement(&addrBuf, address); err != nil {
147✔
363
                                return err
×
364
                        }
×
365
                }
366

367
                // With the addresses fully encoded, we can now write out the
368
                // number of bytes needed to encode them.
369
                addrLen := addrBuf.Len()
110✔
370
                if err := WriteElement(w, uint16(addrLen)); err != nil {
110✔
371
                        return err
×
372
                }
×
373

374
                // Finally, we'll write out the raw addresses themselves, but
375
                // only if we have any bytes to write.
376
                if addrLen > 0 {
149✔
377
                        if _, err := w.Write(addrBuf.Bytes()); err != nil {
39✔
378
                                return err
×
379
                        }
×
380
                }
381

382
        case color.RGBA:
×
383
                if err := WriteElements(w, e.R, e.G, e.B); err != nil {
×
384
                        return err
×
385
                }
×
386

387
        case DeliveryAddress:
×
388
                var length [2]byte
×
389
                binary.BigEndian.PutUint16(length[:], uint16(len(e)))
×
390
                if _, err := w.Write(length[:]); err != nil {
×
391
                        return err
×
392
                }
×
393
                if _, err := w.Write(e[:]); err != nil {
×
394
                        return err
×
395
                }
×
396

397
        case bool:
110✔
398
                var b [1]byte
110✔
399
                if e {
173✔
400
                        b[0] = 1
63✔
401
                }
63✔
402
                if _, err := w.Write(b[:]); err != nil {
110✔
403
                        return err
×
404
                }
×
405

406
        case ExtraOpaqueData:
×
407
                return e.Encode(w)
×
408

409
        default:
×
410
                return fmt.Errorf("unknown type in WriteElement: %T", e)
×
411
        }
412

413
        return nil
3,802✔
414
}
415

416
// WriteElements is writes each element in the elements slice to the passed
417
// buffer using WriteElement.
418
//
419
// TODO(yy): rm this method once we finish dereferencing it from other
420
// packages.
421
func WriteElements(buf *bytes.Buffer, elements ...interface{}) error {
389✔
422
        for _, element := range elements {
3,829✔
423
                err := WriteElement(buf, element)
3,440✔
424
                if err != nil {
3,440✔
425
                        return err
×
426
                }
×
427
        }
428
        return nil
389✔
429
}
430

431
// ReadElement is a one-stop utility function to deserialize any datastructure
432
// encoded using the serialization format of lnwire.
433
func ReadElement(r io.Reader, element interface{}) error {
99,368✔
434
        var err error
99,368✔
435
        switch e := element.(type) {
99,368✔
436
        case *bool:
528✔
437
                var b [1]byte
528✔
438
                if _, err := io.ReadFull(r, b[:]); err != nil {
530✔
439
                        return err
2✔
440
                }
2✔
441

442
                if b[0] == 1 {
698✔
443
                        *e = true
172✔
444
                }
172✔
445

446
        case *NodeAlias:
389✔
447
                var a [32]byte
389✔
448
                if _, err := io.ReadFull(r, a[:]); err != nil {
391✔
449
                        return err
2✔
450
                }
2✔
451

452
                alias, err := NewNodeAlias(string(a[:]))
387✔
453
                if err != nil {
397✔
454
                        return err
10✔
455
                }
10✔
456
                *e = alias
377✔
457

458
        case *QueryEncoding:
×
459
                var b [1]uint8
×
460
                if _, err := r.Read(b[:]); err != nil {
×
461
                        return err
×
462
                }
×
463
                *e = QueryEncoding(b[0])
×
464

465
        case *uint8:
2,690✔
466
                var b [1]uint8
2,690✔
467
                if _, err := r.Read(b[:]); err != nil {
2,694✔
468
                        return err
4✔
469
                }
4✔
470
                *e = b[0]
2,686✔
471

472
        case *FundingFlag:
242✔
473
                var b [1]uint8
242✔
474
                if _, err := r.Read(b[:]); err != nil {
243✔
475
                        return err
1✔
476
                }
1✔
477
                *e = FundingFlag(b[0])
241✔
478

479
        case *uint16:
5,199✔
480
                var b [2]byte
5,199✔
481
                if _, err := io.ReadFull(r, b[:]); err != nil {
5,225✔
482
                        return err
26✔
483
                }
26✔
484
                *e = binary.BigEndian.Uint16(b[:])
5,173✔
485

486
        case *ChanUpdateMsgFlags:
358✔
487
                var b [1]uint8
358✔
488
                if _, err := r.Read(b[:]); err != nil {
365✔
489
                        return err
7✔
490
                }
7✔
491
                *e = ChanUpdateMsgFlags(b[0])
351✔
492

493
        case *ChanUpdateChanFlags:
351✔
494
                var b [1]uint8
351✔
495
                if _, err := r.Read(b[:]); err != nil {
358✔
496
                        return err
7✔
497
                }
7✔
498
                *e = ChanUpdateChanFlags(b[0])
344✔
499

500
        case *uint32:
11,977✔
501
                var b [4]byte
11,977✔
502
                if _, err := io.ReadFull(r, b[:]); err != nil {
12,040✔
503
                        return err
63✔
504
                }
63✔
505
                *e = binary.BigEndian.Uint32(b[:])
11,914✔
506

507
        case *uint64:
4,495✔
508
                var b [8]byte
4,495✔
509
                if _, err := io.ReadFull(r, b[:]); err != nil {
4,506✔
510
                        return err
11✔
511
                }
11✔
512
                *e = binary.BigEndian.Uint64(b[:])
4,484✔
513

514
        case *MilliSatoshi:
4,298✔
515
                var b [8]byte
4,298✔
516
                if _, err := io.ReadFull(r, b[:]); err != nil {
4,321✔
517
                        return err
23✔
518
                }
23✔
519
                *e = MilliSatoshi(int64(binary.BigEndian.Uint64(b[:])))
4,275✔
520

521
        case *btcutil.Amount:
1,768✔
522
                var b [8]byte
1,768✔
523
                if _, err := io.ReadFull(r, b[:]); err != nil {
1,773✔
524
                        return err
5✔
525
                }
5✔
526
                *e = btcutil.Amount(int64(binary.BigEndian.Uint64(b[:])))
1,763✔
527

528
        case **btcec.PublicKey:
3,459✔
529
                var b [btcec.PubKeyBytesLenCompressed]byte
3,459✔
530
                if _, err = io.ReadFull(r, b[:]); err != nil {
3,477✔
531
                        return err
18✔
532
                }
18✔
533

534
                pubKey, err := btcec.ParsePubKey(b[:])
3,441✔
535
                if err != nil {
3,466✔
536
                        return err
25✔
537
                }
25✔
538
                *e = pubKey
3,416✔
539

540
        case *RawFeatureVector:
158✔
541
                f := NewRawFeatureVector()
158✔
542
                err = f.Decode(r)
158✔
543
                if err != nil {
160✔
544
                        return err
2✔
545
                }
2✔
546
                *e = *f
156✔
547

548
        case **RawFeatureVector:
912✔
549
                f := NewRawFeatureVector()
912✔
550
                err = f.Decode(r)
912✔
551
                if err != nil {
930✔
552
                        return err
18✔
553
                }
18✔
554
                *e = f
894✔
555

556
        case *[]Sig:
2,243✔
557
                var l [2]byte
2,243✔
558
                if _, err := io.ReadFull(r, l[:]); err != nil {
2,244✔
559
                        return err
1✔
560
                }
1✔
561
                numSigs := binary.BigEndian.Uint16(l[:])
2,242✔
562

2,242✔
563
                var sigs []Sig
2,242✔
564
                if numSigs > 0 {
3,015✔
565
                        sigs = make([]Sig, numSigs)
773✔
566
                        for i := 0; i < int(numSigs); i++ {
8,254✔
567
                                if err := ReadElement(r, &sigs[i]); err != nil {
7,490✔
568
                                        return err
9✔
569
                                }
9✔
570
                        }
571
                }
572
                *e = sigs
2,233✔
573

574
        case *Sig:
12,456✔
575
                if _, err := io.ReadFull(r, e.bytes[:]); err != nil {
12,491✔
576
                        return err
35✔
577
                }
35✔
578

579
        case *OpaqueReason:
570✔
580
                var l [2]byte
570✔
581
                if _, err := io.ReadFull(r, l[:]); err != nil {
571✔
582
                        return err
1✔
583
                }
1✔
584
                reasonLen := binary.BigEndian.Uint16(l[:])
569✔
585

569✔
586
                *e = OpaqueReason(make([]byte, reasonLen))
569✔
587
                if _, err := io.ReadFull(r, *e); err != nil {
570✔
588
                        return err
1✔
589
                }
1✔
590

591
        case *WarningData:
111✔
592
                var l [2]byte
111✔
593
                if _, err := io.ReadFull(r, l[:]); err != nil {
113✔
594
                        return err
2✔
595
                }
2✔
596
                errorLen := binary.BigEndian.Uint16(l[:])
109✔
597

109✔
598
                *e = WarningData(make([]byte, errorLen))
109✔
599
                if _, err := io.ReadFull(r, *e); err != nil {
110✔
600
                        return err
1✔
601
                }
1✔
602

603
        case *ErrorData:
115✔
604
                var l [2]byte
115✔
605
                if _, err := io.ReadFull(r, l[:]); err != nil {
116✔
606
                        return err
1✔
607
                }
1✔
608
                errorLen := binary.BigEndian.Uint16(l[:])
114✔
609

114✔
610
                *e = ErrorData(make([]byte, errorLen))
114✔
611
                if _, err := io.ReadFull(r, *e); err != nil {
115✔
612
                        return err
1✔
613
                }
1✔
614

615
        case *PingPayload:
111✔
616
                var l [2]byte
111✔
617
                if _, err := io.ReadFull(r, l[:]); err != nil {
112✔
618
                        return err
1✔
619
                }
1✔
620
                pingLen := binary.BigEndian.Uint16(l[:])
110✔
621

110✔
622
                *e = PingPayload(make([]byte, pingLen))
110✔
623
                if _, err := io.ReadFull(r, *e); err != nil {
111✔
624
                        return err
1✔
625
                }
1✔
626

627
        case *PongPayload:
109✔
628
                var l [2]byte
109✔
629
                if _, err := io.ReadFull(r, l[:]); err != nil {
110✔
630
                        return err
1✔
631
                }
1✔
632
                pongLen := binary.BigEndian.Uint16(l[:])
108✔
633

108✔
634
                *e = PongPayload(make([]byte, pongLen))
108✔
635
                if _, err := io.ReadFull(r, *e); err != nil {
110✔
636
                        return err
2✔
637
                }
2✔
638

639
        case *[33]byte:
904✔
640
                if _, err := io.ReadFull(r, e[:]); err != nil {
909✔
641
                        return err
5✔
642
                }
5✔
643

644
        case []byte:
10,770✔
645
                if _, err := io.ReadFull(r, e); err != nil {
10,821✔
646
                        return err
51✔
647
                }
51✔
648

649
        case *PkScript:
×
650
                pkScript, err := wire.ReadVarBytes(r, 0, 34, "pkscript")
×
651
                if err != nil {
×
652
                        return err
×
653
                }
×
654
                *e = pkScript
×
655

656
        case *wire.OutPoint:
324✔
657
                var h [32]byte
324✔
658
                if _, err = io.ReadFull(r, h[:]); err != nil {
325✔
659
                        return err
1✔
660
                }
1✔
661
                hash, err := chainhash.NewHash(h[:])
323✔
662
                if err != nil {
323✔
663
                        return err
×
664
                }
×
665

666
                var idxBytes [2]byte
323✔
667
                _, err = io.ReadFull(r, idxBytes[:])
323✔
668
                if err != nil {
324✔
669
                        return err
1✔
670
                }
1✔
671
                index := binary.BigEndian.Uint16(idxBytes[:])
322✔
672

322✔
673
                *e = wire.OutPoint{
322✔
674
                        Hash:  *hash,
322✔
675
                        Index: uint32(index),
322✔
676
                }
322✔
677

678
        case *FailCode:
134✔
679
                if err := ReadElement(r, (*uint16)(e)); err != nil {
135✔
680
                        return err
1✔
681
                }
1✔
682

683
        case *ChannelID:
9,230✔
684
                if _, err := io.ReadFull(r, e[:]); err != nil {
9,269✔
685
                        return err
39✔
686
                }
39✔
687

688
        case *ShortChannelID:
11,984✔
689
                var blockHeight [4]byte
11,984✔
690
                if _, err = io.ReadFull(r, blockHeight[1:]); err != nil {
13,184✔
691
                        return err
1,200✔
692
                }
1,200✔
693

694
                var txIndex [4]byte
10,784✔
695
                if _, err = io.ReadFull(r, txIndex[1:]); err != nil {
10,974✔
696
                        return err
190✔
697
                }
190✔
698

699
                var txPosition [2]byte
10,594✔
700
                if _, err = io.ReadFull(r, txPosition[:]); err != nil {
10,678✔
701
                        return err
84✔
702
                }
84✔
703

704
                *e = ShortChannelID{
10,510✔
705
                        BlockHeight: binary.BigEndian.Uint32(blockHeight[:]),
10,510✔
706
                        TxIndex:     binary.BigEndian.Uint32(txIndex[:]),
10,510✔
707
                        TxPosition:  binary.BigEndian.Uint16(txPosition[:]),
10,510✔
708
                }
10,510✔
709

710
        case *[]net.Addr:
528✔
711
                // First, we'll read the number of total bytes that have been
528✔
712
                // used to encode the set of addresses.
528✔
713
                var numAddrsBytes [2]byte
528✔
714
                if _, err = io.ReadFull(r, numAddrsBytes[:]); err != nil {
536✔
715
                        return err
8✔
716
                }
8✔
717
                addrsLen := binary.BigEndian.Uint16(numAddrsBytes[:])
520✔
718

520✔
719
                // With the number of addresses, read, we'll now pull in the
520✔
720
                // buffer of the encoded addresses into memory.
520✔
721
                addrs := make([]byte, addrsLen)
520✔
722
                if _, err := io.ReadFull(r, addrs[:]); err != nil {
521✔
723
                        return err
1✔
724
                }
1✔
725
                addrBuf := bytes.NewReader(addrs)
519✔
726

519✔
727
                // Finally, we'll parse the remaining address payload in
519✔
728
                // series, using the first byte to denote how to decode the
519✔
729
                // address itself.
519✔
730
                var (
519✔
731
                        addresses     []net.Addr
519✔
732
                        addrBytesRead uint16
519✔
733
                )
519✔
734

519✔
735
                for addrBytesRead < addrsLen {
8,514✔
736
                        var descriptor [1]byte
7,995✔
737
                        if _, err = io.ReadFull(addrBuf, descriptor[:]); err != nil {
7,995✔
738
                                return err
×
739
                        }
×
740

741
                        addrBytesRead++
7,995✔
742

7,995✔
743
                        var address net.Addr
7,995✔
744
                        switch aType := addressType(descriptor[0]); aType {
7,995✔
745
                        case noAddr:
1,046✔
746
                                addrBytesRead += aType.AddrLen()
1,046✔
747
                                continue
1,046✔
748

749
                        case tcp4Addr:
2,733✔
750
                                var ip [4]byte
2,733✔
751
                                if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
2,735✔
752
                                        return err
2✔
753
                                }
2✔
754

755
                                var port [2]byte
2,731✔
756
                                if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
2,732✔
757
                                        return err
1✔
758
                                }
1✔
759

760
                                address = &net.TCPAddr{
2,730✔
761
                                        IP:   net.IP(ip[:]),
2,730✔
762
                                        Port: int(binary.BigEndian.Uint16(port[:])),
2,730✔
763
                                }
2,730✔
764
                                addrBytesRead += aType.AddrLen()
2,730✔
765

766
                        case tcp6Addr:
2,406✔
767
                                var ip [16]byte
2,406✔
768
                                if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
2,410✔
769
                                        return err
4✔
770
                                }
4✔
771

772
                                var port [2]byte
2,402✔
773
                                if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
2,403✔
774
                                        return err
1✔
775
                                }
1✔
776

777
                                address = &net.TCPAddr{
2,401✔
778
                                        IP:   net.IP(ip[:]),
2,401✔
779
                                        Port: int(binary.BigEndian.Uint16(port[:])),
2,401✔
780
                                }
2,401✔
781
                                addrBytesRead += aType.AddrLen()
2,401✔
782

783
                        case v2OnionAddr:
1,162✔
784
                                var h [tor.V2DecodedLen]byte
1,162✔
785
                                if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
1,165✔
786
                                        return err
3✔
787
                                }
3✔
788

789
                                var p [2]byte
1,159✔
790
                                if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
1,160✔
791
                                        return err
1✔
792
                                }
1✔
793

794
                                onionService := tor.Base32Encoding.EncodeToString(h[:])
1,158✔
795
                                onionService += tor.OnionSuffix
1,158✔
796
                                port := int(binary.BigEndian.Uint16(p[:]))
1,158✔
797

1,158✔
798
                                address = &tor.OnionAddr{
1,158✔
799
                                        OnionService: onionService,
1,158✔
800
                                        Port:         port,
1,158✔
801
                                }
1,158✔
802
                                addrBytesRead += aType.AddrLen()
1,158✔
803

804
                        case v3OnionAddr:
396✔
805
                                var h [tor.V3DecodedLen]byte
396✔
806
                                if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
399✔
807
                                        return err
3✔
808
                                }
3✔
809

810
                                var p [2]byte
393✔
811
                                if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
394✔
812
                                        return err
1✔
813
                                }
1✔
814

815
                                onionService := tor.Base32Encoding.EncodeToString(h[:])
392✔
816
                                onionService += tor.OnionSuffix
392✔
817
                                port := int(binary.BigEndian.Uint16(p[:]))
392✔
818

392✔
819
                                address = &tor.OnionAddr{
392✔
820
                                        OnionService: onionService,
392✔
821
                                        Port:         port,
392✔
822
                                }
392✔
823
                                addrBytesRead += aType.AddrLen()
392✔
824

825
                        default:
261✔
826
                                // If we don't understand this address type,
261✔
827
                                // we just store it along with the remaining
261✔
828
                                // address bytes as type OpaqueAddrs. We need
261✔
829
                                // to hold onto the bytes so that we can still
261✔
830
                                // write them back to the wire when we
261✔
831
                                // propagate this message.
261✔
832
                                payloadLen := 1 + addrsLen - addrBytesRead
261✔
833
                                payload := make([]byte, payloadLen)
261✔
834

261✔
835
                                // First write a byte for the address type that
261✔
836
                                // we already read.
261✔
837
                                payload[0] = byte(aType)
261✔
838

261✔
839
                                // Now append the rest of the address bytes.
261✔
840
                                _, err := io.ReadFull(addrBuf, payload[1:])
261✔
841
                                if err != nil {
261✔
842
                                        return err
×
843
                                }
×
844

845
                                address = &OpaqueAddrs{
261✔
846
                                        Payload: payload,
261✔
847
                                }
261✔
848
                                addrBytesRead = addrsLen
261✔
849
                        }
850

851
                        addresses = append(addresses, address)
6,933✔
852
                }
853

854
                *e = addresses
503✔
855

856
        case *color.RGBA:
391✔
857
                err := ReadElements(r,
391✔
858
                        &e.R,
391✔
859
                        &e.G,
391✔
860
                        &e.B,
391✔
861
                )
391✔
862
                if err != nil {
393✔
863
                        return err
2✔
864
                }
2✔
865

866
        case *DeliveryAddress:
697✔
867
                var addrLen [2]byte
697✔
868
                if _, err = io.ReadFull(r, addrLen[:]); err != nil {
706✔
869
                        return err
9✔
870
                }
9✔
871
                length := binary.BigEndian.Uint16(addrLen[:])
688✔
872

688✔
873
                var addrBytes [deliveryAddressMaxSize]byte
688✔
874

688✔
875
                if length > deliveryAddressMaxSize {
793✔
876
                        return fmt.Errorf(
105✔
877
                                "cannot read %d bytes into addrBytes", length,
105✔
878
                        )
105✔
879
                }
105✔
880
                if _, err = io.ReadFull(r, addrBytes[:length]); err != nil {
584✔
881
                        return err
1✔
882
                }
1✔
883
                *e = addrBytes[:length]
582✔
884

885
        case *PartialSig:
123✔
886
                var sig PartialSig
123✔
887
                if err = sig.Decode(r); err != nil {
124✔
888
                        return err
1✔
889
                }
1✔
890
                *e = sig
122✔
891

892
        case *ExtraOpaqueData:
11,822✔
893
                return e.Decode(r)
11,822✔
894

895
        default:
×
896
                return fmt.Errorf("unknown type in ReadElement: %T", e)
×
897
        }
898

899
        return nil
85,553✔
900
}
901

902
// ReadElements deserializes a variable number of elements into the passed
903
// io.Reader, with each element being deserialized according to the ReadElement
904
// function.
905
func ReadElements(r io.Reader, elements ...interface{}) error {
35,693✔
906
        for _, element := range elements {
125,246✔
907
                err := ReadElement(r, element)
89,553✔
908
                if err != nil {
91,500✔
909
                        return err
1,947✔
910
                }
1,947✔
911
        }
912
        return nil
33,746✔
913
}
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