• 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/migration21/legacy/legacy_decoding.go
1
package legacy
2

3
import (
4
        "bytes"
5
        "encoding/binary"
6
        "errors"
7
        "io"
8

9
        lnwire "github.com/lightningnetwork/lnd/channeldb/migration/lnwire21"
10
        "github.com/lightningnetwork/lnd/channeldb/migration21/common"
11
        "github.com/lightningnetwork/lnd/kvdb"
12
)
13

14
func deserializeHtlcs(r io.Reader) ([]common.HTLC, error) {
×
15
        var numHtlcs uint16
×
16
        if err := ReadElement(r, &numHtlcs); err != nil {
×
17
                return nil, err
×
18
        }
×
19

20
        var htlcs []common.HTLC
×
21
        if numHtlcs == 0 {
×
22
                return htlcs, nil
×
23
        }
×
24

25
        htlcs = make([]common.HTLC, numHtlcs)
×
26
        for i := uint16(0); i < numHtlcs; i++ {
×
27
                if err := ReadElements(r,
×
28
                        &htlcs[i].Signature, &htlcs[i].RHash, &htlcs[i].Amt,
×
29
                        &htlcs[i].RefundTimeout, &htlcs[i].OutputIndex,
×
30
                        &htlcs[i].Incoming, &htlcs[i].OnionBlob,
×
31
                        &htlcs[i].HtlcIndex, &htlcs[i].LogIndex,
×
32
                ); err != nil {
×
33
                        return htlcs, err
×
34
                }
×
35
        }
36

37
        return htlcs, nil
×
38
}
39

40
func DeserializeLogUpdates(r io.Reader) ([]common.LogUpdate, error) {
×
41
        var numUpdates uint16
×
42
        if err := binary.Read(r, byteOrder, &numUpdates); err != nil {
×
43
                return nil, err
×
44
        }
×
45

46
        logUpdates := make([]common.LogUpdate, numUpdates)
×
47
        for i := 0; i < int(numUpdates); i++ {
×
48
                err := ReadElements(r,
×
49
                        &logUpdates[i].LogIndex, &logUpdates[i].UpdateMsg,
×
50
                )
×
51
                if err != nil {
×
52
                        return nil, err
×
53
                }
×
54
        }
55

56
        return logUpdates, nil
×
57
}
58

59
func deserializeChanCommit(r io.Reader) (common.ChannelCommitment, error) {
×
60
        var c common.ChannelCommitment
×
61

×
62
        err := ReadElements(r,
×
63
                &c.CommitHeight, &c.LocalLogIndex, &c.LocalHtlcIndex, &c.RemoteLogIndex,
×
64
                &c.RemoteHtlcIndex, &c.LocalBalance, &c.RemoteBalance,
×
65
                &c.CommitFee, &c.FeePerKw, &c.CommitTx, &c.CommitSig,
×
66
        )
×
67
        if err != nil {
×
68
                return c, err
×
69
        }
×
70

71
        c.Htlcs, err = deserializeHtlcs(r)
×
72
        if err != nil {
×
73
                return c, err
×
74
        }
×
75

76
        return c, nil
×
77
}
78

79
func DeserializeCommitDiff(r io.Reader) (*common.CommitDiff, error) {
×
80
        var (
×
81
                d   common.CommitDiff
×
82
                err error
×
83
        )
×
84

×
85
        d.Commitment, err = deserializeChanCommit(r)
×
86
        if err != nil {
×
87
                return nil, err
×
88
        }
×
89

90
        d.CommitSig = &lnwire.CommitSig{}
×
91
        if err := d.CommitSig.Decode(r, 0); err != nil {
×
92
                return nil, err
×
93
        }
×
94

95
        d.LogUpdates, err = DeserializeLogUpdates(r)
×
96
        if err != nil {
×
97
                return nil, err
×
98
        }
×
99

100
        var numOpenRefs uint16
×
101
        if err := binary.Read(r, byteOrder, &numOpenRefs); err != nil {
×
102
                return nil, err
×
103
        }
×
104

105
        d.OpenedCircuitKeys = make([]common.CircuitKey, numOpenRefs)
×
106
        for i := 0; i < int(numOpenRefs); i++ {
×
107
                err := ReadElements(r,
×
108
                        &d.OpenedCircuitKeys[i].ChanID,
×
109
                        &d.OpenedCircuitKeys[i].HtlcID)
×
110
                if err != nil {
×
111
                        return nil, err
×
112
                }
×
113
        }
114

115
        var numClosedRefs uint16
×
116
        if err := binary.Read(r, byteOrder, &numClosedRefs); err != nil {
×
117
                return nil, err
×
118
        }
×
119

120
        d.ClosedCircuitKeys = make([]common.CircuitKey, numClosedRefs)
×
121
        for i := 0; i < int(numClosedRefs); i++ {
×
122
                err := ReadElements(r,
×
123
                        &d.ClosedCircuitKeys[i].ChanID,
×
124
                        &d.ClosedCircuitKeys[i].HtlcID)
×
125
                if err != nil {
×
126
                        return nil, err
×
127
                }
×
128
        }
129

130
        return &d, nil
×
131
}
132

133
func serializeHtlcs(b io.Writer, htlcs ...common.HTLC) error {
×
134
        numHtlcs := uint16(len(htlcs))
×
135
        if err := WriteElement(b, numHtlcs); err != nil {
×
136
                return err
×
137
        }
×
138

139
        for _, htlc := range htlcs {
×
140
                if err := WriteElements(b,
×
141
                        htlc.Signature, htlc.RHash, htlc.Amt, htlc.RefundTimeout,
×
142
                        htlc.OutputIndex, htlc.Incoming, htlc.OnionBlob,
×
143
                        htlc.HtlcIndex, htlc.LogIndex,
×
144
                ); err != nil {
×
145
                        return err
×
146
                }
×
147
        }
148

149
        return nil
×
150
}
151

152
func serializeChanCommit(w io.Writer, c *common.ChannelCommitment) error {
×
153
        if err := WriteElements(w,
×
154
                c.CommitHeight, c.LocalLogIndex, c.LocalHtlcIndex,
×
155
                c.RemoteLogIndex, c.RemoteHtlcIndex, c.LocalBalance,
×
156
                c.RemoteBalance, c.CommitFee, c.FeePerKw, c.CommitTx,
×
157
                c.CommitSig,
×
158
        ); err != nil {
×
159
                return err
×
160
        }
×
161

162
        return serializeHtlcs(w, c.Htlcs...)
×
163
}
164

165
func SerializeLogUpdates(w io.Writer, logUpdates []common.LogUpdate) error {
×
166
        numUpdates := uint16(len(logUpdates))
×
167
        if err := binary.Write(w, byteOrder, numUpdates); err != nil {
×
168
                return err
×
169
        }
×
170

171
        for _, diff := range logUpdates {
×
172
                err := WriteElements(w, diff.LogIndex, diff.UpdateMsg)
×
173
                if err != nil {
×
174
                        return err
×
175
                }
×
176
        }
177

178
        return nil
×
179
}
180

181
func SerializeCommitDiff(w io.Writer, diff *common.CommitDiff) error { // nolint: dupl
×
182
        if err := serializeChanCommit(w, &diff.Commitment); err != nil {
×
183
                return err
×
184
        }
×
185

186
        if err := diff.CommitSig.Encode(w, 0); err != nil {
×
187
                return err
×
188
        }
×
189

190
        if err := SerializeLogUpdates(w, diff.LogUpdates); err != nil {
×
191
                return err
×
192
        }
×
193

194
        numOpenRefs := uint16(len(diff.OpenedCircuitKeys))
×
195
        if err := binary.Write(w, byteOrder, numOpenRefs); err != nil {
×
196
                return err
×
197
        }
×
198

199
        for _, openRef := range diff.OpenedCircuitKeys {
×
200
                err := WriteElements(w, openRef.ChanID, openRef.HtlcID)
×
201
                if err != nil {
×
202
                        return err
×
203
                }
×
204
        }
205

206
        numClosedRefs := uint16(len(diff.ClosedCircuitKeys))
×
207
        if err := binary.Write(w, byteOrder, numClosedRefs); err != nil {
×
208
                return err
×
209
        }
×
210

211
        for _, closedRef := range diff.ClosedCircuitKeys {
×
212
                err := WriteElements(w, closedRef.ChanID, closedRef.HtlcID)
×
213
                if err != nil {
×
214
                        return err
×
215
                }
×
216
        }
217

218
        return nil
×
219
}
220

221
func DeserializeNetworkResult(r io.Reader) (*common.NetworkResult, error) {
×
222
        var (
×
223
                err error
×
224
        )
×
225

×
226
        n := &common.NetworkResult{}
×
227

×
228
        n.Msg, err = lnwire.ReadMessage(r, 0)
×
229
        if err != nil {
×
230
                return nil, err
×
231
        }
×
232

233
        if err := ReadElements(r,
×
234
                &n.Unencrypted, &n.IsResolution,
×
235
        ); err != nil {
×
236
                return nil, err
×
237
        }
×
238

239
        return n, nil
×
240
}
241

242
func SerializeNetworkResult(w io.Writer, n *common.NetworkResult) error {
×
243
        if _, err := lnwire.WriteMessage(w, n.Msg, 0); err != nil {
×
244
                return err
×
245
        }
×
246

247
        return WriteElements(w, n.Unencrypted, n.IsResolution)
×
248
}
249

250
func readChanConfig(b io.Reader, c *common.ChannelConfig) error { // nolint: dupl
×
251
        return ReadElements(b,
×
252
                &c.DustLimit, &c.MaxPendingAmount, &c.ChanReserve,
×
253
                &c.MinHTLC, &c.MaxAcceptedHtlcs, &c.CsvDelay,
×
254
                &c.MultiSigKey, &c.RevocationBasePoint,
×
255
                &c.PaymentBasePoint, &c.DelayBasePoint,
×
256
                &c.HtlcBasePoint,
×
257
        )
×
258
}
×
259

260
func DeserializeCloseChannelSummary(
261
        r io.Reader) (*common.ChannelCloseSummary, error) { // nolint: dupl
×
262

×
263
        c := &common.ChannelCloseSummary{}
×
264

×
265
        err := ReadElements(r,
×
266
                &c.ChanPoint, &c.ShortChanID, &c.ChainHash, &c.ClosingTXID,
×
267
                &c.CloseHeight, &c.RemotePub, &c.Capacity, &c.SettledBalance,
×
268
                &c.TimeLockedBalance, &c.CloseType, &c.IsPending,
×
269
        )
×
270
        if err != nil {
×
271
                return nil, err
×
272
        }
×
273

274
        // We'll now check to see if the channel close summary was encoded with
275
        // any of the additional optional fields.
276
        var hasNewFields bool
×
277
        err = ReadElements(r, &hasNewFields)
×
278
        if err != nil {
×
279
                return nil, err
×
280
        }
×
281

282
        // If fields are not present, we can return.
283
        if !hasNewFields {
×
284
                return c, nil
×
285
        }
×
286

287
        // Otherwise read the new fields.
288
        if err := ReadElements(r, &c.RemoteCurrentRevocation); err != nil {
×
289
                return nil, err
×
290
        }
×
291

292
        if err := readChanConfig(r, &c.LocalChanConfig); err != nil {
×
293
                return nil, err
×
294
        }
×
295

296
        // Finally, we'll attempt to read the next unrevoked commitment point
297
        // for the remote party. If we closed the channel before receiving a
298
        // funding locked message then this might not be present. A boolean
299
        // indicating whether the field is present will come first.
300
        var hasRemoteNextRevocation bool
×
301
        err = ReadElements(r, &hasRemoteNextRevocation)
×
302
        if err != nil {
×
303
                return nil, err
×
304
        }
×
305

306
        // If this field was written, read it.
307
        if hasRemoteNextRevocation {
×
308
                err = ReadElements(r, &c.RemoteNextRevocation)
×
309
                if err != nil {
×
310
                        return nil, err
×
311
                }
×
312
        }
313

314
        // Check if we have a channel sync message to read.
315
        var hasChanSyncMsg bool
×
316
        err = ReadElements(r, &hasChanSyncMsg)
×
317
        if err == io.EOF {
×
318
                return c, nil
×
319
        } else if err != nil {
×
320
                return nil, err
×
321
        }
×
322

323
        // If a chan sync message is present, read it.
324
        if hasChanSyncMsg {
×
325
                // We must pass in reference to a lnwire.Message for the codec
×
326
                // to support it.
×
327
                msg, err := lnwire.ReadMessage(r, 0)
×
328
                if err != nil {
×
329
                        return nil, err
×
330
                }
×
331

332
                chanSync, ok := msg.(*lnwire.ChannelReestablish)
×
333
                if !ok {
×
334
                        return nil, errors.New("unable cast db Message to " +
×
335
                                "ChannelReestablish")
×
336
                }
×
337
                c.LastChanSyncMsg = chanSync
×
338
        }
339

340
        return c, nil
×
341
}
342

343
func writeChanConfig(b io.Writer, c *common.ChannelConfig) error { // nolint: dupl
×
344
        return WriteElements(b,
×
345
                c.DustLimit, c.MaxPendingAmount, c.ChanReserve, c.MinHTLC,
×
346
                c.MaxAcceptedHtlcs, c.CsvDelay, c.MultiSigKey,
×
347
                c.RevocationBasePoint, c.PaymentBasePoint, c.DelayBasePoint,
×
348
                c.HtlcBasePoint,
×
349
        )
×
350
}
×
351

352
func SerializeChannelCloseSummary(w io.Writer, cs *common.ChannelCloseSummary) error {
×
353
        err := WriteElements(w,
×
354
                cs.ChanPoint, cs.ShortChanID, cs.ChainHash, cs.ClosingTXID,
×
355
                cs.CloseHeight, cs.RemotePub, cs.Capacity, cs.SettledBalance,
×
356
                cs.TimeLockedBalance, cs.CloseType, cs.IsPending,
×
357
        )
×
358
        if err != nil {
×
359
                return err
×
360
        }
×
361

362
        // If this is a close channel summary created before the addition of
363
        // the new fields, then we can exit here.
364
        if cs.RemoteCurrentRevocation == nil {
×
365
                return WriteElements(w, false)
×
366
        }
×
367

368
        // If fields are present, write boolean to indicate this, and continue.
369
        if err := WriteElements(w, true); err != nil {
×
370
                return err
×
371
        }
×
372

373
        if err := WriteElements(w, cs.RemoteCurrentRevocation); err != nil {
×
374
                return err
×
375
        }
×
376

377
        if err := writeChanConfig(w, &cs.LocalChanConfig); err != nil {
×
378
                return err
×
379
        }
×
380

381
        // The RemoteNextRevocation field is optional, as it's possible for a
382
        // channel to be closed before we learn of the next unrevoked
383
        // revocation point for the remote party. Write a boolean indicating
384
        // whether this field is present or not.
385
        if err := WriteElements(w, cs.RemoteNextRevocation != nil); err != nil {
×
386
                return err
×
387
        }
×
388

389
        // Write the field, if present.
390
        if cs.RemoteNextRevocation != nil {
×
391
                if err = WriteElements(w, cs.RemoteNextRevocation); err != nil {
×
392
                        return err
×
393
                }
×
394
        }
395

396
        // Write whether the channel sync message is present.
397
        if err := WriteElements(w, cs.LastChanSyncMsg != nil); err != nil {
×
398
                return err
×
399
        }
×
400

401
        // Write the channel sync message, if present.
402
        if cs.LastChanSyncMsg != nil {
×
403
                _, err = lnwire.WriteMessage(w, cs.LastChanSyncMsg, 0)
×
404
                if err != nil {
×
405
                        return err
×
406
                }
×
407
        }
408

409
        return nil
×
410
}
411

412
// ErrCorruptedFwdPkg signals that the on-disk structure of the forwarding
413
// package has potentially been mangled.
414
var ErrCorruptedFwdPkg = errors.New("fwding package db has been corrupted")
415

416
var (
417
        // fwdPackagesKey is the root-level bucket that all forwarding packages
418
        // are written. This bucket is further subdivided based on the short
419
        // channel ID of each channel.
420
        fwdPackagesKey = []byte("fwd-packages")
421

422
        // addBucketKey is the bucket to which all Add log updates are written.
423
        addBucketKey = []byte("add-updates")
424

425
        // failSettleBucketKey is the bucket to which all Settle/Fail log
426
        // updates are written.
427
        failSettleBucketKey = []byte("fail-settle-updates")
428

429
        // fwdFilterKey is a key used to write the set of Adds that passed
430
        // validation and are to be forwarded to the switch.
431
        // NOTE: The presence of this key within a forwarding package indicates
432
        // that the package has reached FwdStateProcessed.
433
        fwdFilterKey = []byte("fwd-filter-key")
434

435
        // ackFilterKey is a key used to access the PkgFilter indicating which
436
        // Adds have received a Settle/Fail. This response may come from a
437
        // number of sources, including: exitHop settle/fails, switch failures,
438
        // chain arbiter interjections, as well as settle/fails from the
439
        // next hop in the route.
440
        ackFilterKey = []byte("ack-filter-key")
441

442
        // settleFailFilterKey is a key used to access the PkgFilter indicating
443
        // which Settles/Fails in have been received and processed by the link
444
        // that originally received the Add.
445
        settleFailFilterKey = []byte("settle-fail-filter-key")
446
)
447

448
func makeLogKey(updateNum uint64) [8]byte {
×
449
        var key [8]byte
×
450
        byteOrder.PutUint64(key[:], updateNum)
×
451
        return key
×
452
}
×
453

454
// uint16Key writes the provided 16-bit unsigned integer to a 2-byte slice.
455
func uint16Key(i uint16) []byte {
×
456
        key := make([]byte, 2)
×
457
        byteOrder.PutUint16(key, i)
×
458
        return key
×
459
}
×
460

461
// ChannelPackager is used by a channel to manage the lifecycle of its forwarding
462
// packages. The packager is tied to a particular source channel ID, allowing it
463
// to create and edit its own packages. Each packager also has the ability to
464
// remove fail/settle htlcs that correspond to an add contained in one of
465
// source's packages.
466
type ChannelPackager struct {
467
        source lnwire.ShortChannelID
468
}
469

470
// NewChannelPackager creates a new packager for a single channel.
471
func NewChannelPackager(source lnwire.ShortChannelID) *ChannelPackager {
×
472
        return &ChannelPackager{
×
473
                source: source,
×
474
        }
×
475
}
×
476

477
// AddFwdPkg writes a newly locked in forwarding package to disk.
478
func (*ChannelPackager) AddFwdPkg(tx kvdb.RwTx, fwdPkg *common.FwdPkg) error { // nolint: dupl
×
479
        fwdPkgBkt, err := tx.CreateTopLevelBucket(fwdPackagesKey)
×
480
        if err != nil {
×
481
                return err
×
482
        }
×
483

484
        source := makeLogKey(fwdPkg.Source.ToUint64())
×
485
        sourceBkt, err := fwdPkgBkt.CreateBucketIfNotExists(source[:])
×
486
        if err != nil {
×
487
                return err
×
488
        }
×
489

490
        heightKey := makeLogKey(fwdPkg.Height)
×
491
        heightBkt, err := sourceBkt.CreateBucketIfNotExists(heightKey[:])
×
492
        if err != nil {
×
493
                return err
×
494
        }
×
495

496
        // Write ADD updates we received at this commit height.
497
        addBkt, err := heightBkt.CreateBucketIfNotExists(addBucketKey)
×
498
        if err != nil {
×
499
                return err
×
500
        }
×
501

502
        // Write SETTLE/FAIL updates we received at this commit height.
503
        failSettleBkt, err := heightBkt.CreateBucketIfNotExists(failSettleBucketKey)
×
504
        if err != nil {
×
505
                return err
×
506
        }
×
507

508
        for i := range fwdPkg.Adds {
×
509
                err = putLogUpdate(addBkt, uint16(i), &fwdPkg.Adds[i])
×
510
                if err != nil {
×
511
                        return err
×
512
                }
×
513
        }
514

515
        // Persist the initialized pkg filter, which will be used to determine
516
        // when we can remove this forwarding package from disk.
517
        var ackFilterBuf bytes.Buffer
×
518
        if err := fwdPkg.AckFilter.Encode(&ackFilterBuf); err != nil {
×
519
                return err
×
520
        }
×
521

522
        if err := heightBkt.Put(ackFilterKey, ackFilterBuf.Bytes()); err != nil {
×
523
                return err
×
524
        }
×
525

526
        for i := range fwdPkg.SettleFails {
×
527
                err = putLogUpdate(failSettleBkt, uint16(i), &fwdPkg.SettleFails[i])
×
528
                if err != nil {
×
529
                        return err
×
530
                }
×
531
        }
532

533
        var settleFailFilterBuf bytes.Buffer
×
534
        err = fwdPkg.SettleFailFilter.Encode(&settleFailFilterBuf)
×
535
        if err != nil {
×
536
                return err
×
537
        }
×
538

539
        return heightBkt.Put(settleFailFilterKey, settleFailFilterBuf.Bytes())
×
540
}
541

542
// putLogUpdate writes an htlc to the provided `bkt`, using `index` as the key.
543
func putLogUpdate(bkt kvdb.RwBucket, idx uint16, htlc *common.LogUpdate) error {
×
544
        var b bytes.Buffer
×
545
        if err := serializeLogUpdate(&b, htlc); err != nil {
×
546
                return err
×
547
        }
×
548

549
        return bkt.Put(uint16Key(idx), b.Bytes())
×
550
}
551

552
// LoadFwdPkgs scans the forwarding log for any packages that haven't been
553
// processed, and returns their deserialized log updates in a map indexed by the
554
// remote commitment height at which the updates were locked in.
555
func (p *ChannelPackager) LoadFwdPkgs(tx kvdb.RTx) ([]*common.FwdPkg, error) {
×
556
        return loadChannelFwdPkgs(tx, p.source)
×
557
}
×
558

559
// loadChannelFwdPkgs loads all forwarding packages owned by `source`.
560
func loadChannelFwdPkgs(tx kvdb.RTx, source lnwire.ShortChannelID) ([]*common.FwdPkg, error) { // nolint: dupl
×
561
        fwdPkgBkt := tx.ReadBucket(fwdPackagesKey)
×
562
        if fwdPkgBkt == nil {
×
563
                return nil, nil
×
564
        }
×
565

566
        sourceKey := makeLogKey(source.ToUint64())
×
567
        sourceBkt := fwdPkgBkt.NestedReadBucket(sourceKey[:])
×
568
        if sourceBkt == nil {
×
569
                return nil, nil
×
570
        }
×
571

572
        var heights []uint64
×
573
        if err := sourceBkt.ForEach(func(k, _ []byte) error {
×
574
                if len(k) != 8 {
×
575
                        return ErrCorruptedFwdPkg
×
576
                }
×
577

578
                heights = append(heights, byteOrder.Uint64(k))
×
579

×
580
                return nil
×
581
        }); err != nil {
×
582
                return nil, err
×
583
        }
×
584

585
        // Load the forwarding package for each retrieved height.
586
        fwdPkgs := make([]*common.FwdPkg, 0, len(heights))
×
587
        for _, height := range heights {
×
588
                fwdPkg, err := loadFwdPkg(fwdPkgBkt, source, height)
×
589
                if err != nil {
×
590
                        return nil, err
×
591
                }
×
592

593
                fwdPkgs = append(fwdPkgs, fwdPkg)
×
594
        }
595

596
        return fwdPkgs, nil
×
597
}
598

599
// loadFwdPkg reads the packager's fwd pkg at a given height, and determines the
600
// appropriate FwdState.
601
func loadFwdPkg(fwdPkgBkt kvdb.RBucket, source lnwire.ShortChannelID,
602
        height uint64) (*common.FwdPkg, error) {
×
603

×
604
        sourceKey := makeLogKey(source.ToUint64())
×
605
        sourceBkt := fwdPkgBkt.NestedReadBucket(sourceKey[:])
×
606
        if sourceBkt == nil {
×
607
                return nil, ErrCorruptedFwdPkg
×
608
        }
×
609

610
        heightKey := makeLogKey(height)
×
611
        heightBkt := sourceBkt.NestedReadBucket(heightKey[:])
×
612
        if heightBkt == nil {
×
613
                return nil, ErrCorruptedFwdPkg
×
614
        }
×
615

616
        // Load ADDs from disk.
617
        addBkt := heightBkt.NestedReadBucket(addBucketKey)
×
618
        if addBkt == nil {
×
619
                return nil, ErrCorruptedFwdPkg
×
620
        }
×
621

622
        adds, err := loadHtlcs(addBkt)
×
623
        if err != nil {
×
624
                return nil, err
×
625
        }
×
626

627
        // Load ack filter from disk.
628
        ackFilterBytes := heightBkt.Get(ackFilterKey)
×
629
        if ackFilterBytes == nil {
×
630
                return nil, ErrCorruptedFwdPkg
×
631
        }
×
632
        ackFilterReader := bytes.NewReader(ackFilterBytes)
×
633

×
634
        ackFilter := &common.PkgFilter{}
×
635
        if err := ackFilter.Decode(ackFilterReader); err != nil {
×
636
                return nil, err
×
637
        }
×
638

639
        // Load SETTLE/FAILs from disk.
640
        failSettleBkt := heightBkt.NestedReadBucket(failSettleBucketKey)
×
641
        if failSettleBkt == nil {
×
642
                return nil, ErrCorruptedFwdPkg
×
643
        }
×
644

645
        failSettles, err := loadHtlcs(failSettleBkt)
×
646
        if err != nil {
×
647
                return nil, err
×
648
        }
×
649

650
        // Load settle fail filter from disk.
651
        settleFailFilterBytes := heightBkt.Get(settleFailFilterKey)
×
652
        if settleFailFilterBytes == nil {
×
653
                return nil, ErrCorruptedFwdPkg
×
654
        }
×
655
        settleFailFilterReader := bytes.NewReader(settleFailFilterBytes)
×
656

×
657
        settleFailFilter := &common.PkgFilter{}
×
658
        if err := settleFailFilter.Decode(settleFailFilterReader); err != nil {
×
659
                return nil, err
×
660
        }
×
661

662
        // Initialize the fwding package, which always starts in the
663
        // FwdStateLockedIn. We can determine what state the package was left in
664
        // by examining constraints on the information loaded from disk.
665
        fwdPkg := &common.FwdPkg{
×
666
                Source:           source,
×
667
                State:            common.FwdStateLockedIn,
×
668
                Height:           height,
×
669
                Adds:             adds,
×
670
                AckFilter:        ackFilter,
×
671
                SettleFails:      failSettles,
×
672
                SettleFailFilter: settleFailFilter,
×
673
        }
×
674

×
675
        // Check to see if we have written the set exported filter adds to
×
676
        // disk. If we haven't, processing of this package was never started, or
×
677
        // failed during the last attempt.
×
678
        fwdFilterBytes := heightBkt.Get(fwdFilterKey)
×
679
        if fwdFilterBytes == nil {
×
680
                nAdds := uint16(len(adds))
×
681
                fwdPkg.FwdFilter = common.NewPkgFilter(nAdds)
×
682
                return fwdPkg, nil
×
683
        }
×
684

685
        fwdFilterReader := bytes.NewReader(fwdFilterBytes)
×
686
        fwdPkg.FwdFilter = &common.PkgFilter{}
×
687
        if err := fwdPkg.FwdFilter.Decode(fwdFilterReader); err != nil {
×
688
                return nil, err
×
689
        }
×
690

691
        // Otherwise, a complete round of processing was completed, and we
692
        // advance the package to FwdStateProcessed.
693
        fwdPkg.State = common.FwdStateProcessed
×
694

×
695
        // If every add, settle, and fail has been fully acknowledged, we can
×
696
        // safely set the package's state to FwdStateCompleted, signalling that
×
697
        // it can be garbage collected.
×
698
        if fwdPkg.AckFilter.IsFull() && fwdPkg.SettleFailFilter.IsFull() {
×
699
                fwdPkg.State = common.FwdStateCompleted
×
700
        }
×
701

702
        return fwdPkg, nil
×
703
}
704

705
// loadHtlcs retrieves all serialized htlcs in a bucket, returning
706
// them in order of the indexes they were written under.
707
func loadHtlcs(bkt kvdb.RBucket) ([]common.LogUpdate, error) {
×
708
        var htlcs []common.LogUpdate
×
709
        if err := bkt.ForEach(func(_, v []byte) error {
×
710
                htlc, err := deserializeLogUpdate(bytes.NewReader(v))
×
711
                if err != nil {
×
712
                        return err
×
713
                }
×
714

715
                htlcs = append(htlcs, *htlc)
×
716

×
717
                return nil
×
718
        }); err != nil {
×
719
                return nil, err
×
720
        }
×
721

722
        return htlcs, nil
×
723
}
724

725
// serializeLogUpdate writes a log update to the provided io.Writer.
726
func serializeLogUpdate(w io.Writer, l *common.LogUpdate) error {
×
727
        return WriteElements(w, l.LogIndex, l.UpdateMsg)
×
728
}
×
729

730
// deserializeLogUpdate reads a log update from the provided io.Reader.
731
func deserializeLogUpdate(r io.Reader) (*common.LogUpdate, error) {
×
732
        l := &common.LogUpdate{}
×
733
        if err := ReadElements(r, &l.LogIndex, &l.UpdateMsg); err != nil {
×
734
                return nil, err
×
735
        }
×
736

737
        return l, nil
×
738
}
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