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

lightningnetwork / lnd / 13035292482

29 Jan 2025 03:59PM UTC coverage: 49.3% (-9.5%) from 58.777%
13035292482

Pull #9456

github

mohamedawnallah
docs: update release-notes-0.19.0.md

In this commit, we warn users about the removal
of RPCs `SendToRoute`, `SendToRouteSync`, `SendPayment`,
and `SendPaymentSync` in the next release 0.20.
Pull Request #9456: lnrpc+docs: deprecate warning `SendToRoute`, `SendToRouteSync`, `SendPayment`, and `SendPaymentSync` in Release 0.19

100634 of 204126 relevant lines covered (49.3%)

1.54 hits per line

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

0.0
/channeldb/migration/lnwire21/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
// MaxSliceLength is the maximum allowed length for any opaque byte slices in
21
// the wire protocol.
22
const MaxSliceLength = 65535
23

24
// PkScript is simple type definition which represents a raw serialized public
25
// key script.
26
type PkScript []byte
27

28
// addressType specifies the network protocol and version that should be used
29
// when connecting to a node at a particular address.
30
type addressType uint8
31

32
const (
33
        // noAddr denotes a blank address. An address of this type indicates
34
        // that a node doesn't have any advertised addresses.
35
        noAddr addressType = 0
36

37
        // tcp4Addr denotes an IPv4 TCP address.
38
        tcp4Addr addressType = 1
39

40
        // tcp6Addr denotes an IPv6 TCP address.
41
        tcp6Addr addressType = 2
42

43
        // v2OnionAddr denotes a version 2 Tor onion service address.
44
        v2OnionAddr addressType = 3
45

46
        // v3OnionAddr denotes a version 3 Tor (prop224) onion service address.
47
        v3OnionAddr addressType = 4
48
)
49

50
// AddrLen returns the number of bytes that it takes to encode the target
51
// address.
52
func (a addressType) AddrLen() uint16 {
×
53
        switch a {
×
54
        case noAddr:
×
55
                return 0
×
56
        case tcp4Addr:
×
57
                return 6
×
58
        case tcp6Addr:
×
59
                return 18
×
60
        case v2OnionAddr:
×
61
                return 12
×
62
        case v3OnionAddr:
×
63
                return 37
×
64
        default:
×
65
                return 0
×
66
        }
67
}
68

69
// WriteElement is a one-stop shop to write the big endian representation of
70
// any element which is to be serialized for the wire protocol. The passed
71
// io.Writer should be backed by an appropriately sized byte slice, or be able
72
// to dynamically expand to accommodate additional data.
73
//
74
// TODO(roasbeef): this should eventually draw from a buffer pool for
75
// serialization.
76
func WriteElement(w io.Writer, element interface{}) error {
×
77
        switch e := element.(type) {
×
78
        case NodeAlias:
×
79
                if _, err := w.Write(e[:]); err != nil {
×
80
                        return err
×
81
                }
×
82

83
        case ShortChanIDEncoding:
×
84
                var b [1]byte
×
85
                b[0] = uint8(e)
×
86
                if _, err := w.Write(b[:]); err != nil {
×
87
                        return err
×
88
                }
×
89
        case uint8:
×
90
                var b [1]byte
×
91
                b[0] = e
×
92
                if _, err := w.Write(b[:]); err != nil {
×
93
                        return err
×
94
                }
×
95
        case FundingFlag:
×
96
                var b [1]byte
×
97
                b[0] = uint8(e)
×
98
                if _, err := w.Write(b[:]); err != nil {
×
99
                        return err
×
100
                }
×
101
        case uint16:
×
102
                var b [2]byte
×
103
                binary.BigEndian.PutUint16(b[:], e)
×
104
                if _, err := w.Write(b[:]); err != nil {
×
105
                        return err
×
106
                }
×
107
        case ChanUpdateMsgFlags:
×
108
                var b [1]byte
×
109
                b[0] = uint8(e)
×
110
                if _, err := w.Write(b[:]); err != nil {
×
111
                        return err
×
112
                }
×
113
        case ChanUpdateChanFlags:
×
114
                var b [1]byte
×
115
                b[0] = uint8(e)
×
116
                if _, err := w.Write(b[:]); err != nil {
×
117
                        return err
×
118
                }
×
119
        case MilliSatoshi:
×
120
                var b [8]byte
×
121
                binary.BigEndian.PutUint64(b[:], uint64(e))
×
122
                if _, err := w.Write(b[:]); err != nil {
×
123
                        return err
×
124
                }
×
125
        case btcutil.Amount:
×
126
                var b [8]byte
×
127
                binary.BigEndian.PutUint64(b[:], uint64(e))
×
128
                if _, err := w.Write(b[:]); err != nil {
×
129
                        return err
×
130
                }
×
131
        case uint32:
×
132
                var b [4]byte
×
133
                binary.BigEndian.PutUint32(b[:], e)
×
134
                if _, err := w.Write(b[:]); err != nil {
×
135
                        return err
×
136
                }
×
137
        case uint64:
×
138
                var b [8]byte
×
139
                binary.BigEndian.PutUint64(b[:], e)
×
140
                if _, err := w.Write(b[:]); err != nil {
×
141
                        return err
×
142
                }
×
143
        case *btcec.PublicKey:
×
144
                if e == nil {
×
145
                        return fmt.Errorf("cannot write nil pubkey")
×
146
                }
×
147

148
                var b [33]byte
×
149
                serializedPubkey := e.SerializeCompressed()
×
150
                copy(b[:], serializedPubkey)
×
151
                if _, err := w.Write(b[:]); err != nil {
×
152
                        return err
×
153
                }
×
154
        case []Sig:
×
155
                var b [2]byte
×
156
                numSigs := uint16(len(e))
×
157
                binary.BigEndian.PutUint16(b[:], numSigs)
×
158
                if _, err := w.Write(b[:]); err != nil {
×
159
                        return err
×
160
                }
×
161

162
                for _, sig := range e {
×
163
                        if err := WriteElement(w, sig); err != nil {
×
164
                                return err
×
165
                        }
×
166
                }
167
        case Sig:
×
168
                // Write buffer
×
169
                if _, err := w.Write(e[:]); err != nil {
×
170
                        return err
×
171
                }
×
172
        case PingPayload:
×
173
                var l [2]byte
×
174
                binary.BigEndian.PutUint16(l[:], uint16(len(e)))
×
175
                if _, err := w.Write(l[:]); err != nil {
×
176
                        return err
×
177
                }
×
178

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

189
                if _, err := w.Write(e[:]); err != nil {
×
190
                        return err
×
191
                }
×
192
        case ErrorData:
×
193
                var l [2]byte
×
194
                binary.BigEndian.PutUint16(l[:], uint16(len(e)))
×
195
                if _, err := w.Write(l[:]); err != nil {
×
196
                        return err
×
197
                }
×
198

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

209
                if _, err := w.Write(e[:]); err != nil {
×
210
                        return err
×
211
                }
×
212
        case [33]byte:
×
213
                if _, err := w.Write(e[:]); err != nil {
×
214
                        return err
×
215
                }
×
216
        case []byte:
×
217
                if _, err := w.Write(e[:]); err != nil {
×
218
                        return err
×
219
                }
×
220
        case PkScript:
×
221
                // The largest script we'll accept is a p2wsh which is exactly
×
222
                // 34 bytes long.
×
223
                scriptLength := len(e)
×
224
                if scriptLength > 34 {
×
225
                        return fmt.Errorf("'PkScript' too long")
×
226
                }
×
227

228
                if err := wire.WriteVarBytes(w, 0, e); err != nil {
×
229
                        return err
×
230
                }
×
231
        case *RawFeatureVector:
×
232
                if e == nil {
×
233
                        return fmt.Errorf("cannot write nil feature vector")
×
234
                }
×
235

236
                if err := e.Encode(w); err != nil {
×
237
                        return err
×
238
                }
×
239

240
        case wire.OutPoint:
×
241
                var h [32]byte
×
242
                copy(h[:], e.Hash[:])
×
243
                if _, err := w.Write(h[:]); err != nil {
×
244
                        return err
×
245
                }
×
246

247
                if e.Index > math.MaxUint16 {
×
248
                        return fmt.Errorf("index for outpoint (%v) is "+
×
249
                                "greater than max index of %v", e.Index,
×
250
                                math.MaxUint16)
×
251
                }
×
252

253
                var idx [2]byte
×
254
                binary.BigEndian.PutUint16(idx[:], uint16(e.Index))
×
255
                if _, err := w.Write(idx[:]); err != nil {
×
256
                        return err
×
257
                }
×
258

259
        case ChannelID:
×
260
                if _, err := w.Write(e[:]); err != nil {
×
261
                        return err
×
262
                }
×
263
        case FailCode:
×
264
                if err := WriteElement(w, uint16(e)); err != nil {
×
265
                        return err
×
266
                }
×
267
        case ShortChannelID:
×
268
                // Check that field fit in 3 bytes and write the blockHeight
×
269
                if e.BlockHeight > ((1 << 24) - 1) {
×
270
                        return errors.New("block height should fit in 3 bytes")
×
271
                }
×
272

273
                var blockHeight [4]byte
×
274
                binary.BigEndian.PutUint32(blockHeight[:], e.BlockHeight)
×
275

×
276
                if _, err := w.Write(blockHeight[1:]); err != nil {
×
277
                        return err
×
278
                }
×
279

280
                // Check that field fit in 3 bytes and write the txIndex
281
                if e.TxIndex > ((1 << 24) - 1) {
×
282
                        return errors.New("tx index should fit in 3 bytes")
×
283
                }
×
284

285
                var txIndex [4]byte
×
286
                binary.BigEndian.PutUint32(txIndex[:], e.TxIndex)
×
287
                if _, err := w.Write(txIndex[1:]); err != nil {
×
288
                        return err
×
289
                }
×
290

291
                // Write the txPosition
292
                var txPosition [2]byte
×
293
                binary.BigEndian.PutUint16(txPosition[:], e.TxPosition)
×
294
                if _, err := w.Write(txPosition[:]); err != nil {
×
295
                        return err
×
296
                }
×
297

298
        case *net.TCPAddr:
×
299
                if e == nil {
×
300
                        return fmt.Errorf("cannot write nil TCPAddr")
×
301
                }
×
302

303
                if e.IP.To4() != nil {
×
304
                        var descriptor [1]byte
×
305
                        descriptor[0] = uint8(tcp4Addr)
×
306
                        if _, err := w.Write(descriptor[:]); err != nil {
×
307
                                return err
×
308
                        }
×
309

310
                        var ip [4]byte
×
311
                        copy(ip[:], e.IP.To4())
×
312
                        if _, err := w.Write(ip[:]); err != nil {
×
313
                                return err
×
314
                        }
×
315
                } else {
×
316
                        var descriptor [1]byte
×
317
                        descriptor[0] = uint8(tcp6Addr)
×
318
                        if _, err := w.Write(descriptor[:]); err != nil {
×
319
                                return err
×
320
                        }
×
321
                        var ip [16]byte
×
322
                        copy(ip[:], e.IP.To16())
×
323
                        if _, err := w.Write(ip[:]); err != nil {
×
324
                                return err
×
325
                        }
×
326
                }
327
                var port [2]byte
×
328
                binary.BigEndian.PutUint16(port[:], uint16(e.Port))
×
329
                if _, err := w.Write(port[:]); err != nil {
×
330
                        return err
×
331
                }
×
332

333
        case *tor.OnionAddr:
×
334
                if e == nil {
×
335
                        return errors.New("cannot write nil onion address")
×
336
                }
×
337

338
                var suffixIndex int
×
339
                switch len(e.OnionService) {
×
340
                case tor.V2Len:
×
341
                        descriptor := []byte{byte(v2OnionAddr)}
×
342
                        if _, err := w.Write(descriptor); err != nil {
×
343
                                return err
×
344
                        }
×
345
                        suffixIndex = tor.V2Len - tor.OnionSuffixLen
×
346
                case tor.V3Len:
×
347
                        descriptor := []byte{byte(v3OnionAddr)}
×
348
                        if _, err := w.Write(descriptor); err != nil {
×
349
                                return err
×
350
                        }
×
351
                        suffixIndex = tor.V3Len - tor.OnionSuffixLen
×
352
                default:
×
353
                        return errors.New("unknown onion service length")
×
354
                }
355

356
                host, err := tor.Base32Encoding.DecodeString(
×
357
                        e.OnionService[:suffixIndex],
×
358
                )
×
359
                if err != nil {
×
360
                        return err
×
361
                }
×
362
                if _, err := w.Write(host); err != nil {
×
363
                        return err
×
364
                }
×
365

366
                var port [2]byte
×
367
                binary.BigEndian.PutUint16(port[:], uint16(e.Port))
×
368
                if _, err := w.Write(port[:]); err != nil {
×
369
                        return err
×
370
                }
×
371

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

383
                // With the addresses fully encoded, we can now write out the
384
                // number of bytes needed to encode them.
385
                addrLen := addrBuf.Len()
×
386
                if err := WriteElement(w, uint16(addrLen)); err != nil {
×
387
                        return err
×
388
                }
×
389

390
                // Finally, we'll write out the raw addresses themselves, but
391
                // only if we have any bytes to write.
392
                if addrLen > 0 {
×
393
                        if _, err := w.Write(addrBuf.Bytes()); err != nil {
×
394
                                return err
×
395
                        }
×
396
                }
397
        case color.RGBA:
×
398
                if err := WriteElements(w, e.R, e.G, e.B); err != nil {
×
399
                        return err
×
400
                }
×
401

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

412
        case bool:
×
413
                var b [1]byte
×
414
                if e {
×
415
                        b[0] = 1
×
416
                }
×
417
                if _, err := w.Write(b[:]); err != nil {
×
418
                        return err
×
419
                }
×
420
        default:
×
421
                return fmt.Errorf("unknown type in WriteElement: %T", e)
×
422
        }
423

424
        return nil
×
425
}
426

427
// WriteElements is writes each element in the elements slice to the passed
428
// io.Writer using WriteElement.
429
func WriteElements(w io.Writer, elements ...interface{}) error {
×
430
        for _, element := range elements {
×
431
                err := WriteElement(w, element)
×
432
                if err != nil {
×
433
                        return err
×
434
                }
×
435
        }
436
        return nil
×
437
}
438

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

450
                if b[0] == 1 {
×
451
                        *e = true
×
452
                }
×
453

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

460
                alias, err := NewNodeAlias(string(a[:]))
×
461
                if err != nil {
×
462
                        return err
×
463
                }
×
464

465
                *e = alias
×
466
        case *ShortChanIDEncoding:
×
467
                var b [1]uint8
×
468
                if _, err := r.Read(b[:]); err != nil {
×
469
                        return err
×
470
                }
×
471
                *e = ShortChanIDEncoding(b[0])
×
472
        case *uint8:
×
473
                var b [1]uint8
×
474
                if _, err := r.Read(b[:]); err != nil {
×
475
                        return err
×
476
                }
×
477
                *e = b[0]
×
478
        case *FundingFlag:
×
479
                var b [1]uint8
×
480
                if _, err := r.Read(b[:]); err != nil {
×
481
                        return err
×
482
                }
×
483
                *e = FundingFlag(b[0])
×
484
        case *uint16:
×
485
                var b [2]byte
×
486
                if _, err := io.ReadFull(r, b[:]); err != nil {
×
487
                        return err
×
488
                }
×
489
                *e = binary.BigEndian.Uint16(b[:])
×
490
        case *ChanUpdateMsgFlags:
×
491
                var b [1]uint8
×
492
                if _, err := r.Read(b[:]); err != nil {
×
493
                        return err
×
494
                }
×
495
                *e = ChanUpdateMsgFlags(b[0])
×
496
        case *ChanUpdateChanFlags:
×
497
                var b [1]uint8
×
498
                if _, err := r.Read(b[:]); err != nil {
×
499
                        return err
×
500
                }
×
501
                *e = ChanUpdateChanFlags(b[0])
×
502
        case *uint32:
×
503
                var b [4]byte
×
504
                if _, err := io.ReadFull(r, b[:]); err != nil {
×
505
                        return err
×
506
                }
×
507
                *e = binary.BigEndian.Uint32(b[:])
×
508
        case *uint64:
×
509
                var b [8]byte
×
510
                if _, err := io.ReadFull(r, b[:]); err != nil {
×
511
                        return err
×
512
                }
×
513
                *e = binary.BigEndian.Uint64(b[:])
×
514
        case *MilliSatoshi:
×
515
                var b [8]byte
×
516
                if _, err := io.ReadFull(r, b[:]); err != nil {
×
517
                        return err
×
518
                }
×
519
                *e = MilliSatoshi(int64(binary.BigEndian.Uint64(b[:])))
×
520
        case *btcutil.Amount:
×
521
                var b [8]byte
×
522
                if _, err := io.ReadFull(r, b[:]); err != nil {
×
523
                        return err
×
524
                }
×
525
                *e = btcutil.Amount(int64(binary.BigEndian.Uint64(b[:])))
×
526
        case **btcec.PublicKey:
×
527
                var b [btcec.PubKeyBytesLenCompressed]byte
×
528
                if _, err = io.ReadFull(r, b[:]); err != nil {
×
529
                        return err
×
530
                }
×
531

532
                pubKey, err := btcec.ParsePubKey(b[:])
×
533
                if err != nil {
×
534
                        return err
×
535
                }
×
536
                *e = pubKey
×
537
        case **RawFeatureVector:
×
538
                f := NewRawFeatureVector()
×
539
                err = f.Decode(r)
×
540
                if err != nil {
×
541
                        return err
×
542
                }
×
543

544
                *e = f
×
545

546
        case *[]Sig:
×
547
                var l [2]byte
×
548
                if _, err := io.ReadFull(r, l[:]); err != nil {
×
549
                        return err
×
550
                }
×
551
                numSigs := binary.BigEndian.Uint16(l[:])
×
552

×
553
                var sigs []Sig
×
554
                if numSigs > 0 {
×
555
                        sigs = make([]Sig, numSigs)
×
556
                        for i := 0; i < int(numSigs); i++ {
×
557
                                if err := ReadElement(r, &sigs[i]); err != nil {
×
558
                                        return err
×
559
                                }
×
560
                        }
561
                }
562

563
                *e = sigs
×
564

565
        case *Sig:
×
566
                if _, err := io.ReadFull(r, e[:]); err != nil {
×
567
                        return err
×
568
                }
×
569
        case *OpaqueReason:
×
570
                var l [2]byte
×
571
                if _, err := io.ReadFull(r, l[:]); err != nil {
×
572
                        return err
×
573
                }
×
574
                reasonLen := binary.BigEndian.Uint16(l[:])
×
575

×
576
                *e = OpaqueReason(make([]byte, reasonLen))
×
577
                if _, err := io.ReadFull(r, *e); err != nil {
×
578
                        return err
×
579
                }
×
580
        case *ErrorData:
×
581
                var l [2]byte
×
582
                if _, err := io.ReadFull(r, l[:]); err != nil {
×
583
                        return err
×
584
                }
×
585
                errorLen := binary.BigEndian.Uint16(l[:])
×
586

×
587
                *e = ErrorData(make([]byte, errorLen))
×
588
                if _, err := io.ReadFull(r, *e); err != nil {
×
589
                        return err
×
590
                }
×
591
        case *PingPayload:
×
592
                var l [2]byte
×
593
                if _, err := io.ReadFull(r, l[:]); err != nil {
×
594
                        return err
×
595
                }
×
596
                pingLen := binary.BigEndian.Uint16(l[:])
×
597

×
598
                *e = PingPayload(make([]byte, pingLen))
×
599
                if _, err := io.ReadFull(r, *e); err != nil {
×
600
                        return err
×
601
                }
×
602
        case *PongPayload:
×
603
                var l [2]byte
×
604
                if _, err := io.ReadFull(r, l[:]); err != nil {
×
605
                        return err
×
606
                }
×
607
                pongLen := binary.BigEndian.Uint16(l[:])
×
608

×
609
                *e = PongPayload(make([]byte, pongLen))
×
610
                if _, err := io.ReadFull(r, *e); err != nil {
×
611
                        return err
×
612
                }
×
613
        case *[33]byte:
×
614
                if _, err := io.ReadFull(r, e[:]); err != nil {
×
615
                        return err
×
616
                }
×
617
        case []byte:
×
618
                if _, err := io.ReadFull(r, e); err != nil {
×
619
                        return err
×
620
                }
×
621
        case *PkScript:
×
622
                pkScript, err := wire.ReadVarBytes(r, 0, 34, "pkscript")
×
623
                if err != nil {
×
624
                        return err
×
625
                }
×
626
                *e = pkScript
×
627
        case *wire.OutPoint:
×
628
                var h [32]byte
×
629
                if _, err = io.ReadFull(r, h[:]); err != nil {
×
630
                        return err
×
631
                }
×
632
                hash, err := chainhash.NewHash(h[:])
×
633
                if err != nil {
×
634
                        return err
×
635
                }
×
636

637
                var idxBytes [2]byte
×
638
                _, err = io.ReadFull(r, idxBytes[:])
×
639
                if err != nil {
×
640
                        return err
×
641
                }
×
642
                index := binary.BigEndian.Uint16(idxBytes[:])
×
643

×
644
                *e = wire.OutPoint{
×
645
                        Hash:  *hash,
×
646
                        Index: uint32(index),
×
647
                }
×
648
        case *FailCode:
×
649
                if err := ReadElement(r, (*uint16)(e)); err != nil {
×
650
                        return err
×
651
                }
×
652
        case *ChannelID:
×
653
                if _, err := io.ReadFull(r, e[:]); err != nil {
×
654
                        return err
×
655
                }
×
656

657
        case *ShortChannelID:
×
658
                var blockHeight [4]byte
×
659
                if _, err = io.ReadFull(r, blockHeight[1:]); err != nil {
×
660
                        return err
×
661
                }
×
662

663
                var txIndex [4]byte
×
664
                if _, err = io.ReadFull(r, txIndex[1:]); err != nil {
×
665
                        return err
×
666
                }
×
667

668
                var txPosition [2]byte
×
669
                if _, err = io.ReadFull(r, txPosition[:]); err != nil {
×
670
                        return err
×
671
                }
×
672

673
                *e = ShortChannelID{
×
674
                        BlockHeight: binary.BigEndian.Uint32(blockHeight[:]),
×
675
                        TxIndex:     binary.BigEndian.Uint32(txIndex[:]),
×
676
                        TxPosition:  binary.BigEndian.Uint16(txPosition[:]),
×
677
                }
×
678

679
        case *[]net.Addr:
×
680
                // First, we'll read the number of total bytes that have been
×
681
                // used to encode the set of addresses.
×
682
                var numAddrsBytes [2]byte
×
683
                if _, err = io.ReadFull(r, numAddrsBytes[:]); err != nil {
×
684
                        return err
×
685
                }
×
686
                addrsLen := binary.BigEndian.Uint16(numAddrsBytes[:])
×
687

×
688
                // With the number of addresses, read, we'll now pull in the
×
689
                // buffer of the encoded addresses into memory.
×
690
                addrs := make([]byte, addrsLen)
×
691
                if _, err := io.ReadFull(r, addrs[:]); err != nil {
×
692
                        return err
×
693
                }
×
694
                addrBuf := bytes.NewReader(addrs)
×
695

×
696
                // Finally, we'll parse the remaining address payload in
×
697
                // series, using the first byte to denote how to decode the
×
698
                // address itself.
×
699
                var (
×
700
                        addresses     []net.Addr
×
701
                        addrBytesRead uint16
×
702
                )
×
703

×
704
                for addrBytesRead < addrsLen {
×
705
                        var descriptor [1]byte
×
706
                        if _, err = io.ReadFull(addrBuf, descriptor[:]); err != nil {
×
707
                                return err
×
708
                        }
×
709

710
                        addrBytesRead++
×
711

×
712
                        var address net.Addr
×
713
                        switch aType := addressType(descriptor[0]); aType {
×
714
                        case noAddr:
×
715
                                addrBytesRead += aType.AddrLen()
×
716
                                continue
×
717

718
                        case tcp4Addr:
×
719
                                var ip [4]byte
×
720
                                if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
×
721
                                        return err
×
722
                                }
×
723

724
                                var port [2]byte
×
725
                                if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
×
726
                                        return err
×
727
                                }
×
728

729
                                address = &net.TCPAddr{
×
730
                                        IP:   net.IP(ip[:]),
×
731
                                        Port: int(binary.BigEndian.Uint16(port[:])),
×
732
                                }
×
733
                                addrBytesRead += aType.AddrLen()
×
734

735
                        case tcp6Addr:
×
736
                                var ip [16]byte
×
737
                                if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
×
738
                                        return err
×
739
                                }
×
740

741
                                var port [2]byte
×
742
                                if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
×
743
                                        return err
×
744
                                }
×
745

746
                                address = &net.TCPAddr{
×
747
                                        IP:   net.IP(ip[:]),
×
748
                                        Port: int(binary.BigEndian.Uint16(port[:])),
×
749
                                }
×
750
                                addrBytesRead += aType.AddrLen()
×
751

752
                        case v2OnionAddr:
×
753
                                var h [tor.V2DecodedLen]byte
×
754
                                if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
×
755
                                        return err
×
756
                                }
×
757

758
                                var p [2]byte
×
759
                                if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
×
760
                                        return err
×
761
                                }
×
762

763
                                onionService := tor.Base32Encoding.EncodeToString(h[:])
×
764
                                onionService += tor.OnionSuffix
×
765
                                port := int(binary.BigEndian.Uint16(p[:]))
×
766

×
767
                                address = &tor.OnionAddr{
×
768
                                        OnionService: onionService,
×
769
                                        Port:         port,
×
770
                                }
×
771
                                addrBytesRead += aType.AddrLen()
×
772

773
                        case v3OnionAddr:
×
774
                                var h [tor.V3DecodedLen]byte
×
775
                                if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
×
776
                                        return err
×
777
                                }
×
778

779
                                var p [2]byte
×
780
                                if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
×
781
                                        return err
×
782
                                }
×
783

784
                                onionService := tor.Base32Encoding.EncodeToString(h[:])
×
785
                                onionService += tor.OnionSuffix
×
786
                                port := int(binary.BigEndian.Uint16(p[:]))
×
787

×
788
                                address = &tor.OnionAddr{
×
789
                                        OnionService: onionService,
×
790
                                        Port:         port,
×
791
                                }
×
792
                                addrBytesRead += aType.AddrLen()
×
793

794
                        default:
×
795
                                return &ErrUnknownAddrType{aType}
×
796
                        }
797

798
                        addresses = append(addresses, address)
×
799
                }
800

801
                *e = addresses
×
802
        case *color.RGBA:
×
803
                err := ReadElements(r,
×
804
                        &e.R,
×
805
                        &e.G,
×
806
                        &e.B,
×
807
                )
×
808
                if err != nil {
×
809
                        return err
×
810
                }
×
811
        case *DeliveryAddress:
×
812
                var addrLen [2]byte
×
813
                if _, err = io.ReadFull(r, addrLen[:]); err != nil {
×
814
                        return err
×
815
                }
×
816
                length := binary.BigEndian.Uint16(addrLen[:])
×
817

×
818
                var addrBytes [deliveryAddressMaxSize]byte
×
819
                if length > deliveryAddressMaxSize {
×
820
                        return fmt.Errorf("cannot read %d bytes into addrBytes", length)
×
821
                }
×
822
                if _, err = io.ReadFull(r, addrBytes[:length]); err != nil {
×
823
                        return err
×
824
                }
×
825
                *e = addrBytes[:length]
×
826
        default:
×
827
                return fmt.Errorf("unknown type in ReadElement: %T", e)
×
828
        }
829

830
        return nil
×
831
}
832

833
// ReadElements deserializes a variable number of elements into the passed
834
// io.Reader, with each element being deserialized according to the ReadElement
835
// function.
836
func ReadElements(r io.Reader, elements ...interface{}) error {
×
837
        for _, element := range elements {
×
838
                err := ReadElement(r, element)
×
839
                if err != nil {
×
840
                        return err
×
841
                }
×
842
        }
843
        return nil
×
844
}
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