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

lightningnetwork / lnd / 17101605539

20 Aug 2025 02:35PM UTC coverage: 57.321% (-9.4%) from 66.68%
17101605539

push

github

web-flow
Merge pull request #10102 from yyforyongyu/fix-UpdatesInHorizon

Catch bad gossip peer and fix `UpdatesInHorizon`

28 of 89 new or added lines in 4 files covered. (31.46%)

29163 existing lines in 459 files now uncovered.

99187 of 173038 relevant lines covered (57.32%)

1.78 hits per line

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

56.52
/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 {
3✔
46
        switch e := element.(type) {
3✔
47
        case keychain.KeyDescriptor:
3✔
48
                if err := binary.Write(w, byteOrder, e.Family); err != nil {
3✔
49
                        return err
×
50
                }
×
51
                if err := binary.Write(w, byteOrder, e.Index); err != nil {
3✔
52
                        return err
×
53
                }
×
54

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

186
        case lnwire.FundingFlag:
3✔
187
                if err := binary.Write(w, byteOrder, e); err != nil {
3✔
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:
3✔
197
                if err := WriteElement(w, uint32(len(e))); err != nil {
3✔
198
                        return err
×
199
                }
×
200

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

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

211
        return nil
3✔
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 {
3✔
217
        for _, element := range elements {
6✔
218
                err := WriteElement(w, element)
3✔
219
                if err != nil {
3✔
220
                        return err
×
221
                }
×
222
        }
223
        return nil
3✔
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 {
3✔
229
        switch e := element.(type) {
3✔
230
        case *keychain.KeyDescriptor:
3✔
231
                if err := binary.Read(r, byteOrder, &e.Family); err != nil {
3✔
232
                        return err
×
233
                }
×
234
                if err := binary.Read(r, byteOrder, &e.Index); err != nil {
3✔
235
                        return err
×
236
                }
×
237

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

243
                if hasPubKey {
6✔
244
                        return ReadElement(r, &e.PubKey)
3✔
245
                }
3✔
246

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

254
                *e = ChannelType(ctype)
3✔
255

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

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

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

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

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

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

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

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

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

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

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

312
                *e = btcutil.Amount(a)
3✔
313

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

320
                *e = lnwire.MilliSatoshi(a)
3✔
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:
3✔
332
                var b [btcec.PubKeyBytesLenCompressed]byte
3✔
333
                if _, err := io.ReadFull(r, b[:]); err != nil {
3✔
334
                        return err
×
335
                }
×
336

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

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

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

355
                *e = producer
3✔
356

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

363
                *e = store
3✔
364

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

371
                *e = tx
3✔
372

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

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

384
                *e = bytes
3✔
385

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

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

398
                *e = msg
3✔
399

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

407
                *e = ChannelStatus(status)
3✔
408

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

414
        case *lnwire.FundingFlag:
3✔
415
                if err := binary.Read(r, byteOrder, e); err != nil {
3✔
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:
3✔
427
                var numAddrs uint32
3✔
428
                if err := ReadElement(r, &numAddrs); err != nil {
3✔
429
                        return err
×
430
                }
×
431

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

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

445
        return nil
3✔
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 {
3✔
452
        for _, element := range elements {
6✔
453
                err := ReadElement(r, element)
3✔
454
                if err != nil {
3✔
UNCOV
455
                        return err
×
UNCOV
456
                }
×
457
        }
458
        return nil
3✔
459
}
460

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

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

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

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

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

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

3✔
492
        return err
3✔
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