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

lightningnetwork / lnd / 16915531902

12 Aug 2025 04:59PM UTC coverage: 66.948%. First build
16915531902

Pull #10151

github

web-flow
Merge d106ffd13 into 4e0af2f49
Pull Request #10151: Refactor Payment PR 5

246 of 321 new or added lines in 20 files covered. (76.64%)

135783 of 202820 relevant lines covered (66.95%)

21592.59 hits per line

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

58.84
/channeldb/codec.go
1
package channeldb
2

3
import (
4
        "bytes"
5
        "encoding/binary"
6
        "fmt"
7
        "io"
8
        "net"
9
        "time"
10

11
        "github.com/btcsuite/btcd/btcec/v2"
12
        "github.com/btcsuite/btcd/btcutil"
13
        "github.com/btcsuite/btcd/chaincfg/chainhash"
14
        "github.com/btcsuite/btcd/wire"
15
        graphdb "github.com/lightningnetwork/lnd/graph/db"
16
        "github.com/lightningnetwork/lnd/keychain"
17
        "github.com/lightningnetwork/lnd/lnwire"
18
        "github.com/lightningnetwork/lnd/shachain"
19
        "github.com/lightningnetwork/lnd/tlv"
20
)
21

22
// UnknownElementType is an error returned when the codec is unable to encode or
23
// decode a particular type.
24
type UnknownElementType struct {
25
        method  string
26
        element interface{}
27
}
28

29
// NewUnknownElementType creates a new UnknownElementType error from the passed
30
// method name and element.
31
func NewUnknownElementType(method string, el interface{}) UnknownElementType {
×
32
        return UnknownElementType{method: method, element: el}
×
33
}
×
34

35
// Error returns the name of the method that encountered the error, as well as
36
// the type that was unsupported.
37
func (e UnknownElementType) Error() string {
×
38
        return fmt.Sprintf("Unknown type in %s: %T", e.method, e.element)
×
39
}
×
40

41
// WriteElement is a one-stop shop to write the big endian representation of
42
// any element which is to be serialized for storage on disk. The passed
43
// io.Writer should be backed by an appropriately sized byte slice, or be able
44
// to dynamically expand to accommodate additional data.
45
func WriteElement(w io.Writer, element interface{}) error {
938,762✔
46
        switch e := element.(type) {
938,762✔
47
        case keychain.KeyDescriptor:
33,053✔
48
                if err := binary.Write(w, byteOrder, e.Family); err != nil {
33,053✔
49
                        return err
×
50
                }
×
51
                if err := binary.Write(w, byteOrder, e.Index); err != nil {
33,053✔
52
                        return err
×
53
                }
×
54

55
                if e.PubKey != nil {
66,096✔
56
                        if err := binary.Write(w, byteOrder, true); err != nil {
33,043✔
57
                                return fmt.Errorf("error writing serialized "+
×
58
                                        "element: %w", err)
×
59
                        }
×
60

61
                        return WriteElement(w, e.PubKey)
33,043✔
62
                }
63

64
                return binary.Write(w, byteOrder, false)
10✔
65
        case ChannelType:
3,247✔
66
                var buf [8]byte
3,247✔
67
                if err := tlv.WriteVarInt(w, uint64(e), &buf); err != nil {
3,247✔
68
                        return err
×
69
                }
×
70

71
        case chainhash.Hash:
4,435✔
72
                if _, err := w.Write(e[:]); err != nil {
4,435✔
73
                        return err
×
74
                }
×
75

76
        case wire.OutPoint:
3,498✔
77
                return graphdb.WriteOutpoint(w, &e)
3,498✔
78

79
        case lnwire.ShortChannelID:
4,638✔
80
                if err := binary.Write(w, byteOrder, e.ToUint64()); err != nil {
4,638✔
81
                        return err
×
82
                }
×
83

84
        case lnwire.ChannelID:
180,213✔
85
                if _, err := w.Write(e[:]); err != nil {
180,213✔
86
                        return err
×
87
                }
×
88

89
        case int64, uint64:
288,839✔
90
                if err := binary.Write(w, byteOrder, e); err != nil {
288,839✔
91
                        return err
×
92
                }
×
93

94
        case uint32:
37,631✔
95
                if err := binary.Write(w, byteOrder, e); err != nil {
37,631✔
96
                        return err
×
97
                }
×
98

99
        case int32:
28,388✔
100
                if err := binary.Write(w, byteOrder, e); err != nil {
28,388✔
101
                        return err
×
102
                }
×
103

104
        case uint16:
38,346✔
105
                if err := binary.Write(w, byteOrder, e); err != nil {
38,346✔
106
                        return err
×
107
                }
×
108

109
        case uint8:
1,298✔
110
                if err := binary.Write(w, byteOrder, e); err != nil {
1,298✔
111
                        return err
×
112
                }
×
113

114
        case bool:
40,082✔
115
                if err := binary.Write(w, byteOrder, e); err != nil {
40,082✔
116
                        return err
×
117
                }
×
118

119
        case btcutil.Amount:
33,870✔
120
                if err := binary.Write(w, byteOrder, uint64(e)); err != nil {
33,870✔
121
                        return err
×
122
                }
×
123

124
        case lnwire.MilliSatoshi:
66,090✔
125
                if err := binary.Write(w, byteOrder, uint64(e)); err != nil {
66,090✔
126
                        return err
×
127
                }
×
128

129
        case *btcec.PrivateKey:
1✔
130
                b := e.Serialize()
1✔
131
                if _, err := w.Write(b); err != nil {
1✔
132
                        return err
×
133
                }
×
134

135
        case *btcec.PublicKey:
43,764✔
136
                b := e.SerializeCompressed()
43,764✔
137
                if _, err := w.Write(b); err != nil {
43,764✔
138
                        return err
×
139
                }
×
140

141
        case shachain.Producer:
3,833✔
142
                return e.Encode(w)
3,833✔
143

144
        case shachain.Store:
3,833✔
145
                return e.Encode(w)
3,833✔
146

147
        case *wire.MsgTx:
10,419✔
148
                return e.Serialize(w)
10,419✔
149

150
        case [32]byte:
28,463✔
151
                if _, err := w.Write(e[:]); err != nil {
28,463✔
152
                        return err
×
153
                }
×
154

155
        case []byte:
68,040✔
156
                if err := wire.WriteVarBytes(w, 0, e); err != nil {
68,040✔
157
                        return err
×
158
                }
×
159

160
        case lnwire.Message:
7,353✔
161
                var msgBuf bytes.Buffer
7,353✔
162
                if _, err := lnwire.WriteMessage(&msgBuf, e, 0); err != nil {
7,353✔
163
                        return err
×
164
                }
×
165

166
                msgLen := uint16(len(msgBuf.Bytes()))
7,353✔
167
                if err := WriteElements(w, msgLen); err != nil {
7,353✔
168
                        return err
×
169
                }
×
170

171
                if _, err := w.Write(msgBuf.Bytes()); err != nil {
7,353✔
172
                        return err
×
173
                }
×
174

175
        case ChannelStatus:
3,247✔
176
                var buf [8]byte
3,247✔
177
                if err := tlv.WriteVarInt(w, uint64(e), &buf); err != nil {
3,247✔
178
                        return err
×
179
                }
×
180

181
        case ClosureType:
134✔
182
                if err := binary.Write(w, byteOrder, e); err != nil {
134✔
183
                        return err
×
184
                }
×
185

186
        case lnwire.FundingFlag:
3,247✔
187
                if err := binary.Write(w, byteOrder, e); err != nil {
3,247✔
188
                        return err
×
189
                }
×
190

191
        case net.Addr:
×
192
                if err := graphdb.SerializeAddr(w, e); err != nil {
×
193
                        return err
×
194
                }
×
195

196
        case []net.Addr:
206✔
197
                if err := WriteElement(w, uint32(len(e))); err != nil {
206✔
198
                        return err
×
199
                }
×
200

201
                for _, addr := range e {
718✔
202
                        if err := graphdb.SerializeAddr(w, addr); err != nil {
512✔
203
                                return err
×
204
                        }
×
205
                }
206

207
        default:
2,669✔
208
                return UnknownElementType{"WriteElement", e}
2,669✔
209
        }
210

211
        return nil
881,475✔
212
}
213

214
// WriteElements is writes each element in the elements slice to the passed
215
// io.Writer using WriteElement.
216
func WriteElements(w io.Writer, elements ...interface{}) error {
75,909✔
217
        for _, element := range elements {
594,909✔
218
                err := WriteElement(w, element)
519,000✔
219
                if err != nil {
519,000✔
220
                        return err
×
221
                }
×
222
        }
223
        return nil
75,909✔
224
}
225

226
// ReadElement is a one-stop utility function to deserialize any datastructure
227
// encoded using the serialization format of the database.
228
func ReadElement(r io.Reader, element interface{}) error {
1,566,306✔
229
        switch e := element.(type) {
1,566,306✔
230
        case *keychain.KeyDescriptor:
72,433✔
231
                if err := binary.Read(r, byteOrder, &e.Family); err != nil {
72,433✔
232
                        return err
×
233
                }
×
234
                if err := binary.Read(r, byteOrder, &e.Index); err != nil {
72,433✔
235
                        return err
×
236
                }
×
237

238
                var hasPubKey bool
72,433✔
239
                if err := binary.Read(r, byteOrder, &hasPubKey); err != nil {
72,433✔
240
                        return err
×
241
                }
×
242

243
                if hasPubKey {
144,846✔
244
                        return ReadElement(r, &e.PubKey)
72,413✔
245
                }
72,413✔
246

247
        case *ChannelType:
7,185✔
248
                var buf [8]byte
7,185✔
249
                ctype, err := tlv.ReadVarInt(r, &buf)
7,185✔
250
                if err != nil {
7,185✔
251
                        return err
×
252
                }
×
253

254
                *e = ChannelType(ctype)
7,185✔
255

256
        case *chainhash.Hash:
7,445✔
257
                if _, err := io.ReadFull(r, e[:]); err != nil {
7,445✔
258
                        return err
×
259
                }
×
260

261
        case *wire.OutPoint:
7,318✔
262
                return graphdb.ReadOutpoint(r, e)
7,318✔
263

264
        case *lnwire.ShortChannelID:
8,439✔
265
                var a uint64
8,439✔
266
                if err := binary.Read(r, byteOrder, &a); err != nil {
8,439✔
267
                        return err
×
268
                }
×
269
                *e = lnwire.NewShortChanIDFromInt(a)
8,439✔
270

271
        case *lnwire.ChannelID:
180,451✔
272
                if _, err := io.ReadFull(r, e[:]); err != nil {
180,451✔
273
                        return err
×
274
                }
×
275

276
        case *int64, *uint64:
403,446✔
277
                if err := binary.Read(r, byteOrder, e); err != nil {
403,456✔
278
                        return err
10✔
279
                }
10✔
280

281
        case *uint32:
81,965✔
282
                if err := binary.Read(r, byteOrder, e); err != nil {
81,965✔
283
                        return err
×
284
                }
×
285

286
        case *int32:
64,421✔
287
                if err := binary.Read(r, byteOrder, e); err != nil {
64,421✔
288
                        return err
×
289
                }
×
290

291
        case *uint16:
65,320✔
292
                if err := binary.Read(r, byteOrder, e); err != nil {
65,320✔
293
                        return err
×
294
                }
×
295

296
        case *uint8:
1,832✔
297
                if err := binary.Read(r, byteOrder, e); err != nil {
1,832✔
298
                        return err
×
299
                }
×
300

301
        case *bool:
85,172✔
302
                if err := binary.Read(r, byteOrder, e); err != nil {
85,172✔
303
                        return err
×
304
                }
×
305

306
        case *btcutil.Amount:
69,433✔
307
                var a uint64
69,433✔
308
                if err := binary.Read(r, byteOrder, &a); err != nil {
69,433✔
309
                        return err
×
310
                }
×
311

312
                *e = btcutil.Amount(a)
69,433✔
313

314
        case *lnwire.MilliSatoshi:
143,359✔
315
                var a uint64
143,359✔
316
                if err := binary.Read(r, byteOrder, &a); err != nil {
143,359✔
317
                        return err
×
318
                }
×
319

320
                *e = lnwire.MilliSatoshi(a)
143,359✔
321

322
        case **btcec.PrivateKey:
×
323
                var b [btcec.PrivKeyBytesLen]byte
×
324
                if _, err := io.ReadFull(r, b[:]); err != nil {
×
325
                        return err
×
326
                }
×
327

328
                priv, _ := btcec.PrivKeyFromBytes(b[:])
×
329
                *e = priv
×
330

331
        case **btcec.PublicKey:
94,474✔
332
                var b [btcec.PubKeyBytesLenCompressed]byte
94,474✔
333
                if _, err := io.ReadFull(r, b[:]); err != nil {
94,474✔
334
                        return err
×
335
                }
×
336

337
                pubKey, err := btcec.ParsePubKey(b[:])
94,474✔
338
                if err != nil {
94,474✔
339
                        return err
×
340
                }
×
341
                *e = pubKey
94,474✔
342

343
        case *shachain.Producer:
7,200✔
344
                var root [32]byte
7,200✔
345
                if _, err := io.ReadFull(r, root[:]); err != nil {
7,200✔
346
                        return err
×
347
                }
×
348

349
                // TODO(roasbeef): remove
350
                producer, err := shachain.NewRevocationProducerFromBytes(root[:])
7,200✔
351
                if err != nil {
7,200✔
352
                        return err
×
353
                }
×
354

355
                *e = producer
7,200✔
356

357
        case *shachain.Store:
7,200✔
358
                store, err := shachain.NewRevocationStoreFromBytes(r)
7,200✔
359
                if err != nil {
7,200✔
360
                        return err
×
361
                }
×
362

363
                *e = store
7,200✔
364

365
        case **wire.MsgTx:
20,279✔
366
                tx := wire.NewMsgTx(2)
20,279✔
367
                if err := tx.Deserialize(r); err != nil {
20,279✔
368
                        return err
×
369
                }
×
370

371
                *e = tx
20,279✔
372

373
        case *[32]byte:
65,129✔
374
                if _, err := io.ReadFull(r, e[:]); err != nil {
65,129✔
375
                        return err
×
376
                }
×
377

378
        case *[]byte:
150,353✔
379
                bytes, err := wire.ReadVarBytes(r, 0, 66000, "[]byte")
150,353✔
380
                if err != nil {
150,353✔
381
                        return err
×
382
                }
×
383

384
                *e = bytes
150,353✔
385

386
        case *lnwire.Message:
5,532✔
387
                var msgLen uint16
5,532✔
388
                if err := ReadElement(r, &msgLen); err != nil {
5,532✔
389
                        return err
×
390
                }
×
391

392
                msgReader := io.LimitReader(r, int64(msgLen))
5,532✔
393
                msg, err := lnwire.ReadMessage(msgReader, 0)
5,532✔
394
                if err != nil {
5,532✔
395
                        return err
×
396
                }
×
397

398
                *e = msg
5,532✔
399

400
        case *ChannelStatus:
7,185✔
401
                var buf [8]byte
7,185✔
402
                status, err := tlv.ReadVarInt(r, &buf)
7,185✔
403
                if err != nil {
7,185✔
404
                        return err
×
405
                }
×
406

407
                *e = ChannelStatus(status)
7,185✔
408

409
        case *ClosureType:
133✔
410
                if err := binary.Read(r, byteOrder, e); err != nil {
133✔
411
                        return err
×
412
                }
×
413

414
        case *lnwire.FundingFlag:
7,185✔
415
                if err := binary.Read(r, byteOrder, e); err != nil {
7,185✔
416
                        return err
×
417
                }
×
418

419
        case *net.Addr:
×
420
                addr, err := graphdb.DeserializeAddr(r)
×
421
                if err != nil {
×
422
                        return err
×
423
                }
×
424
                *e = addr
×
425

426
        case *[]net.Addr:
318✔
427
                var numAddrs uint32
318✔
428
                if err := ReadElement(r, &numAddrs); err != nil {
318✔
429
                        return err
×
430
                }
×
431

432
                *e = make([]net.Addr, numAddrs)
318✔
433
                for i := uint32(0); i < numAddrs; i++ {
948✔
434
                        addr, err := graphdb.DeserializeAddr(r)
630✔
435
                        if err != nil {
630✔
436
                                return err
×
437
                        }
×
438
                        (*e)[i] = addr
630✔
439
                }
440

441
        default:
3,174✔
442
                return UnknownElementType{"ReadElement", e}
3,174✔
443
        }
444

445
        return nil
1,483,400✔
446
}
447

448
// ReadElements deserializes a variable number of elements into the passed
449
// io.Reader, with each element being deserialized according to the ReadElement
450
// function.
451
func ReadElements(r io.Reader, elements ...interface{}) error {
132,046✔
452
        for _, element := range elements {
1,209,897✔
453
                err := ReadElement(r, element)
1,077,851✔
454
                if err != nil {
1,077,861✔
455
                        return err
10✔
456
                }
10✔
457
        }
458
        return nil
132,036✔
459
}
460

461
// deserializeTime deserializes time as unix nanoseconds.
462
func deserializeTime(r io.Reader) (time.Time, error) {
5✔
463
        var scratch [8]byte
5✔
464
        if _, err := io.ReadFull(r, scratch[:]); err != nil {
5✔
NEW
465
                return time.Time{}, err
×
NEW
466
        }
×
467

468
        // Convert to time.Time. Interpret unix nano time zero as a zero
469
        // time.Time value.
470
        unixNano := byteOrder.Uint64(scratch[:])
5✔
471
        if unixNano == 0 {
5✔
NEW
472
                return time.Time{}, nil
×
NEW
473
        }
×
474

475
        return time.Unix(0, int64(unixNano)), nil
5✔
476
}
477

478
// serializeTime serializes time as unix nanoseconds.
479
func serializeTime(w io.Writer, t time.Time) error {
5✔
480
        var scratch [8]byte
5✔
481

5✔
482
        // Convert to unix nano seconds, but only if time is non-zero. Calling
5✔
483
        // UnixNano() on a zero time yields an undefined result.
5✔
484
        var unixNano int64
5✔
485
        if !t.IsZero() {
10✔
486
                unixNano = t.UnixNano()
5✔
487
        }
5✔
488

489
        byteOrder.PutUint64(scratch[:], uint64(unixNano))
5✔
490
        _, err := w.Write(scratch[:])
5✔
491

5✔
492
        return err
5✔
493
}
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