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

lightningnetwork / lnd / 12231552240

09 Dec 2024 08:17AM UTC coverage: 58.955% (+0.02%) from 58.933%
12231552240

Pull #9242

github

aakselrod
go.mod: update btcwallet to latest to eliminate waddrmgr deadlock
Pull Request #9242: Reapply #8644

24 of 40 new or added lines in 3 files covered. (60.0%)

89 existing lines in 18 files now uncovered.

133525 of 226485 relevant lines covered (58.96%)

19398.62 hits per line

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

78.03
/channeldb/channel.go
1
package channeldb
2

3
import (
4
        "bytes"
5
        "crypto/hmac"
6
        "crypto/sha256"
7
        "encoding/binary"
8
        "errors"
9
        "fmt"
10
        "io"
11
        "net"
12
        "strconv"
13
        "strings"
14
        "sync"
15

16
        "github.com/btcsuite/btcd/btcec/v2"
17
        "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
18
        "github.com/btcsuite/btcd/btcutil"
19
        "github.com/btcsuite/btcd/chaincfg/chainhash"
20
        "github.com/btcsuite/btcd/wire"
21
        "github.com/btcsuite/btcwallet/walletdb"
22
        "github.com/lightningnetwork/lnd/fn"
23
        graphdb "github.com/lightningnetwork/lnd/graph/db"
24
        "github.com/lightningnetwork/lnd/graph/db/models"
25
        "github.com/lightningnetwork/lnd/htlcswitch/hop"
26
        "github.com/lightningnetwork/lnd/input"
27
        "github.com/lightningnetwork/lnd/keychain"
28
        "github.com/lightningnetwork/lnd/kvdb"
29
        "github.com/lightningnetwork/lnd/lntypes"
30
        "github.com/lightningnetwork/lnd/lnwire"
31
        "github.com/lightningnetwork/lnd/shachain"
32
        "github.com/lightningnetwork/lnd/tlv"
33
)
34

35
const (
36
        // AbsoluteThawHeightThreshold is the threshold at which a thaw height
37
        // begins to be interpreted as an absolute block height, rather than a
38
        // relative one.
39
        AbsoluteThawHeightThreshold uint32 = 500000
40

41
        // HTLCBlindingPointTLV is the tlv type used for storing blinding
42
        // points with HTLCs.
43
        HTLCBlindingPointTLV tlv.Type = 0
44
)
45

46
var (
47
        // closedChannelBucket stores summarization information concerning
48
        // previously open, but now closed channels.
49
        closedChannelBucket = []byte("closed-chan-bucket")
50

51
        // openChannelBucket stores all the currently open channels. This bucket
52
        // has a second, nested bucket which is keyed by a node's ID. Within
53
        // that node ID bucket, all attributes required to track, update, and
54
        // close a channel are stored.
55
        //
56
        // openChan -> nodeID -> chanPoint
57
        //
58
        // TODO(roasbeef): flesh out comment
59
        openChannelBucket = []byte("open-chan-bucket")
60

61
        // outpointBucket stores all of our channel outpoints and a tlv
62
        // stream containing channel data.
63
        //
64
        // outpoint -> tlv stream.
65
        //
66
        outpointBucket = []byte("outpoint-bucket")
67

68
        // chanIDBucket stores all of the 32-byte channel ID's we know about.
69
        // These could be derived from outpointBucket, but it is more
70
        // convenient to have these in their own bucket.
71
        //
72
        // chanID -> tlv stream.
73
        //
74
        chanIDBucket = []byte("chan-id-bucket")
75

76
        // historicalChannelBucket stores all channels that have seen their
77
        // commitment tx confirm. All information from their previous open state
78
        // is retained.
79
        historicalChannelBucket = []byte("historical-chan-bucket")
80

81
        // chanInfoKey can be accessed within the bucket for a channel
82
        // (identified by its chanPoint). This key stores all the static
83
        // information for a channel which is decided at the end of  the
84
        // funding flow.
85
        chanInfoKey = []byte("chan-info-key")
86

87
        // localUpfrontShutdownKey can be accessed within the bucket for a channel
88
        // (identified by its chanPoint). This key stores an optional upfront
89
        // shutdown script for the local peer.
90
        localUpfrontShutdownKey = []byte("local-upfront-shutdown-key")
91

92
        // remoteUpfrontShutdownKey can be accessed within the bucket for a channel
93
        // (identified by its chanPoint). This key stores an optional upfront
94
        // shutdown script for the remote peer.
95
        remoteUpfrontShutdownKey = []byte("remote-upfront-shutdown-key")
96

97
        // chanCommitmentKey can be accessed within the sub-bucket for a
98
        // particular channel. This key stores the up to date commitment state
99
        // for a particular channel party. Appending a 0 to the end of this key
100
        // indicates it's the commitment for the local party, and appending a 1
101
        // to the end of this key indicates it's the commitment for the remote
102
        // party.
103
        chanCommitmentKey = []byte("chan-commitment-key")
104

105
        // unsignedAckedUpdatesKey is an entry in the channel bucket that
106
        // contains the remote updates that we have acked, but not yet signed
107
        // for in one of our remote commits.
108
        unsignedAckedUpdatesKey = []byte("unsigned-acked-updates-key")
109

110
        // remoteUnsignedLocalUpdatesKey is an entry in the channel bucket that
111
        // contains the local updates that the remote party has acked, but
112
        // has not yet signed for in one of their local commits.
113
        remoteUnsignedLocalUpdatesKey = []byte("remote-unsigned-local-updates-key")
114

115
        // revocationStateKey stores their current revocation hash, our
116
        // preimage producer and their preimage store.
117
        revocationStateKey = []byte("revocation-state-key")
118

119
        // dataLossCommitPointKey stores the commitment point received from the
120
        // remote peer during a channel sync in case we have lost channel state.
121
        dataLossCommitPointKey = []byte("data-loss-commit-point-key")
122

123
        // forceCloseTxKey points to a the unilateral closing tx that we
124
        // broadcasted when moving the channel to state CommitBroadcasted.
125
        forceCloseTxKey = []byte("closing-tx-key")
126

127
        // coopCloseTxKey points to a the cooperative closing tx that we
128
        // broadcasted when moving the channel to state CoopBroadcasted.
129
        coopCloseTxKey = []byte("coop-closing-tx-key")
130

131
        // shutdownInfoKey points to the serialised shutdown info that has been
132
        // persisted for a channel. The existence of this info means that we
133
        // have sent the Shutdown message before and so should re-initiate the
134
        // shutdown on re-establish.
135
        shutdownInfoKey = []byte("shutdown-info-key")
136

137
        // commitDiffKey stores the current pending commitment state we've
138
        // extended to the remote party (if any). Each time we propose a new
139
        // state, we store the information necessary to reconstruct this state
140
        // from the prior commitment. This allows us to resync the remote party
141
        // to their expected state in the case of message loss.
142
        //
143
        // TODO(roasbeef): rename to commit chain?
144
        commitDiffKey = []byte("commit-diff-key")
145

146
        // frozenChanKey is the key where we store the information for any
147
        // active "frozen" channels. This key is present only in the leaf
148
        // bucket for a given channel.
149
        frozenChanKey = []byte("frozen-chans")
150

151
        // lastWasRevokeKey is a key that stores true when the last update we
152
        // sent was a revocation and false when it was a commitment signature.
153
        // This is nil in the case of new channels with no updates exchanged.
154
        lastWasRevokeKey = []byte("last-was-revoke")
155

156
        // finalHtlcsBucket contains the htlcs that have been resolved
157
        // definitively. Within this bucket, there is a sub-bucket for each
158
        // channel. In each channel bucket, the htlc indices are stored along
159
        // with final outcome.
160
        //
161
        // final-htlcs -> chanID -> htlcIndex -> outcome
162
        //
163
        // 'outcome' is a byte value that encodes:
164
        //
165
        //       | true      false
166
        // ------+------------------
167
        // bit 0 | settled   failed
168
        // bit 1 | offchain  onchain
169
        //
170
        // This bucket is positioned at the root level, because its contents
171
        // will be kept independent of the channel lifecycle. This is to avoid
172
        // the situation where a channel force-closes autonomously and the user
173
        // not being able to query for htlc outcomes anymore.
174
        finalHtlcsBucket = []byte("final-htlcs")
175
)
176

177
var (
178
        // ErrNoCommitmentsFound is returned when a channel has not set
179
        // commitment states.
180
        ErrNoCommitmentsFound = fmt.Errorf("no commitments found")
181

182
        // ErrNoChanInfoFound is returned when a particular channel does not
183
        // have any channels state.
184
        ErrNoChanInfoFound = fmt.Errorf("no chan info found")
185

186
        // ErrNoRevocationsFound is returned when revocation state for a
187
        // particular channel cannot be found.
188
        ErrNoRevocationsFound = fmt.Errorf("no revocations found")
189

190
        // ErrNoPendingCommit is returned when there is not a pending
191
        // commitment for a remote party. A new commitment is written to disk
192
        // each time we write a new state in order to be properly fault
193
        // tolerant.
194
        ErrNoPendingCommit = fmt.Errorf("no pending commits found")
195

196
        // ErrNoCommitPoint is returned when no data loss commit point is found
197
        // in the database.
198
        ErrNoCommitPoint = fmt.Errorf("no commit point found")
199

200
        // ErrNoCloseTx is returned when no closing tx is found for a channel
201
        // in the state CommitBroadcasted.
202
        ErrNoCloseTx = fmt.Errorf("no closing tx found")
203

204
        // ErrNoShutdownInfo is returned when no shutdown info has been
205
        // persisted for a channel.
206
        ErrNoShutdownInfo = errors.New("no shutdown info")
207

208
        // ErrNoRestoredChannelMutation is returned when a caller attempts to
209
        // mutate a channel that's been recovered.
210
        ErrNoRestoredChannelMutation = fmt.Errorf("cannot mutate restored " +
211
                "channel state")
212

213
        // ErrChanBorked is returned when a caller attempts to mutate a borked
214
        // channel.
215
        ErrChanBorked = fmt.Errorf("cannot mutate borked channel")
216

217
        // ErrMissingIndexEntry is returned when a caller attempts to close a
218
        // channel and the outpoint is missing from the index.
219
        ErrMissingIndexEntry = fmt.Errorf("missing outpoint from index")
220

221
        // ErrOnionBlobLength is returned is an onion blob with incorrect
222
        // length is read from disk.
223
        ErrOnionBlobLength = errors.New("onion blob < 1366 bytes")
224
)
225

226
const (
227
        // A tlv type definition used to serialize an outpoint's indexStatus
228
        // for use in the outpoint index.
229
        indexStatusType tlv.Type = 0
230
)
231

232
// openChannelTlvData houses the new data fields that are stored for each
233
// channel in a TLV stream within the root bucket. This is stored as a TLV
234
// stream appended to the existing hard-coded fields in the channel's root
235
// bucket. New fields being added to the channel state should be added here.
236
//
237
// NOTE: This struct is used for serialization purposes only and its fields
238
// should be accessed via the OpenChannel struct while in memory.
239
type openChannelTlvData struct {
240
        // revokeKeyLoc is the key locator for the revocation key.
241
        revokeKeyLoc tlv.RecordT[tlv.TlvType1, keyLocRecord]
242

243
        // initialLocalBalance is the initial local balance of the channel.
244
        initialLocalBalance tlv.RecordT[tlv.TlvType2, uint64]
245

246
        // initialRemoteBalance is the initial remote balance of the channel.
247
        initialRemoteBalance tlv.RecordT[tlv.TlvType3, uint64]
248

249
        // realScid is the real short channel ID of the channel corresponding to
250
        // the on-chain outpoint.
251
        realScid tlv.RecordT[tlv.TlvType4, lnwire.ShortChannelID]
252

253
        // memo is an optional text field that gives context to the user about
254
        // the channel.
255
        memo tlv.OptionalRecordT[tlv.TlvType5, []byte]
256

257
        // tapscriptRoot is the optional Tapscript root the channel funding
258
        // output commits to.
259
        tapscriptRoot tlv.OptionalRecordT[tlv.TlvType6, [32]byte]
260

261
        // customBlob is an optional TLV encoded blob of data representing
262
        // custom channel funding information.
263
        customBlob tlv.OptionalRecordT[tlv.TlvType7, tlv.Blob]
264
}
265

266
// encode serializes the openChannelTlvData to the given io.Writer.
267
func (c *openChannelTlvData) encode(w io.Writer) error {
3,217✔
268
        tlvRecords := []tlv.Record{
3,217✔
269
                c.revokeKeyLoc.Record(),
3,217✔
270
                c.initialLocalBalance.Record(),
3,217✔
271
                c.initialRemoteBalance.Record(),
3,217✔
272
                c.realScid.Record(),
3,217✔
273
        }
3,217✔
274
        c.memo.WhenSome(func(memo tlv.RecordT[tlv.TlvType5, []byte]) {
3,642✔
275
                tlvRecords = append(tlvRecords, memo.Record())
425✔
276
        })
425✔
277
        c.tapscriptRoot.WhenSome(
3,217✔
278
                func(root tlv.RecordT[tlv.TlvType6, [32]byte]) {
3,690✔
279
                        tlvRecords = append(tlvRecords, root.Record())
473✔
280
                },
473✔
281
        )
282
        c.customBlob.WhenSome(func(blob tlv.RecordT[tlv.TlvType7, tlv.Blob]) {
3,638✔
283
                tlvRecords = append(tlvRecords, blob.Record())
421✔
284
        })
421✔
285

286
        // Create the tlv stream.
287
        tlvStream, err := tlv.NewStream(tlvRecords...)
3,217✔
288
        if err != nil {
3,217✔
289
                return err
×
290
        }
×
291

292
        return tlvStream.Encode(w)
3,217✔
293
}
294

295
// decode deserializes the openChannelTlvData from the given io.Reader.
296
func (c *openChannelTlvData) decode(r io.Reader) error {
7,121✔
297
        memo := c.memo.Zero()
7,121✔
298
        tapscriptRoot := c.tapscriptRoot.Zero()
7,121✔
299
        blob := c.customBlob.Zero()
7,121✔
300

7,121✔
301
        // Create the tlv stream.
7,121✔
302
        tlvStream, err := tlv.NewStream(
7,121✔
303
                c.revokeKeyLoc.Record(),
7,121✔
304
                c.initialLocalBalance.Record(),
7,121✔
305
                c.initialRemoteBalance.Record(),
7,121✔
306
                c.realScid.Record(),
7,121✔
307
                memo.Record(),
7,121✔
308
                tapscriptRoot.Record(),
7,121✔
309
                blob.Record(),
7,121✔
310
        )
7,121✔
311
        if err != nil {
7,121✔
312
                return err
×
313
        }
×
314

315
        tlvs, err := tlvStream.DecodeWithParsedTypes(r)
7,121✔
316
        if err != nil {
7,121✔
317
                return err
×
318
        }
×
319

320
        if _, ok := tlvs[memo.TlvType()]; ok {
7,452✔
321
                c.memo = tlv.SomeRecordT(memo)
331✔
322
        }
331✔
323
        if _, ok := tlvs[tapscriptRoot.TlvType()]; ok {
7,556✔
324
                c.tapscriptRoot = tlv.SomeRecordT(tapscriptRoot)
435✔
325
        }
435✔
326
        if _, ok := tlvs[c.customBlob.TlvType()]; ok {
7,448✔
327
                c.customBlob = tlv.SomeRecordT(blob)
327✔
328
        }
327✔
329

330
        return nil
7,121✔
331
}
332

333
// indexStatus is an enum-like type that describes what state the
334
// outpoint is in. Currently only two possible values.
335
type indexStatus uint8
336

337
const (
338
        // outpointOpen represents an outpoint that is open in the outpoint index.
339
        outpointOpen indexStatus = 0
340

341
        // outpointClosed represents an outpoint that is closed in the outpoint
342
        // index.
343
        outpointClosed indexStatus = 1
344
)
345

346
// ChannelType is an enum-like type that describes one of several possible
347
// channel types. Each open channel is associated with a particular type as the
348
// channel type may determine how higher level operations are conducted such as
349
// fee negotiation, channel closing, the format of HTLCs, etc. Structure-wise,
350
// a ChannelType is a bit field, with each bit denoting a modification from the
351
// base channel type of single funder.
352
type ChannelType uint64
353

354
const (
355
        // NOTE: iota isn't used here for this enum needs to be stable
356
        // long-term as it will be persisted to the database.
357

358
        // SingleFunderBit represents a channel wherein one party solely funds
359
        // the entire capacity of the channel.
360
        SingleFunderBit ChannelType = 0
361

362
        // DualFunderBit represents a channel wherein both parties contribute
363
        // funds towards the total capacity of the channel. The channel may be
364
        // funded symmetrically or asymmetrically.
365
        DualFunderBit ChannelType = 1 << 0
366

367
        // SingleFunderTweaklessBit is similar to the basic SingleFunder channel
368
        // type, but it omits the tweak for one's key in the commitment
369
        // transaction of the remote party.
370
        SingleFunderTweaklessBit ChannelType = 1 << 1
371

372
        // NoFundingTxBit denotes if we have the funding transaction locally on
373
        // disk. This bit may be on if the funding transaction was crafted by a
374
        // wallet external to the primary daemon.
375
        NoFundingTxBit ChannelType = 1 << 2
376

377
        // AnchorOutputsBit indicates that the channel makes use of anchor
378
        // outputs to bump the commitment transaction's effective feerate. This
379
        // channel type also uses a delayed to_remote output script.
380
        AnchorOutputsBit ChannelType = 1 << 3
381

382
        // FrozenBit indicates that the channel is a frozen channel, meaning
383
        // that only the responder can decide to cooperatively close the
384
        // channel.
385
        FrozenBit ChannelType = 1 << 4
386

387
        // ZeroHtlcTxFeeBit indicates that the channel should use zero-fee
388
        // second-level HTLC transactions.
389
        ZeroHtlcTxFeeBit ChannelType = 1 << 5
390

391
        // LeaseExpirationBit indicates that the channel has been leased for a
392
        // period of time, constraining every output that pays to the channel
393
        // initiator with an additional CLTV of the lease maturity.
394
        LeaseExpirationBit ChannelType = 1 << 6
395

396
        // ZeroConfBit indicates that the channel is a zero-conf channel.
397
        ZeroConfBit ChannelType = 1 << 7
398

399
        // ScidAliasChanBit indicates that the channel has negotiated the
400
        // scid-alias channel type.
401
        ScidAliasChanBit ChannelType = 1 << 8
402

403
        // ScidAliasFeatureBit indicates that the scid-alias feature bit was
404
        // negotiated during the lifetime of this channel.
405
        ScidAliasFeatureBit ChannelType = 1 << 9
406

407
        // SimpleTaprootFeatureBit indicates that the simple-taproot-chans
408
        // feature bit was negotiated during the lifetime of the channel.
409
        SimpleTaprootFeatureBit ChannelType = 1 << 10
410

411
        // TapscriptRootBit indicates that this is a MuSig2 channel with a top
412
        // level tapscript commitment. This MUST be set along with the
413
        // SimpleTaprootFeatureBit.
414
        TapscriptRootBit ChannelType = 1 << 11
415
)
416

417
// IsSingleFunder returns true if the channel type if one of the known single
418
// funder variants.
419
func (c ChannelType) IsSingleFunder() bool {
10,420✔
420
        return c&DualFunderBit == 0
10,420✔
421
}
10,420✔
422

423
// IsDualFunder returns true if the ChannelType has the DualFunderBit set.
424
func (c ChannelType) IsDualFunder() bool {
×
425
        return c&DualFunderBit == DualFunderBit
×
426
}
×
427

428
// IsTweakless returns true if the target channel uses a commitment that
429
// doesn't tweak the key for the remote party.
430
func (c ChannelType) IsTweakless() bool {
10,611✔
431
        return c&SingleFunderTweaklessBit == SingleFunderTweaklessBit
10,611✔
432
}
10,611✔
433

434
// HasFundingTx returns true if this channel type is one that has a funding
435
// transaction stored locally.
436
func (c ChannelType) HasFundingTx() bool {
10,430✔
437
        return c&NoFundingTxBit == 0
10,430✔
438
}
10,430✔
439

440
// HasAnchors returns true if this channel type has anchor outputs on its
441
// commitment.
442
func (c ChannelType) HasAnchors() bool {
258,084✔
443
        return c&AnchorOutputsBit == AnchorOutputsBit
258,084✔
444
}
258,084✔
445

446
// ZeroHtlcTxFee returns true if this channel type uses second-level HTLC
447
// transactions signed with zero-fee.
448
func (c ChannelType) ZeroHtlcTxFee() bool {
207,950✔
449
        return c&ZeroHtlcTxFeeBit == ZeroHtlcTxFeeBit
207,950✔
450
}
207,950✔
451

452
// IsFrozen returns true if the channel is considered to be "frozen". A frozen
453
// channel means that only the responder can initiate a cooperative channel
454
// closure.
455
func (c ChannelType) IsFrozen() bool {
8,482✔
456
        return c&FrozenBit == FrozenBit
8,482✔
457
}
8,482✔
458

459
// HasLeaseExpiration returns true if the channel originated from a lease.
460
func (c ChannelType) HasLeaseExpiration() bool {
32,214✔
461
        return c&LeaseExpirationBit == LeaseExpirationBit
32,214✔
462
}
32,214✔
463

464
// HasZeroConf returns true if the channel is a zero-conf channel.
465
func (c ChannelType) HasZeroConf() bool {
648✔
466
        return c&ZeroConfBit == ZeroConfBit
648✔
467
}
648✔
468

469
// HasScidAliasChan returns true if the scid-alias channel type was negotiated.
470
func (c ChannelType) HasScidAliasChan() bool {
×
471
        return c&ScidAliasChanBit == ScidAliasChanBit
×
472
}
×
473

474
// HasScidAliasFeature returns true if the scid-alias feature bit was
475
// negotiated during the lifetime of this channel.
476
func (c ChannelType) HasScidAliasFeature() bool {
488✔
477
        return c&ScidAliasFeatureBit == ScidAliasFeatureBit
488✔
478
}
488✔
479

480
// IsTaproot returns true if the channel is using taproot features.
481
func (c ChannelType) IsTaproot() bool {
288,479✔
482
        return c&SimpleTaprootFeatureBit == SimpleTaprootFeatureBit
288,479✔
483
}
288,479✔
484

485
// HasTapscriptRoot returns true if the channel is using a top level tapscript
486
// root commitment.
487
func (c ChannelType) HasTapscriptRoot() bool {
262✔
488
        return c&TapscriptRootBit == TapscriptRootBit
262✔
489
}
262✔
490

491
// ChannelStateBounds are the parameters from OpenChannel and AcceptChannel
492
// that are responsible for providing bounds on the state space of the abstract
493
// channel state. These values must be remembered for normal channel operation
494
// but they do not impact how we compute the commitment transactions themselves.
495
type ChannelStateBounds struct {
496
        // ChanReserve is an absolute reservation on the channel for the
497
        // owner of this set of constraints. This means that the current
498
        // settled balance for this node CANNOT dip below the reservation
499
        // amount. This acts as a defense against costless attacks when
500
        // either side no longer has any skin in the game.
501
        ChanReserve btcutil.Amount
502

503
        // MaxPendingAmount is the maximum pending HTLC value that the
504
        // owner of these constraints can offer the remote node at a
505
        // particular time.
506
        MaxPendingAmount lnwire.MilliSatoshi
507

508
        // MinHTLC is the minimum HTLC value that the owner of these
509
        // constraints can offer the remote node. If any HTLCs below this
510
        // amount are offered, then the HTLC will be rejected. This, in
511
        // tandem with the dust limit allows a node to regulate the
512
        // smallest HTLC that it deems economically relevant.
513
        MinHTLC lnwire.MilliSatoshi
514

515
        // MaxAcceptedHtlcs is the maximum number of HTLCs that the owner of
516
        // this set of constraints can offer the remote node. This allows each
517
        // node to limit their over all exposure to HTLCs that may need to be
518
        // acted upon in the case of a unilateral channel closure or a contract
519
        // breach.
520
        MaxAcceptedHtlcs uint16
521
}
522

523
// CommitmentParams are the parameters from OpenChannel and
524
// AcceptChannel that are required to render an abstract channel state to a
525
// concrete commitment transaction. These values are necessary to (re)compute
526
// the commitment transaction. We treat these differently than the state space
527
// bounds because their history needs to be stored in order to properly handle
528
// chain resolution.
529
type CommitmentParams struct {
530
        // DustLimit is the threshold (in satoshis) below which any outputs
531
        // should be trimmed. When an output is trimmed, it isn't materialized
532
        // as an actual output, but is instead burned to miner's fees.
533
        DustLimit btcutil.Amount
534

535
        // CsvDelay is the relative time lock delay expressed in blocks. Any
536
        // settled outputs that pay to the owner of this channel configuration
537
        // MUST ensure that the delay branch uses this value as the relative
538
        // time lock. Similarly, any HTLC's offered by this node should use
539
        // this value as well.
540
        CsvDelay uint16
541
}
542

543
// ChannelConfig is a struct that houses the various configuration opens for
544
// channels. Each side maintains an instance of this configuration file as it
545
// governs: how the funding and commitment transaction to be created, the
546
// nature of HTLC's allotted, the keys to be used for delivery, and relative
547
// time lock parameters.
548
type ChannelConfig struct {
549
        // ChannelStateBounds is the set of constraints that must be
550
        // upheld for the duration of the channel for the owner of this channel
551
        // configuration. Constraints govern a number of flow control related
552
        // parameters, also including the smallest HTLC that will be accepted
553
        // by a participant.
554
        ChannelStateBounds
555

556
        // CommitmentParams is an embedding of the parameters
557
        // required to render an abstract channel state into a concrete
558
        // commitment transaction.
559
        CommitmentParams
560

561
        // MultiSigKey is the key to be used within the 2-of-2 output script
562
        // for the owner of this channel config.
563
        MultiSigKey keychain.KeyDescriptor
564

565
        // RevocationBasePoint is the base public key to be used when deriving
566
        // revocation keys for the remote node's commitment transaction. This
567
        // will be combined along with a per commitment secret to derive a
568
        // unique revocation key for each state.
569
        RevocationBasePoint keychain.KeyDescriptor
570

571
        // PaymentBasePoint is the base public key to be used when deriving
572
        // the key used within the non-delayed pay-to-self output on the
573
        // commitment transaction for a node. This will be combined with a
574
        // tweak derived from the per-commitment point to ensure unique keys
575
        // for each commitment transaction.
576
        PaymentBasePoint keychain.KeyDescriptor
577

578
        // DelayBasePoint is the base public key to be used when deriving the
579
        // key used within the delayed pay-to-self output on the commitment
580
        // transaction for a node. This will be combined with a tweak derived
581
        // from the per-commitment point to ensure unique keys for each
582
        // commitment transaction.
583
        DelayBasePoint keychain.KeyDescriptor
584

585
        // HtlcBasePoint is the base public key to be used when deriving the
586
        // local HTLC key. The derived key (combined with the tweak derived
587
        // from the per-commitment point) is used within the "to self" clause
588
        // within any HTLC output scripts.
589
        HtlcBasePoint keychain.KeyDescriptor
590
}
591

592
// commitTlvData stores all the optional data that may be stored as a TLV stream
593
// at the _end_ of the normal serialized commit on disk.
594
type commitTlvData struct {
595
        // customBlob is a custom blob that may store extra data for custom
596
        // channels.
597
        customBlob tlv.OptionalRecordT[tlv.TlvType1, tlv.Blob]
598
}
599

600
// encode encodes the aux data into the passed io.Writer.
601
func (c *commitTlvData) encode(w io.Writer) error {
8,425✔
602
        var tlvRecords []tlv.Record
8,425✔
603
        c.customBlob.WhenSome(func(blob tlv.RecordT[tlv.TlvType1, tlv.Blob]) {
9,270✔
604
                tlvRecords = append(tlvRecords, blob.Record())
845✔
605
        })
845✔
606

607
        // Create the tlv stream.
608
        tlvStream, err := tlv.NewStream(tlvRecords...)
8,425✔
609
        if err != nil {
8,425✔
610
                return err
×
611
        }
×
612

613
        return tlvStream.Encode(w)
8,425✔
614
}
615

616
// decode attempts to decode the aux data from the passed io.Reader.
617
func (c *commitTlvData) decode(r io.Reader) error {
16,297✔
618
        blob := c.customBlob.Zero()
16,297✔
619

16,297✔
620
        tlvStream, err := tlv.NewStream(
16,297✔
621
                blob.Record(),
16,297✔
622
        )
16,297✔
623
        if err != nil {
16,297✔
624
                return err
×
625
        }
×
626

627
        tlvs, err := tlvStream.DecodeWithParsedTypes(r)
16,297✔
628
        if err != nil {
16,297✔
629
                return err
×
630
        }
×
631

632
        if _, ok := tlvs[c.customBlob.TlvType()]; ok {
16,955✔
633
                c.customBlob = tlv.SomeRecordT(blob)
658✔
634
        }
658✔
635

636
        return nil
16,297✔
637
}
638

639
// ChannelCommitment is a snapshot of the commitment state at a particular
640
// point in the commitment chain. With each state transition, a snapshot of the
641
// current state along with all non-settled HTLCs are recorded. These snapshots
642
// detail the state of the _remote_ party's commitment at a particular state
643
// number.  For ourselves (the local node) we ONLY store our most recent
644
// (unrevoked) state for safety purposes.
645
type ChannelCommitment struct {
646
        // CommitHeight is the update number that this ChannelDelta represents
647
        // the total number of commitment updates to this point. This can be
648
        // viewed as sort of a "commitment height" as this number is
649
        // monotonically increasing.
650
        CommitHeight uint64
651

652
        // LocalLogIndex is the cumulative log index index of the local node at
653
        // this point in the commitment chain. This value will be incremented
654
        // for each _update_ added to the local update log.
655
        LocalLogIndex uint64
656

657
        // LocalHtlcIndex is the current local running HTLC index. This value
658
        // will be incremented for each outgoing HTLC the local node offers.
659
        LocalHtlcIndex uint64
660

661
        // RemoteLogIndex is the cumulative log index index of the remote node
662
        // at this point in the commitment chain. This value will be
663
        // incremented for each _update_ added to the remote update log.
664
        RemoteLogIndex uint64
665

666
        // RemoteHtlcIndex is the current remote running HTLC index. This value
667
        // will be incremented for each outgoing HTLC the remote node offers.
668
        RemoteHtlcIndex uint64
669

670
        // LocalBalance is the current available settled balance within the
671
        // channel directly spendable by us.
672
        //
673
        // NOTE: This is the balance *after* subtracting any commitment fee,
674
        // AND anchor output values.
675
        LocalBalance lnwire.MilliSatoshi
676

677
        // RemoteBalance is the current available settled balance within the
678
        // channel directly spendable by the remote node.
679
        //
680
        // NOTE: This is the balance *after* subtracting any commitment fee,
681
        // AND anchor output values.
682
        RemoteBalance lnwire.MilliSatoshi
683

684
        // CommitFee is the amount calculated to be paid in fees for the
685
        // current set of commitment transactions. The fee amount is persisted
686
        // with the channel in order to allow the fee amount to be removed and
687
        // recalculated with each channel state update, including updates that
688
        // happen after a system restart.
689
        CommitFee btcutil.Amount
690

691
        // FeePerKw is the min satoshis/kilo-weight that should be paid within
692
        // the commitment transaction for the entire duration of the channel's
693
        // lifetime. This field may be updated during normal operation of the
694
        // channel as on-chain conditions change.
695
        //
696
        // TODO(halseth): make this SatPerKWeight. Cannot be done atm because
697
        // this will cause the import cycle lnwallet<->channeldb. Fee
698
        // estimation stuff should be in its own package.
699
        FeePerKw btcutil.Amount
700

701
        // CommitTx is the latest version of the commitment state, broadcast
702
        // able by us.
703
        CommitTx *wire.MsgTx
704

705
        // CustomBlob is an optional blob that can be used to store information
706
        // specific to a custom channel type. This may track some custom
707
        // specific state for this given commitment.
708
        CustomBlob fn.Option[tlv.Blob]
709

710
        // CommitSig is one half of the signature required to fully complete
711
        // the script for the commitment transaction above. This is the
712
        // signature signed by the remote party for our version of the
713
        // commitment transactions.
714
        CommitSig []byte
715

716
        // Htlcs is the set of HTLC's that are pending at this particular
717
        // commitment height.
718
        Htlcs []HTLC
719
}
720

721
// amendTlvData updates the channel with the given auxiliary TLV data.
722
func (c *ChannelCommitment) amendTlvData(auxData commitTlvData) {
16,297✔
723
        auxData.customBlob.WhenSomeV(func(blob tlv.Blob) {
16,955✔
724
                c.CustomBlob = fn.Some(blob)
658✔
725
        })
658✔
726
}
727

728
// extractTlvData creates a new commitTlvData from the given commitment.
729
func (c *ChannelCommitment) extractTlvData() commitTlvData {
8,425✔
730
        var auxData commitTlvData
8,425✔
731

8,425✔
732
        c.CustomBlob.WhenSome(func(blob tlv.Blob) {
9,270✔
733
                auxData.customBlob = tlv.SomeRecordT(
845✔
734
                        tlv.NewPrimitiveRecord[tlv.TlvType1](blob),
845✔
735
                )
845✔
736
        })
845✔
737

738
        return auxData
8,425✔
739
}
740

741
// ChannelStatus is a bit vector used to indicate whether an OpenChannel is in
742
// the default usable state, or a state where it shouldn't be used.
743
type ChannelStatus uint64
744

745
var (
746
        // ChanStatusDefault is the normal state of an open channel.
747
        ChanStatusDefault ChannelStatus
748

749
        // ChanStatusBorked indicates that the channel has entered an
750
        // irreconcilable state, triggered by a state desynchronization or
751
        // channel breach.  Channels in this state should never be added to the
752
        // htlc switch.
753
        ChanStatusBorked ChannelStatus = 1
754

755
        // ChanStatusCommitBroadcasted indicates that a commitment for this
756
        // channel has been broadcasted.
757
        ChanStatusCommitBroadcasted ChannelStatus = 1 << 1
758

759
        // ChanStatusLocalDataLoss indicates that we have lost channel state
760
        // for this channel, and broadcasting our latest commitment might be
761
        // considered a breach.
762
        //
763
        // TODO(halseh): actually enforce that we are not force closing such a
764
        // channel.
765
        ChanStatusLocalDataLoss ChannelStatus = 1 << 2
766

767
        // ChanStatusRestored is a status flag that signals that the channel
768
        // has been restored, and doesn't have all the fields a typical channel
769
        // will have.
770
        ChanStatusRestored ChannelStatus = 1 << 3
771

772
        // ChanStatusCoopBroadcasted indicates that a cooperative close for
773
        // this channel has been broadcasted. Older cooperatively closed
774
        // channels will only have this status set. Newer ones will also have
775
        // close initiator information stored using the local/remote initiator
776
        // status. This status is set in conjunction with the initiator status
777
        // so that we do not need to check multiple channel statues for
778
        // cooperative closes.
779
        ChanStatusCoopBroadcasted ChannelStatus = 1 << 4
780

781
        // ChanStatusLocalCloseInitiator indicates that we initiated closing
782
        // the channel.
783
        ChanStatusLocalCloseInitiator ChannelStatus = 1 << 5
784

785
        // ChanStatusRemoteCloseInitiator indicates that the remote node
786
        // initiated closing the channel.
787
        ChanStatusRemoteCloseInitiator ChannelStatus = 1 << 6
788
)
789

790
// chanStatusStrings maps a ChannelStatus to a human friendly string that
791
// describes that status.
792
var chanStatusStrings = map[ChannelStatus]string{
793
        ChanStatusDefault:              "ChanStatusDefault",
794
        ChanStatusBorked:               "ChanStatusBorked",
795
        ChanStatusCommitBroadcasted:    "ChanStatusCommitBroadcasted",
796
        ChanStatusLocalDataLoss:        "ChanStatusLocalDataLoss",
797
        ChanStatusRestored:             "ChanStatusRestored",
798
        ChanStatusCoopBroadcasted:      "ChanStatusCoopBroadcasted",
799
        ChanStatusLocalCloseInitiator:  "ChanStatusLocalCloseInitiator",
800
        ChanStatusRemoteCloseInitiator: "ChanStatusRemoteCloseInitiator",
801
}
802

803
// orderedChanStatusFlags is an in-order list of all that channel status flags.
804
var orderedChanStatusFlags = []ChannelStatus{
805
        ChanStatusBorked,
806
        ChanStatusCommitBroadcasted,
807
        ChanStatusLocalDataLoss,
808
        ChanStatusRestored,
809
        ChanStatusCoopBroadcasted,
810
        ChanStatusLocalCloseInitiator,
811
        ChanStatusRemoteCloseInitiator,
812
}
813

814
// String returns a human-readable representation of the ChannelStatus.
815
func (c ChannelStatus) String() string {
5✔
816
        // If no flags are set, then this is the default case.
5✔
817
        if c == ChanStatusDefault {
9✔
818
                return chanStatusStrings[ChanStatusDefault]
4✔
819
        }
4✔
820

821
        // Add individual bit flags.
822
        statusStr := ""
5✔
823
        for _, flag := range orderedChanStatusFlags {
16✔
824
                if c&flag == flag {
16✔
825
                        statusStr += chanStatusStrings[flag] + "|"
5✔
826
                        c -= flag
5✔
827
                }
5✔
828
        }
829

830
        // Remove anything to the right of the final bar, including it as well.
831
        statusStr = strings.TrimRight(statusStr, "|")
5✔
832

5✔
833
        // Add any remaining flags which aren't accounted for as hex.
5✔
834
        if c != 0 {
5✔
835
                statusStr += "|0x" + strconv.FormatUint(uint64(c), 16)
×
836
        }
×
837

838
        // If this was purely an unknown flag, then remove the extra bar at the
839
        // start of the string.
840
        statusStr = strings.TrimLeft(statusStr, "|")
5✔
841

5✔
842
        return statusStr
5✔
843
}
844

845
// FinalHtlcByte defines a byte type that encodes information about the final
846
// htlc resolution.
847
type FinalHtlcByte byte
848

849
const (
850
        // FinalHtlcSettledBit is the bit that encodes whether the htlc was
851
        // settled or failed.
852
        FinalHtlcSettledBit FinalHtlcByte = 1 << 0
853

854
        // FinalHtlcOffchainBit is the bit that encodes whether the htlc was
855
        // resolved offchain or onchain.
856
        FinalHtlcOffchainBit FinalHtlcByte = 1 << 1
857
)
858

859
// OpenChannel encapsulates the persistent and dynamic state of an open channel
860
// with a remote node. An open channel supports several options for on-disk
861
// serialization depending on the exact context. Full (upon channel creation)
862
// state commitments, and partial (due to a commitment update) writes are
863
// supported. Each partial write due to a state update appends the new update
864
// to an on-disk log, which can then subsequently be queried in order to
865
// "time-travel" to a prior state.
866
type OpenChannel struct {
867
        // ChanType denotes which type of channel this is.
868
        ChanType ChannelType
869

870
        // ChainHash is a hash which represents the blockchain that this
871
        // channel will be opened within. This value is typically the genesis
872
        // hash. In the case that the original chain went through a contentious
873
        // hard-fork, then this value will be tweaked using the unique fork
874
        // point on each branch.
875
        ChainHash chainhash.Hash
876

877
        // FundingOutpoint is the outpoint of the final funding transaction.
878
        // This value uniquely and globally identifies the channel within the
879
        // target blockchain as specified by the chain hash parameter.
880
        FundingOutpoint wire.OutPoint
881

882
        // ShortChannelID encodes the exact location in the chain in which the
883
        // channel was initially confirmed. This includes: the block height,
884
        // transaction index, and the output within the target transaction.
885
        //
886
        // If IsZeroConf(), then this will the "base" (very first) ALIAS scid
887
        // and the confirmed SCID will be stored in ConfirmedScid.
888
        ShortChannelID lnwire.ShortChannelID
889

890
        // IsPending indicates whether a channel's funding transaction has been
891
        // confirmed.
892
        IsPending bool
893

894
        // IsInitiator is a bool which indicates if we were the original
895
        // initiator for the channel. This value may affect how higher levels
896
        // negotiate fees, or close the channel.
897
        IsInitiator bool
898

899
        // chanStatus is the current status of this channel. If it is not in
900
        // the state Default, it should not be used for forwarding payments.
901
        chanStatus ChannelStatus
902

903
        // FundingBroadcastHeight is the height in which the funding
904
        // transaction was broadcast. This value can be used by higher level
905
        // sub-systems to determine if a channel is stale and/or should have
906
        // been confirmed before a certain height.
907
        FundingBroadcastHeight uint32
908

909
        // NumConfsRequired is the number of confirmations a channel's funding
910
        // transaction must have received in order to be considered available
911
        // for normal transactional use.
912
        NumConfsRequired uint16
913

914
        // ChannelFlags holds the flags that were sent as part of the
915
        // open_channel message.
916
        ChannelFlags lnwire.FundingFlag
917

918
        // IdentityPub is the identity public key of the remote node this
919
        // channel has been established with.
920
        IdentityPub *btcec.PublicKey
921

922
        // Capacity is the total capacity of this channel.
923
        Capacity btcutil.Amount
924

925
        // TotalMSatSent is the total number of milli-satoshis we've sent
926
        // within this channel.
927
        TotalMSatSent lnwire.MilliSatoshi
928

929
        // TotalMSatReceived is the total number of milli-satoshis we've
930
        // received within this channel.
931
        TotalMSatReceived lnwire.MilliSatoshi
932

933
        // InitialLocalBalance is the balance we have during the channel
934
        // opening. When we are not the initiator, this value represents the
935
        // push amount.
936
        InitialLocalBalance lnwire.MilliSatoshi
937

938
        // InitialRemoteBalance is the balance they have during the channel
939
        // opening.
940
        InitialRemoteBalance lnwire.MilliSatoshi
941

942
        // LocalChanCfg is the channel configuration for the local node.
943
        LocalChanCfg ChannelConfig
944

945
        // RemoteChanCfg is the channel configuration for the remote node.
946
        RemoteChanCfg ChannelConfig
947

948
        // LocalCommitment is the current local commitment state for the local
949
        // party. This is stored distinct from the state of the remote party
950
        // as there are certain asymmetric parameters which affect the
951
        // structure of each commitment.
952
        LocalCommitment ChannelCommitment
953

954
        // RemoteCommitment is the current remote commitment state for the
955
        // remote party. This is stored distinct from the state of the local
956
        // party as there are certain asymmetric parameters which affect the
957
        // structure of each commitment.
958
        RemoteCommitment ChannelCommitment
959

960
        // RemoteCurrentRevocation is the current revocation for their
961
        // commitment transaction. However, since this the derived public key,
962
        // we don't yet have the private key so we aren't yet able to verify
963
        // that it's actually in the hash chain.
964
        RemoteCurrentRevocation *btcec.PublicKey
965

966
        // RemoteNextRevocation is the revocation key to be used for the *next*
967
        // commitment transaction we create for the local node. Within the
968
        // specification, this value is referred to as the
969
        // per-commitment-point.
970
        RemoteNextRevocation *btcec.PublicKey
971

972
        // RevocationProducer is used to generate the revocation in such a way
973
        // that remote side might store it efficiently and have the ability to
974
        // restore the revocation by index if needed. Current implementation of
975
        // secret producer is shachain producer.
976
        RevocationProducer shachain.Producer
977

978
        // RevocationStore is used to efficiently store the revocations for
979
        // previous channels states sent to us by remote side. Current
980
        // implementation of secret store is shachain store.
981
        RevocationStore shachain.Store
982

983
        // Packager is used to create and update forwarding packages for this
984
        // channel, which encodes all necessary information to recover from
985
        // failures and reforward HTLCs that were not fully processed.
986
        Packager FwdPackager
987

988
        // FundingTxn is the transaction containing this channel's funding
989
        // outpoint. Upon restarts, this txn will be rebroadcast if the channel
990
        // is found to be pending.
991
        //
992
        // NOTE: This value will only be populated for single-funder channels
993
        // for which we are the initiator, and that we also have the funding
994
        // transaction for. One can check this by using the HasFundingTx()
995
        // method on the ChanType field.
996
        FundingTxn *wire.MsgTx
997

998
        // LocalShutdownScript is set to a pre-set script if the channel was opened
999
        // by the local node with option_upfront_shutdown_script set. If the option
1000
        // was not set, the field is empty.
1001
        LocalShutdownScript lnwire.DeliveryAddress
1002

1003
        // RemoteShutdownScript is set to a pre-set script if the channel was opened
1004
        // by the remote node with option_upfront_shutdown_script set. If the option
1005
        // was not set, the field is empty.
1006
        RemoteShutdownScript lnwire.DeliveryAddress
1007

1008
        // ThawHeight is the height when a frozen channel once again becomes a
1009
        // normal channel. If this is zero, then there're no restrictions on
1010
        // this channel. If the value is lower than 500,000, then it's
1011
        // interpreted as a relative height, or an absolute height otherwise.
1012
        ThawHeight uint32
1013

1014
        // LastWasRevoke is a boolean that determines if the last update we sent
1015
        // was a revocation (true) or a commitment signature (false).
1016
        LastWasRevoke bool
1017

1018
        // RevocationKeyLocator stores the KeyLocator information that we will
1019
        // need to derive the shachain root for this channel. This allows us to
1020
        // have private key isolation from lnd.
1021
        RevocationKeyLocator keychain.KeyLocator
1022

1023
        // confirmedScid is the confirmed ShortChannelID for a zero-conf
1024
        // channel. If the channel is unconfirmed, then this will be the
1025
        // default ShortChannelID. This is only set for zero-conf channels.
1026
        confirmedScid lnwire.ShortChannelID
1027

1028
        // Memo is any arbitrary information we wish to store locally about the
1029
        // channel that will be useful to our future selves.
1030
        Memo []byte
1031

1032
        // TapscriptRoot is an optional tapscript root used to derive the MuSig2
1033
        // funding output.
1034
        TapscriptRoot fn.Option[chainhash.Hash]
1035

1036
        // CustomBlob is an optional blob that can be used to store information
1037
        // specific to a custom channel type. This information is only created
1038
        // at channel funding time, and after wards is to be considered
1039
        // immutable.
1040
        CustomBlob fn.Option[tlv.Blob]
1041

1042
        // TODO(roasbeef): eww
1043
        Db *ChannelStateDB
1044

1045
        // TODO(roasbeef): just need to store local and remote HTLC's?
1046

1047
        sync.RWMutex
1048
}
1049

1050
// String returns a string representation of the channel.
1051
func (c *OpenChannel) String() string {
4✔
1052
        indexStr := "height=%v, local_htlc_index=%v, local_log_index=%v, " +
4✔
1053
                "remote_htlc_index=%v, remote_log_index=%v"
4✔
1054

4✔
1055
        commit := c.LocalCommitment
4✔
1056
        local := fmt.Sprintf(indexStr, commit.CommitHeight,
4✔
1057
                commit.LocalHtlcIndex, commit.LocalLogIndex,
4✔
1058
                commit.RemoteHtlcIndex, commit.RemoteLogIndex,
4✔
1059
        )
4✔
1060

4✔
1061
        commit = c.RemoteCommitment
4✔
1062
        remote := fmt.Sprintf(indexStr, commit.CommitHeight,
4✔
1063
                commit.LocalHtlcIndex, commit.LocalLogIndex,
4✔
1064
                commit.RemoteHtlcIndex, commit.RemoteLogIndex,
4✔
1065
        )
4✔
1066

4✔
1067
        return fmt.Sprintf("SCID=%v, status=%v, initiator=%v, pending=%v, "+
4✔
1068
                "local commitment has %s, remote commitment has %s",
4✔
1069
                c.ShortChannelID, c.chanStatus, c.IsInitiator, c.IsPending,
4✔
1070
                local, remote,
4✔
1071
        )
4✔
1072
}
4✔
1073

1074
// Initiator returns the ChannelParty that originally opened this channel.
1075
func (c *OpenChannel) Initiator() lntypes.ChannelParty {
15,456✔
1076
        c.RLock()
15,456✔
1077
        defer c.RUnlock()
15,456✔
1078

15,456✔
1079
        if c.IsInitiator {
25,024✔
1080
                return lntypes.Local
9,568✔
1081
        }
9,568✔
1082

1083
        return lntypes.Remote
5,892✔
1084
}
1085

1086
// ShortChanID returns the current ShortChannelID of this channel.
1087
func (c *OpenChannel) ShortChanID() lnwire.ShortChannelID {
8,230✔
1088
        c.RLock()
8,230✔
1089
        defer c.RUnlock()
8,230✔
1090

8,230✔
1091
        return c.ShortChannelID
8,230✔
1092
}
8,230✔
1093

1094
// ZeroConfRealScid returns the zero-conf channel's confirmed scid. This should
1095
// only be called if IsZeroConf returns true.
1096
func (c *OpenChannel) ZeroConfRealScid() lnwire.ShortChannelID {
13✔
1097
        c.RLock()
13✔
1098
        defer c.RUnlock()
13✔
1099

13✔
1100
        return c.confirmedScid
13✔
1101
}
13✔
1102

1103
// ZeroConfConfirmed returns whether the zero-conf channel has confirmed. This
1104
// should only be called if IsZeroConf returns true.
1105
func (c *OpenChannel) ZeroConfConfirmed() bool {
42✔
1106
        c.RLock()
42✔
1107
        defer c.RUnlock()
42✔
1108

42✔
1109
        return c.confirmedScid != hop.Source
42✔
1110
}
42✔
1111

1112
// IsZeroConf returns whether the option_zeroconf channel type was negotiated.
1113
func (c *OpenChannel) IsZeroConf() bool {
648✔
1114
        c.RLock()
648✔
1115
        defer c.RUnlock()
648✔
1116

648✔
1117
        return c.ChanType.HasZeroConf()
648✔
1118
}
648✔
1119

1120
// IsOptionScidAlias returns whether the option_scid_alias channel type was
1121
// negotiated.
1122
func (c *OpenChannel) IsOptionScidAlias() bool {
×
1123
        c.RLock()
×
1124
        defer c.RUnlock()
×
1125

×
1126
        return c.ChanType.HasScidAliasChan()
×
1127
}
×
1128

1129
// NegotiatedAliasFeature returns whether the option-scid-alias feature bit was
1130
// negotiated.
1131
func (c *OpenChannel) NegotiatedAliasFeature() bool {
486✔
1132
        c.RLock()
486✔
1133
        defer c.RUnlock()
486✔
1134

486✔
1135
        return c.ChanType.HasScidAliasFeature()
486✔
1136
}
486✔
1137

1138
// ChanStatus returns the current ChannelStatus of this channel.
1139
func (c *OpenChannel) ChanStatus() ChannelStatus {
215✔
1140
        c.RLock()
215✔
1141
        defer c.RUnlock()
215✔
1142

215✔
1143
        return c.chanStatus
215✔
1144
}
215✔
1145

1146
// ApplyChanStatus allows the caller to modify the internal channel state in a
1147
// thead-safe manner.
1148
func (c *OpenChannel) ApplyChanStatus(status ChannelStatus) error {
3✔
1149
        c.Lock()
3✔
1150
        defer c.Unlock()
3✔
1151

3✔
1152
        return c.putChanStatus(status)
3✔
1153
}
3✔
1154

1155
// ClearChanStatus allows the caller to clear a particular channel status from
1156
// the primary channel status bit field. After this method returns, a call to
1157
// HasChanStatus(status) should return false.
1158
func (c *OpenChannel) ClearChanStatus(status ChannelStatus) error {
4✔
1159
        c.Lock()
4✔
1160
        defer c.Unlock()
4✔
1161

4✔
1162
        return c.clearChanStatus(status)
4✔
1163
}
4✔
1164

1165
// HasChanStatus returns true if the internal bitfield channel status of the
1166
// target channel has the specified status bit set.
1167
func (c *OpenChannel) HasChanStatus(status ChannelStatus) bool {
377✔
1168
        c.RLock()
377✔
1169
        defer c.RUnlock()
377✔
1170

377✔
1171
        return c.hasChanStatus(status)
377✔
1172
}
377✔
1173

1174
func (c *OpenChannel) hasChanStatus(status ChannelStatus) bool {
20,626✔
1175
        // Special case ChanStatusDefualt since it isn't actually flag, but a
20,626✔
1176
        // particular combination (or lack-there-of) of flags.
20,626✔
1177
        if status == ChanStatusDefault {
20,635✔
1178
                return c.chanStatus == ChanStatusDefault
9✔
1179
        }
9✔
1180

1181
        return c.chanStatus&status == status
20,621✔
1182
}
1183

1184
// BroadcastHeight returns the height at which the funding tx was broadcast.
1185
func (c *OpenChannel) BroadcastHeight() uint32 {
140✔
1186
        c.RLock()
140✔
1187
        defer c.RUnlock()
140✔
1188

140✔
1189
        return c.FundingBroadcastHeight
140✔
1190
}
140✔
1191

1192
// SetBroadcastHeight sets the FundingBroadcastHeight.
1193
func (c *OpenChannel) SetBroadcastHeight(height uint32) {
4✔
1194
        c.Lock()
4✔
1195
        defer c.Unlock()
4✔
1196

4✔
1197
        c.FundingBroadcastHeight = height
4✔
1198
}
4✔
1199

1200
// amendTlvData updates the channel with the given auxiliary TLV data.
1201
func (c *OpenChannel) amendTlvData(auxData openChannelTlvData) {
7,121✔
1202
        c.RevocationKeyLocator = auxData.revokeKeyLoc.Val.KeyLocator
7,121✔
1203
        c.InitialLocalBalance = lnwire.MilliSatoshi(
7,121✔
1204
                auxData.initialLocalBalance.Val,
7,121✔
1205
        )
7,121✔
1206
        c.InitialRemoteBalance = lnwire.MilliSatoshi(
7,121✔
1207
                auxData.initialRemoteBalance.Val,
7,121✔
1208
        )
7,121✔
1209
        c.confirmedScid = auxData.realScid.Val
7,121✔
1210

7,121✔
1211
        auxData.memo.WhenSomeV(func(memo []byte) {
7,452✔
1212
                c.Memo = memo
331✔
1213
        })
331✔
1214
        auxData.tapscriptRoot.WhenSomeV(func(h [32]byte) {
7,556✔
1215
                c.TapscriptRoot = fn.Some[chainhash.Hash](h)
435✔
1216
        })
435✔
1217
        auxData.customBlob.WhenSomeV(func(blob tlv.Blob) {
7,448✔
1218
                c.CustomBlob = fn.Some(blob)
327✔
1219
        })
327✔
1220
}
1221

1222
// extractTlvData creates a new openChannelTlvData from the given channel.
1223
func (c *OpenChannel) extractTlvData() openChannelTlvData {
3,217✔
1224
        auxData := openChannelTlvData{
3,217✔
1225
                revokeKeyLoc: tlv.NewRecordT[tlv.TlvType1](
3,217✔
1226
                        keyLocRecord{c.RevocationKeyLocator},
3,217✔
1227
                ),
3,217✔
1228
                initialLocalBalance: tlv.NewPrimitiveRecord[tlv.TlvType2](
3,217✔
1229
                        uint64(c.InitialLocalBalance),
3,217✔
1230
                ),
3,217✔
1231
                initialRemoteBalance: tlv.NewPrimitiveRecord[tlv.TlvType3](
3,217✔
1232
                        uint64(c.InitialRemoteBalance),
3,217✔
1233
                ),
3,217✔
1234
                realScid: tlv.NewRecordT[tlv.TlvType4](
3,217✔
1235
                        c.confirmedScid,
3,217✔
1236
                ),
3,217✔
1237
        }
3,217✔
1238

3,217✔
1239
        if len(c.Memo) != 0 {
3,642✔
1240
                auxData.memo = tlv.SomeRecordT(
425✔
1241
                        tlv.NewPrimitiveRecord[tlv.TlvType5](c.Memo),
425✔
1242
                )
425✔
1243
        }
425✔
1244
        c.TapscriptRoot.WhenSome(func(h chainhash.Hash) {
3,690✔
1245
                auxData.tapscriptRoot = tlv.SomeRecordT(
473✔
1246
                        tlv.NewPrimitiveRecord[tlv.TlvType6, [32]byte](h),
473✔
1247
                )
473✔
1248
        })
473✔
1249
        c.CustomBlob.WhenSome(func(blob tlv.Blob) {
3,638✔
1250
                auxData.customBlob = tlv.SomeRecordT(
421✔
1251
                        tlv.NewPrimitiveRecord[tlv.TlvType7](blob),
421✔
1252
                )
421✔
1253
        })
421✔
1254

1255
        return auxData
3,217✔
1256
}
1257

1258
// Refresh updates the in-memory channel state using the latest state observed
1259
// on disk.
1260
func (c *OpenChannel) Refresh() error {
9✔
1261
        c.Lock()
9✔
1262
        defer c.Unlock()
9✔
1263

9✔
1264
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
18✔
1265
                chanBucket, err := fetchChanBucket(
9✔
1266
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
9✔
1267
                )
9✔
1268
                if err != nil {
13✔
1269
                        return err
4✔
1270
                }
4✔
1271

1272
                // We'll re-populating the in-memory channel with the info
1273
                // fetched from disk.
1274
                if err := fetchChanInfo(chanBucket, c); err != nil {
9✔
1275
                        return fmt.Errorf("unable to fetch chan info: %w", err)
×
1276
                }
×
1277

1278
                // Also populate the channel's commitment states for both sides
1279
                // of the channel.
1280
                if err := fetchChanCommitments(chanBucket, c); err != nil {
9✔
1281
                        return fmt.Errorf("unable to fetch chan commitments: "+
×
1282
                                "%v", err)
×
1283
                }
×
1284

1285
                // Also retrieve the current revocation state.
1286
                if err := fetchChanRevocationState(chanBucket, c); err != nil {
9✔
1287
                        return fmt.Errorf("unable to fetch chan revocations: "+
×
1288
                                "%v", err)
×
1289
                }
×
1290

1291
                return nil
9✔
1292
        }, func() {})
9✔
1293
        if err != nil {
13✔
1294
                return err
4✔
1295
        }
4✔
1296

1297
        return nil
9✔
1298
}
1299

1300
// fetchChanBucket is a helper function that returns the bucket where a
1301
// channel's data resides in given: the public key for the node, the outpoint,
1302
// and the chainhash that the channel resides on.
1303
func fetchChanBucket(tx kvdb.RTx, nodeKey *btcec.PublicKey,
1304
        outPoint *wire.OutPoint, chainHash chainhash.Hash) (kvdb.RBucket, error) {
2,945✔
1305

2,945✔
1306
        // First fetch the top level bucket which stores all data related to
2,945✔
1307
        // current, active channels.
2,945✔
1308
        openChanBucket := tx.ReadBucket(openChannelBucket)
2,945✔
1309
        if openChanBucket == nil {
2,945✔
1310
                return nil, ErrNoChanDBExists
×
1311
        }
×
1312

1313
        // TODO(roasbeef): CreateTopLevelBucket on the interface isn't like
1314
        // CreateIfNotExists, will return error
1315

1316
        // Within this top level bucket, fetch the bucket dedicated to storing
1317
        // open channel data specific to the remote node.
1318
        nodePub := nodeKey.SerializeCompressed()
2,945✔
1319
        nodeChanBucket := openChanBucket.NestedReadBucket(nodePub)
2,945✔
1320
        if nodeChanBucket == nil {
4,055✔
1321
                return nil, ErrNoActiveChannels
1,110✔
1322
        }
1,110✔
1323

1324
        // We'll then recurse down an additional layer in order to fetch the
1325
        // bucket for this particular chain.
1326
        chainBucket := nodeChanBucket.NestedReadBucket(chainHash[:])
1,835✔
1327
        if chainBucket == nil {
1,835✔
1328
                return nil, ErrNoActiveChannels
×
1329
        }
×
1330

1331
        // With the bucket for the node and chain fetched, we can now go down
1332
        // another level, for this channel itself.
1333
        var chanPointBuf bytes.Buffer
1,835✔
1334
        if err := graphdb.WriteOutpoint(&chanPointBuf, outPoint); err != nil {
1,835✔
1335
                return nil, err
×
1336
        }
×
1337
        chanBucket := chainBucket.NestedReadBucket(chanPointBuf.Bytes())
1,835✔
1338
        if chanBucket == nil {
1,840✔
1339
                return nil, ErrChannelNotFound
5✔
1340
        }
5✔
1341

1342
        return chanBucket, nil
1,834✔
1343
}
1344

1345
// fetchChanBucketRw is a helper function that returns the bucket where a
1346
// channel's data resides in given: the public key for the node, the outpoint,
1347
// and the chainhash that the channel resides on. This differs from
1348
// fetchChanBucket in that it returns a writeable bucket.
1349
func fetchChanBucketRw(tx kvdb.RwTx, nodeKey *btcec.PublicKey,
1350
        outPoint *wire.OutPoint, chainHash chainhash.Hash) (kvdb.RwBucket,
1351
        error) {
6,852✔
1352

6,852✔
1353
        // First fetch the top level bucket which stores all data related to
6,852✔
1354
        // current, active channels.
6,852✔
1355
        openChanBucket := tx.ReadWriteBucket(openChannelBucket)
6,852✔
1356
        if openChanBucket == nil {
6,852✔
1357
                return nil, ErrNoChanDBExists
×
1358
        }
×
1359

1360
        // TODO(roasbeef): CreateTopLevelBucket on the interface isn't like
1361
        // CreateIfNotExists, will return error
1362

1363
        // Within this top level bucket, fetch the bucket dedicated to storing
1364
        // open channel data specific to the remote node.
1365
        nodePub := nodeKey.SerializeCompressed()
6,852✔
1366
        nodeChanBucket := openChanBucket.NestedReadWriteBucket(nodePub)
6,852✔
1367
        if nodeChanBucket == nil {
6,852✔
1368
                return nil, ErrNoActiveChannels
×
1369
        }
×
1370

1371
        // We'll then recurse down an additional layer in order to fetch the
1372
        // bucket for this particular chain.
1373
        chainBucket := nodeChanBucket.NestedReadWriteBucket(chainHash[:])
6,852✔
1374
        if chainBucket == nil {
6,852✔
1375
                return nil, ErrNoActiveChannels
×
1376
        }
×
1377

1378
        // With the bucket for the node and chain fetched, we can now go down
1379
        // another level, for this channel itself.
1380
        var chanPointBuf bytes.Buffer
6,852✔
1381
        if err := graphdb.WriteOutpoint(&chanPointBuf, outPoint); err != nil {
6,852✔
1382
                return nil, err
×
1383
        }
×
1384
        chanBucket := chainBucket.NestedReadWriteBucket(chanPointBuf.Bytes())
6,852✔
1385
        if chanBucket == nil {
6,853✔
1386
                return nil, ErrChannelNotFound
1✔
1387
        }
1✔
1388

1389
        return chanBucket, nil
6,852✔
1390
}
1391

1392
func fetchFinalHtlcsBucketRw(tx kvdb.RwTx,
1393
        chanID lnwire.ShortChannelID) (kvdb.RwBucket, error) {
7✔
1394

7✔
1395
        finalHtlcsBucket, err := tx.CreateTopLevelBucket(finalHtlcsBucket)
7✔
1396
        if err != nil {
7✔
1397
                return nil, err
×
1398
        }
×
1399

1400
        var chanIDBytes [8]byte
7✔
1401
        byteOrder.PutUint64(chanIDBytes[:], chanID.ToUint64())
7✔
1402
        chanBucket, err := finalHtlcsBucket.CreateBucketIfNotExists(
7✔
1403
                chanIDBytes[:],
7✔
1404
        )
7✔
1405
        if err != nil {
7✔
1406
                return nil, err
×
1407
        }
×
1408

1409
        return chanBucket, nil
7✔
1410
}
1411

1412
// fullSync syncs the contents of an OpenChannel while re-using an existing
1413
// database transaction.
1414
func (c *OpenChannel) fullSync(tx kvdb.RwTx) error {
881✔
1415
        // Fetch the outpoint bucket and check if the outpoint already exists.
881✔
1416
        opBucket := tx.ReadWriteBucket(outpointBucket)
881✔
1417
        if opBucket == nil {
881✔
1418
                return ErrNoChanDBExists
×
1419
        }
×
1420
        cidBucket := tx.ReadWriteBucket(chanIDBucket)
881✔
1421
        if cidBucket == nil {
881✔
1422
                return ErrNoChanDBExists
×
1423
        }
×
1424

1425
        var chanPointBuf bytes.Buffer
881✔
1426
        err := graphdb.WriteOutpoint(&chanPointBuf, &c.FundingOutpoint)
881✔
1427
        if err != nil {
881✔
1428
                return err
×
1429
        }
×
1430

1431
        // Now, check if the outpoint exists in our index.
1432
        if opBucket.Get(chanPointBuf.Bytes()) != nil {
885✔
1433
                return ErrChanAlreadyExists
4✔
1434
        }
4✔
1435

1436
        cid := lnwire.NewChanIDFromOutPoint(c.FundingOutpoint)
881✔
1437
        if cidBucket.Get(cid[:]) != nil {
881✔
1438
                return ErrChanAlreadyExists
×
1439
        }
×
1440

1441
        status := uint8(outpointOpen)
881✔
1442

881✔
1443
        // Write the status of this outpoint as the first entry in a tlv
881✔
1444
        // stream.
881✔
1445
        statusRecord := tlv.MakePrimitiveRecord(indexStatusType, &status)
881✔
1446
        opStream, err := tlv.NewStream(statusRecord)
881✔
1447
        if err != nil {
881✔
1448
                return err
×
1449
        }
×
1450

1451
        var b bytes.Buffer
881✔
1452
        if err := opStream.Encode(&b); err != nil {
881✔
1453
                return err
×
1454
        }
×
1455

1456
        // Add the outpoint to our outpoint index with the tlv stream.
1457
        if err := opBucket.Put(chanPointBuf.Bytes(), b.Bytes()); err != nil {
881✔
1458
                return err
×
1459
        }
×
1460

1461
        if err := cidBucket.Put(cid[:], []byte{}); err != nil {
881✔
1462
                return err
×
1463
        }
×
1464

1465
        // First fetch the top level bucket which stores all data related to
1466
        // current, active channels.
1467
        openChanBucket, err := tx.CreateTopLevelBucket(openChannelBucket)
881✔
1468
        if err != nil {
881✔
1469
                return err
×
1470
        }
×
1471

1472
        // Within this top level bucket, fetch the bucket dedicated to storing
1473
        // open channel data specific to the remote node.
1474
        nodePub := c.IdentityPub.SerializeCompressed()
881✔
1475
        nodeChanBucket, err := openChanBucket.CreateBucketIfNotExists(nodePub)
881✔
1476
        if err != nil {
881✔
1477
                return err
×
1478
        }
×
1479

1480
        // We'll then recurse down an additional layer in order to fetch the
1481
        // bucket for this particular chain.
1482
        chainBucket, err := nodeChanBucket.CreateBucketIfNotExists(c.ChainHash[:])
881✔
1483
        if err != nil {
881✔
1484
                return err
×
1485
        }
×
1486

1487
        // With the bucket for the node fetched, we can now go down another
1488
        // level, creating the bucket for this channel itself.
1489
        chanBucket, err := chainBucket.CreateBucket(
881✔
1490
                chanPointBuf.Bytes(),
881✔
1491
        )
881✔
1492
        switch {
881✔
1493
        case err == kvdb.ErrBucketExists:
×
1494
                // If this channel already exists, then in order to avoid
×
1495
                // overriding it, we'll return an error back up to the caller.
×
1496
                return ErrChanAlreadyExists
×
1497
        case err != nil:
×
1498
                return err
×
1499
        }
1500

1501
        return putOpenChannel(chanBucket, c)
881✔
1502
}
1503

1504
// MarkAsOpen marks a channel as fully open given a locator that uniquely
1505
// describes its location within the chain.
1506
func (c *OpenChannel) MarkAsOpen(openLoc lnwire.ShortChannelID) error {
167✔
1507
        c.Lock()
167✔
1508
        defer c.Unlock()
167✔
1509

167✔
1510
        if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
334✔
1511
                chanBucket, err := fetchChanBucketRw(
167✔
1512
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
167✔
1513
                )
167✔
1514
                if err != nil {
167✔
1515
                        return err
×
1516
                }
×
1517

1518
                channel, err := fetchOpenChannel(chanBucket, &c.FundingOutpoint)
167✔
1519
                if err != nil {
167✔
1520
                        return err
×
1521
                }
×
1522

1523
                channel.IsPending = false
167✔
1524
                channel.ShortChannelID = openLoc
167✔
1525

167✔
1526
                return putOpenChannel(chanBucket, channel)
167✔
1527
        }, func() {}); err != nil {
167✔
1528
                return err
×
1529
        }
×
1530

1531
        c.IsPending = false
167✔
1532
        c.ShortChannelID = openLoc
167✔
1533
        c.Packager = NewChannelPackager(openLoc)
167✔
1534

167✔
1535
        return nil
167✔
1536
}
1537

1538
// MarkRealScid marks the zero-conf channel's confirmed ShortChannelID. This
1539
// should only be done if IsZeroConf returns true.
1540
func (c *OpenChannel) MarkRealScid(realScid lnwire.ShortChannelID) error {
11✔
1541
        c.Lock()
11✔
1542
        defer c.Unlock()
11✔
1543

11✔
1544
        if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
22✔
1545
                chanBucket, err := fetchChanBucketRw(
11✔
1546
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
11✔
1547
                )
11✔
1548
                if err != nil {
11✔
1549
                        return err
×
1550
                }
×
1551

1552
                channel, err := fetchOpenChannel(
11✔
1553
                        chanBucket, &c.FundingOutpoint,
11✔
1554
                )
11✔
1555
                if err != nil {
11✔
1556
                        return err
×
1557
                }
×
1558

1559
                channel.confirmedScid = realScid
11✔
1560

11✔
1561
                return putOpenChannel(chanBucket, channel)
11✔
1562
        }, func() {}); err != nil {
11✔
1563
                return err
×
1564
        }
×
1565

1566
        c.confirmedScid = realScid
11✔
1567

11✔
1568
        return nil
11✔
1569
}
1570

1571
// MarkScidAliasNegotiated adds ScidAliasFeatureBit to ChanType in-memory and
1572
// in the database.
1573
func (c *OpenChannel) MarkScidAliasNegotiated() error {
4✔
1574
        c.Lock()
4✔
1575
        defer c.Unlock()
4✔
1576

4✔
1577
        if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
8✔
1578
                chanBucket, err := fetchChanBucketRw(
4✔
1579
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
4✔
1580
                )
4✔
1581
                if err != nil {
4✔
1582
                        return err
×
1583
                }
×
1584

1585
                channel, err := fetchOpenChannel(
4✔
1586
                        chanBucket, &c.FundingOutpoint,
4✔
1587
                )
4✔
1588
                if err != nil {
4✔
1589
                        return err
×
1590
                }
×
1591

1592
                channel.ChanType |= ScidAliasFeatureBit
4✔
1593
                return putOpenChannel(chanBucket, channel)
4✔
1594
        }, func() {}); err != nil {
4✔
1595
                return err
×
1596
        }
×
1597

1598
        c.ChanType |= ScidAliasFeatureBit
4✔
1599

4✔
1600
        return nil
4✔
1601
}
1602

1603
// MarkDataLoss marks sets the channel status to LocalDataLoss and stores the
1604
// passed commitPoint for use to retrieve funds in case the remote force closes
1605
// the channel.
1606
func (c *OpenChannel) MarkDataLoss(commitPoint *btcec.PublicKey) error {
8✔
1607
        c.Lock()
8✔
1608
        defer c.Unlock()
8✔
1609

8✔
1610
        var b bytes.Buffer
8✔
1611
        if err := WriteElement(&b, commitPoint); err != nil {
8✔
1612
                return err
×
1613
        }
×
1614

1615
        putCommitPoint := func(chanBucket kvdb.RwBucket) error {
16✔
1616
                return chanBucket.Put(dataLossCommitPointKey, b.Bytes())
8✔
1617
        }
8✔
1618

1619
        return c.putChanStatus(ChanStatusLocalDataLoss, putCommitPoint)
8✔
1620
}
1621

1622
// DataLossCommitPoint retrieves the stored commit point set during
1623
// MarkDataLoss. If not found ErrNoCommitPoint is returned.
1624
func (c *OpenChannel) DataLossCommitPoint() (*btcec.PublicKey, error) {
4✔
1625
        var commitPoint *btcec.PublicKey
4✔
1626

4✔
1627
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
8✔
1628
                chanBucket, err := fetchChanBucket(
4✔
1629
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
4✔
1630
                )
4✔
1631
                switch err {
4✔
1632
                case nil:
4✔
1633
                case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
×
1634
                        return ErrNoCommitPoint
×
1635
                default:
×
1636
                        return err
×
1637
                }
1638

1639
                bs := chanBucket.Get(dataLossCommitPointKey)
4✔
1640
                if bs == nil {
4✔
1641
                        return ErrNoCommitPoint
×
1642
                }
×
1643
                r := bytes.NewReader(bs)
4✔
1644
                if err := ReadElements(r, &commitPoint); err != nil {
4✔
1645
                        return err
×
1646
                }
×
1647

1648
                return nil
4✔
1649
        }, func() {
4✔
1650
                commitPoint = nil
4✔
1651
        })
4✔
1652
        if err != nil {
4✔
1653
                return nil, err
×
1654
        }
×
1655

1656
        return commitPoint, nil
4✔
1657
}
1658

1659
// MarkBorked marks the event when the channel as reached an irreconcilable
1660
// state, such as a channel breach or state desynchronization. Borked channels
1661
// should never be added to the switch.
1662
func (c *OpenChannel) MarkBorked() error {
6✔
1663
        c.Lock()
6✔
1664
        defer c.Unlock()
6✔
1665

6✔
1666
        return c.putChanStatus(ChanStatusBorked)
6✔
1667
}
6✔
1668

1669
// SecondCommitmentPoint returns the second per-commitment-point for use in the
1670
// channel_ready message.
1671
func (c *OpenChannel) SecondCommitmentPoint() (*btcec.PublicKey, error) {
4✔
1672
        c.RLock()
4✔
1673
        defer c.RUnlock()
4✔
1674

4✔
1675
        // Since we start at commitment height = 0, the second per commitment
4✔
1676
        // point is actually at the 1st index.
4✔
1677
        revocation, err := c.RevocationProducer.AtIndex(1)
4✔
1678
        if err != nil {
4✔
1679
                return nil, err
×
1680
        }
×
1681

1682
        return input.ComputeCommitmentPoint(revocation[:]), nil
4✔
1683
}
1684

1685
var (
1686
        // taprootRevRootKey is the key used to derive the revocation root for
1687
        // the taproot nonces. This is done via HMAC of the existing revocation
1688
        // root.
1689
        taprootRevRootKey = []byte("taproot-rev-root")
1690
)
1691

1692
// DeriveMusig2Shachain derives a shachain producer for the taproot channel
1693
// from normal shachain revocation root.
1694
func DeriveMusig2Shachain(revRoot shachain.Producer) (shachain.Producer, error) { //nolint:ll
979✔
1695
        // In order to obtain the revocation root hash to create the taproot
979✔
1696
        // revocation, we'll encode the producer into a buffer, then use that
979✔
1697
        // to derive the shachain root needed.
979✔
1698
        var rootHashBuf bytes.Buffer
979✔
1699
        if err := revRoot.Encode(&rootHashBuf); err != nil {
979✔
1700
                return nil, fmt.Errorf("unable to encode producer: %w", err)
×
1701
        }
×
1702

1703
        revRootHash := chainhash.HashH(rootHashBuf.Bytes())
979✔
1704

979✔
1705
        // For taproot channel types, we'll also generate a distinct shachain
979✔
1706
        // root using the same seed information. We'll use this to generate
979✔
1707
        // verification nonces for the channel. We'll bind with this a simple
979✔
1708
        // hmac.
979✔
1709
        taprootRevHmac := hmac.New(sha256.New, taprootRevRootKey)
979✔
1710
        if _, err := taprootRevHmac.Write(revRootHash[:]); err != nil {
979✔
1711
                return nil, err
×
1712
        }
×
1713

1714
        taprootRevRoot := taprootRevHmac.Sum(nil)
979✔
1715

979✔
1716
        // Once we have the root, we can then generate our shachain producer
979✔
1717
        // and from that generate the per-commitment point.
979✔
1718
        return shachain.NewRevocationProducerFromBytes(
979✔
1719
                taprootRevRoot,
979✔
1720
        )
979✔
1721
}
1722

1723
// NewMusigVerificationNonce generates the local or verification nonce for
1724
// another musig2 session. In order to permit our implementation to not have to
1725
// write any secret nonce state to disk, we'll use the _next_ shachain
1726
// pre-image as our primary randomness source. When used to generate the nonce
1727
// again to broadcast our commitment hte current height will be used.
1728
func NewMusigVerificationNonce(pubKey *btcec.PublicKey, targetHeight uint64,
1729
        shaGen shachain.Producer) (*musig2.Nonces, error) {
219✔
1730

219✔
1731
        // Now that we know what height we need, we'll grab the shachain
219✔
1732
        // pre-image at the target destination.
219✔
1733
        nextPreimage, err := shaGen.AtIndex(targetHeight)
219✔
1734
        if err != nil {
219✔
1735
                return nil, err
×
1736
        }
×
1737

1738
        shaChainRand := musig2.WithCustomRand(bytes.NewBuffer(nextPreimage[:]))
219✔
1739
        pubKeyOpt := musig2.WithPublicKey(pubKey)
219✔
1740

219✔
1741
        return musig2.GenNonces(pubKeyOpt, shaChainRand)
219✔
1742
}
1743

1744
// ChanSyncMsg returns the ChannelReestablish message that should be sent upon
1745
// reconnection with the remote peer that we're maintaining this channel with.
1746
// The information contained within this message is necessary to re-sync our
1747
// commitment chains in the case of a last or only partially processed message.
1748
// When the remote party receives this message one of three things may happen:
1749
//
1750
//  1. We're fully synced and no messages need to be sent.
1751
//  2. We didn't get the last CommitSig message they sent, so they'll re-send
1752
//     it.
1753
//  3. We didn't get the last RevokeAndAck message they sent, so they'll
1754
//     re-send it.
1755
//
1756
// If this is a restored channel, having status ChanStatusRestored, then we'll
1757
// modify our typical chan sync message to ensure they force close even if
1758
// we're on the very first state.
1759
func (c *OpenChannel) ChanSyncMsg() (*lnwire.ChannelReestablish, error) {
258✔
1760
        c.Lock()
258✔
1761
        defer c.Unlock()
258✔
1762

258✔
1763
        // The remote commitment height that we'll send in the
258✔
1764
        // ChannelReestablish message is our current commitment height plus
258✔
1765
        // one. If the receiver thinks that our commitment height is actually
258✔
1766
        // *equal* to this value, then they'll re-send the last commitment that
258✔
1767
        // they sent but we never fully processed.
258✔
1768
        localHeight := c.LocalCommitment.CommitHeight
258✔
1769
        nextLocalCommitHeight := localHeight + 1
258✔
1770

258✔
1771
        // The second value we'll send is the height of the remote commitment
258✔
1772
        // from our PoV. If the receiver thinks that their height is actually
258✔
1773
        // *one plus* this value, then they'll re-send their last revocation.
258✔
1774
        remoteChainTipHeight := c.RemoteCommitment.CommitHeight
258✔
1775

258✔
1776
        // If this channel has undergone a commitment update, then in order to
258✔
1777
        // prove to the remote party our knowledge of their prior commitment
258✔
1778
        // state, we'll also send over the last commitment secret that the
258✔
1779
        // remote party sent.
258✔
1780
        var lastCommitSecret [32]byte
258✔
1781
        if remoteChainTipHeight != 0 {
330✔
1782
                remoteSecret, err := c.RevocationStore.LookUp(
72✔
1783
                        remoteChainTipHeight - 1,
72✔
1784
                )
72✔
1785
                if err != nil {
72✔
1786
                        return nil, err
×
1787
                }
×
1788
                lastCommitSecret = [32]byte(*remoteSecret)
72✔
1789
        }
1790

1791
        // Additionally, we'll send over the current unrevoked commitment on
1792
        // our local commitment transaction.
1793
        currentCommitSecret, err := c.RevocationProducer.AtIndex(
258✔
1794
                localHeight,
258✔
1795
        )
258✔
1796
        if err != nil {
258✔
1797
                return nil, err
×
1798
        }
×
1799

1800
        // If we've restored this channel, then we'll purposefully give them an
1801
        // invalid LocalUnrevokedCommitPoint so they'll force close the channel
1802
        // allowing us to sweep our funds.
1803
        if c.hasChanStatus(ChanStatusRestored) {
262✔
1804
                currentCommitSecret[0] ^= 1
4✔
1805

4✔
1806
                // If this is a tweakless channel, then we'll purposefully send
4✔
1807
                // a next local height taht's invalid to trigger a force close
4✔
1808
                // on their end. We do this as tweakless channels don't require
4✔
1809
                // that the commitment point is valid, only that it's present.
4✔
1810
                if c.ChanType.IsTweakless() {
8✔
1811
                        nextLocalCommitHeight = 0
4✔
1812
                }
4✔
1813
        }
1814

1815
        // If this is a taproot channel, then we'll need to generate our next
1816
        // verification nonce to send to the remote party. They'll use this to
1817
        // sign the next update to our commitment transaction.
1818
        var nextTaprootNonce lnwire.OptMusig2NonceTLV
258✔
1819
        if c.ChanType.IsTaproot() {
283✔
1820
                taprootRevProducer, err := DeriveMusig2Shachain(
25✔
1821
                        c.RevocationProducer,
25✔
1822
                )
25✔
1823
                if err != nil {
25✔
1824
                        return nil, err
×
1825
                }
×
1826

1827
                nextNonce, err := NewMusigVerificationNonce(
25✔
1828
                        c.LocalChanCfg.MultiSigKey.PubKey,
25✔
1829
                        nextLocalCommitHeight, taprootRevProducer,
25✔
1830
                )
25✔
1831
                if err != nil {
25✔
1832
                        return nil, fmt.Errorf("unable to gen next "+
×
1833
                                "nonce: %w", err)
×
1834
                }
×
1835

1836
                nextTaprootNonce = lnwire.SomeMusig2Nonce(nextNonce.PubNonce)
25✔
1837
        }
1838

1839
        return &lnwire.ChannelReestablish{
258✔
1840
                ChanID: lnwire.NewChanIDFromOutPoint(
258✔
1841
                        c.FundingOutpoint,
258✔
1842
                ),
258✔
1843
                NextLocalCommitHeight:  nextLocalCommitHeight,
258✔
1844
                RemoteCommitTailHeight: remoteChainTipHeight,
258✔
1845
                LastRemoteCommitSecret: lastCommitSecret,
258✔
1846
                LocalUnrevokedCommitPoint: input.ComputeCommitmentPoint(
258✔
1847
                        currentCommitSecret[:],
258✔
1848
                ),
258✔
1849
                LocalNonce: nextTaprootNonce,
258✔
1850
        }, nil
258✔
1851
}
1852

1853
// MarkShutdownSent serialises and persist the given ShutdownInfo for this
1854
// channel. Persisting this info represents the fact that we have sent the
1855
// Shutdown message to the remote side and hence that we should re-transmit the
1856
// same Shutdown message on re-establish.
1857
func (c *OpenChannel) MarkShutdownSent(info *ShutdownInfo) error {
15✔
1858
        c.Lock()
15✔
1859
        defer c.Unlock()
15✔
1860

15✔
1861
        return c.storeShutdownInfo(info)
15✔
1862
}
15✔
1863

1864
// storeShutdownInfo serialises the ShutdownInfo and persists it under the
1865
// shutdownInfoKey.
1866
func (c *OpenChannel) storeShutdownInfo(info *ShutdownInfo) error {
15✔
1867
        var b bytes.Buffer
15✔
1868
        err := info.encode(&b)
15✔
1869
        if err != nil {
15✔
1870
                return err
×
1871
        }
×
1872

1873
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
30✔
1874
                chanBucket, err := fetchChanBucketRw(
15✔
1875
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
15✔
1876
                )
15✔
1877
                if err != nil {
15✔
1878
                        return err
×
1879
                }
×
1880

1881
                return chanBucket.Put(shutdownInfoKey, b.Bytes())
15✔
1882
        }, func() {})
15✔
1883
}
1884

1885
// ShutdownInfo decodes the shutdown info stored for this channel and returns
1886
// the result. If no shutdown info has been persisted for this channel then the
1887
// ErrNoShutdownInfo error is returned.
1888
func (c *OpenChannel) ShutdownInfo() (fn.Option[ShutdownInfo], error) {
8✔
1889
        c.RLock()
8✔
1890
        defer c.RUnlock()
8✔
1891

8✔
1892
        var shutdownInfo *ShutdownInfo
8✔
1893
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
16✔
1894
                chanBucket, err := fetchChanBucket(
8✔
1895
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
8✔
1896
                )
8✔
1897
                switch {
8✔
1898
                case err == nil:
8✔
1899
                case errors.Is(err, ErrNoChanDBExists),
1900
                        errors.Is(err, ErrNoActiveChannels),
1901
                        errors.Is(err, ErrChannelNotFound):
2✔
1902

2✔
1903
                        return ErrNoShutdownInfo
2✔
1904
                default:
×
1905
                        return err
×
1906
                }
1907

1908
                shutdownInfoBytes := chanBucket.Get(shutdownInfoKey)
8✔
1909
                if shutdownInfoBytes == nil {
14✔
1910
                        return ErrNoShutdownInfo
6✔
1911
                }
6✔
1912

1913
                shutdownInfo, err = decodeShutdownInfo(shutdownInfoBytes)
6✔
1914

6✔
1915
                return err
6✔
1916
        }, func() {
8✔
1917
                shutdownInfo = nil
8✔
1918
        })
8✔
1919
        if err != nil {
14✔
1920
                return fn.None[ShutdownInfo](), err
6✔
1921
        }
6✔
1922

1923
        return fn.Some[ShutdownInfo](*shutdownInfo), nil
6✔
1924
}
1925

1926
// isBorked returns true if the channel has been marked as borked in the
1927
// database. This requires an existing database transaction to already be
1928
// active.
1929
//
1930
// NOTE: The primary mutex should already be held before this method is called.
1931
func (c *OpenChannel) isBorked(chanBucket kvdb.RBucket) (bool, error) {
5,990✔
1932
        channel, err := fetchOpenChannel(chanBucket, &c.FundingOutpoint)
5,990✔
1933
        if err != nil {
5,990✔
1934
                return false, err
×
1935
        }
×
1936

1937
        return channel.chanStatus != ChanStatusDefault, nil
5,990✔
1938
}
1939

1940
// MarkCommitmentBroadcasted marks the channel as a commitment transaction has
1941
// been broadcast, either our own or the remote, and we should watch the chain
1942
// for it to confirm before taking any further action. It takes as argument the
1943
// closing tx _we believe_ will appear in the chain. This is only used to
1944
// republish this tx at startup to ensure propagation, and we should still
1945
// handle the case where a different tx actually hits the chain.
1946
func (c *OpenChannel) MarkCommitmentBroadcasted(closeTx *wire.MsgTx,
1947
        closer lntypes.ChannelParty) error {
12✔
1948

12✔
1949
        return c.markBroadcasted(
12✔
1950
                ChanStatusCommitBroadcasted, forceCloseTxKey, closeTx,
12✔
1951
                closer,
12✔
1952
        )
12✔
1953
}
12✔
1954

1955
// MarkCoopBroadcasted marks the channel to indicate that a cooperative close
1956
// transaction has been broadcast, either our own or the remote, and that we
1957
// should watch the chain for it to confirm before taking further action. It
1958
// takes as argument a cooperative close tx that could appear on chain, and
1959
// should be rebroadcast upon startup. This is only used to republish and
1960
// ensure propagation, and we should still handle the case where a different tx
1961
// actually hits the chain.
1962
func (c *OpenChannel) MarkCoopBroadcasted(closeTx *wire.MsgTx,
1963
        closer lntypes.ChannelParty) error {
42✔
1964

42✔
1965
        return c.markBroadcasted(
42✔
1966
                ChanStatusCoopBroadcasted, coopCloseTxKey, closeTx,
42✔
1967
                closer,
42✔
1968
        )
42✔
1969
}
42✔
1970

1971
// markBroadcasted is a helper function which modifies the channel status of the
1972
// receiving channel and inserts a close transaction under the requested key,
1973
// which should specify either a coop or force close. It adds a status which
1974
// indicates the party that initiated the channel close.
1975
func (c *OpenChannel) markBroadcasted(status ChannelStatus, key []byte,
1976
        closeTx *wire.MsgTx, closer lntypes.ChannelParty) error {
50✔
1977

50✔
1978
        c.Lock()
50✔
1979
        defer c.Unlock()
50✔
1980

50✔
1981
        // If a closing tx is provided, we'll generate a closure to write the
50✔
1982
        // transaction in the appropriate bucket under the given key.
50✔
1983
        var putClosingTx func(kvdb.RwBucket) error
50✔
1984
        if closeTx != nil {
75✔
1985
                var b bytes.Buffer
25✔
1986
                if err := WriteElement(&b, closeTx); err != nil {
25✔
1987
                        return err
×
1988
                }
×
1989

1990
                putClosingTx = func(chanBucket kvdb.RwBucket) error {
50✔
1991
                        return chanBucket.Put(key, b.Bytes())
25✔
1992
                }
25✔
1993
        }
1994

1995
        // Add the initiator status to the status provided. These statuses are
1996
        // set in addition to the broadcast status so that we do not need to
1997
        // migrate the original logic which does not store initiator.
1998
        if closer.IsLocal() {
94✔
1999
                status |= ChanStatusLocalCloseInitiator
44✔
2000
        } else {
54✔
2001
                status |= ChanStatusRemoteCloseInitiator
10✔
2002
        }
10✔
2003

2004
        return c.putChanStatus(status, putClosingTx)
50✔
2005
}
2006

2007
// BroadcastedCommitment retrieves the stored unilateral closing tx set during
2008
// MarkCommitmentBroadcasted. If not found ErrNoCloseTx is returned.
2009
func (c *OpenChannel) BroadcastedCommitment() (*wire.MsgTx, error) {
11✔
2010
        return c.getClosingTx(forceCloseTxKey)
11✔
2011
}
11✔
2012

2013
// BroadcastedCooperative retrieves the stored cooperative closing tx set during
2014
// MarkCoopBroadcasted. If not found ErrNoCloseTx is returned.
2015
func (c *OpenChannel) BroadcastedCooperative() (*wire.MsgTx, error) {
13✔
2016
        return c.getClosingTx(coopCloseTxKey)
13✔
2017
}
13✔
2018

2019
// getClosingTx is a helper method which returns the stored closing transaction
2020
// for key. The caller should use either the force or coop closing keys.
2021
func (c *OpenChannel) getClosingTx(key []byte) (*wire.MsgTx, error) {
20✔
2022
        var closeTx *wire.MsgTx
20✔
2023

20✔
2024
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
40✔
2025
                chanBucket, err := fetchChanBucket(
20✔
2026
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
20✔
2027
                )
20✔
2028
                switch err {
20✔
2029
                case nil:
20✔
2030
                case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
×
2031
                        return ErrNoCloseTx
×
2032
                default:
×
2033
                        return err
×
2034
                }
2035

2036
                bs := chanBucket.Get(key)
20✔
2037
                if bs == nil {
26✔
2038
                        return ErrNoCloseTx
6✔
2039
                }
6✔
2040
                r := bytes.NewReader(bs)
18✔
2041
                return ReadElement(r, &closeTx)
18✔
2042
        }, func() {
20✔
2043
                closeTx = nil
20✔
2044
        })
20✔
2045
        if err != nil {
26✔
2046
                return nil, err
6✔
2047
        }
6✔
2048

2049
        return closeTx, nil
18✔
2050
}
2051

2052
// putChanStatus appends the given status to the channel. fs is an optional
2053
// list of closures that are given the chanBucket in order to atomically add
2054
// extra information together with the new status.
2055
func (c *OpenChannel) putChanStatus(status ChannelStatus,
2056
        fs ...func(kvdb.RwBucket) error) error {
59✔
2057

59✔
2058
        if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
118✔
2059
                chanBucket, err := fetchChanBucketRw(
59✔
2060
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
59✔
2061
                )
59✔
2062
                if err != nil {
60✔
2063
                        return err
1✔
2064
                }
1✔
2065

2066
                channel, err := fetchOpenChannel(chanBucket, &c.FundingOutpoint)
59✔
2067
                if err != nil {
59✔
2068
                        return err
×
2069
                }
×
2070

2071
                // Add this status to the existing bitvector found in the DB.
2072
                status = channel.chanStatus | status
59✔
2073
                channel.chanStatus = status
59✔
2074

59✔
2075
                if err := putOpenChannel(chanBucket, channel); err != nil {
59✔
2076
                        return err
×
2077
                }
×
2078

2079
                for _, f := range fs {
113✔
2080
                        // Skip execution of nil closures.
54✔
2081
                        if f == nil {
83✔
2082
                                continue
29✔
2083
                        }
2084

2085
                        if err := f(chanBucket); err != nil {
29✔
2086
                                return err
×
2087
                        }
×
2088
                }
2089

2090
                return nil
59✔
2091
        }, func() {}); err != nil {
60✔
2092
                return err
1✔
2093
        }
1✔
2094

2095
        // Update the in-memory representation to keep it in sync with the DB.
2096
        c.chanStatus = status
59✔
2097

59✔
2098
        return nil
59✔
2099
}
2100

2101
func (c *OpenChannel) clearChanStatus(status ChannelStatus) error {
4✔
2102
        if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
8✔
2103
                chanBucket, err := fetchChanBucketRw(
4✔
2104
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
4✔
2105
                )
4✔
2106
                if err != nil {
4✔
2107
                        return err
×
2108
                }
×
2109

2110
                channel, err := fetchOpenChannel(chanBucket, &c.FundingOutpoint)
4✔
2111
                if err != nil {
4✔
2112
                        return err
×
2113
                }
×
2114

2115
                // Unset this bit in the bitvector on disk.
2116
                status = channel.chanStatus & ^status
4✔
2117
                channel.chanStatus = status
4✔
2118

4✔
2119
                return putOpenChannel(chanBucket, channel)
4✔
2120
        }, func() {}); err != nil {
4✔
2121
                return err
×
2122
        }
×
2123

2124
        // Update the in-memory representation to keep it in sync with the DB.
2125
        c.chanStatus = status
4✔
2126

4✔
2127
        return nil
4✔
2128
}
2129

2130
// putOpenChannel serializes, and stores the current state of the channel in its
2131
// entirety.
2132
func putOpenChannel(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
1,224✔
2133
        // First, we'll write out all the relatively static fields, that are
1,224✔
2134
        // decided upon initial channel creation.
1,224✔
2135
        if err := putChanInfo(chanBucket, channel); err != nil {
1,224✔
2136
                return fmt.Errorf("unable to store chan info: %w", err)
×
2137
        }
×
2138

2139
        // With the static channel info written out, we'll now write out the
2140
        // current commitment state for both parties.
2141
        if err := putChanCommitments(chanBucket, channel); err != nil {
1,224✔
2142
                return fmt.Errorf("unable to store chan commitments: %w", err)
×
2143
        }
×
2144

2145
        // Next, if this is a frozen channel, we'll add in the axillary
2146
        // information we need to store.
2147
        if channel.ChanType.IsFrozen() || channel.ChanType.HasLeaseExpiration() {
1,656✔
2148
                err := storeThawHeight(
432✔
2149
                        chanBucket, channel.ThawHeight,
432✔
2150
                )
432✔
2151
                if err != nil {
432✔
2152
                        return fmt.Errorf("unable to store thaw height: %w",
×
2153
                                err)
×
2154
                }
×
2155
        }
2156

2157
        // Finally, we'll write out the revocation state for both parties
2158
        // within a distinct key space.
2159
        if err := putChanRevocationState(chanBucket, channel); err != nil {
1,224✔
2160
                return fmt.Errorf("unable to store chan revocations: %w", err)
×
2161
        }
×
2162

2163
        return nil
1,224✔
2164
}
2165

2166
// fetchOpenChannel retrieves, and deserializes (including decrypting
2167
// sensitive) the complete channel currently active with the passed nodeID.
2168
func fetchOpenChannel(chanBucket kvdb.RBucket,
2169
        chanPoint *wire.OutPoint) (*OpenChannel, error) {
7,116✔
2170

7,116✔
2171
        channel := &OpenChannel{
7,116✔
2172
                FundingOutpoint: *chanPoint,
7,116✔
2173
        }
7,116✔
2174

7,116✔
2175
        // First, we'll read all the static information that changes less
7,116✔
2176
        // frequently from disk.
7,116✔
2177
        if err := fetchChanInfo(chanBucket, channel); err != nil {
7,116✔
2178
                return nil, fmt.Errorf("unable to fetch chan info: %w", err)
×
2179
        }
×
2180

2181
        // With the static information read, we'll now read the current
2182
        // commitment state for both sides of the channel.
2183
        if err := fetchChanCommitments(chanBucket, channel); err != nil {
7,116✔
2184
                return nil, fmt.Errorf("unable to fetch chan commitments: %w",
×
2185
                        err)
×
2186
        }
×
2187

2188
        // Next, if this is a frozen channel, we'll add in the axillary
2189
        // information we need to store.
2190
        if channel.ChanType.IsFrozen() || channel.ChanType.HasLeaseExpiration() {
7,454✔
2191
                thawHeight, err := fetchThawHeight(chanBucket)
338✔
2192
                if err != nil {
338✔
2193
                        return nil, fmt.Errorf("unable to store thaw "+
×
2194
                                "height: %v", err)
×
2195
                }
×
2196

2197
                channel.ThawHeight = thawHeight
338✔
2198
        }
2199

2200
        // Finally, we'll retrieve the current revocation state so we can
2201
        // properly
2202
        if err := fetchChanRevocationState(chanBucket, channel); err != nil {
7,116✔
2203
                return nil, fmt.Errorf("unable to fetch chan revocations: %w",
×
2204
                        err)
×
2205
        }
×
2206

2207
        channel.Packager = NewChannelPackager(channel.ShortChannelID)
7,116✔
2208

7,116✔
2209
        return channel, nil
7,116✔
2210
}
2211

2212
// SyncPending writes the contents of the channel to the database while it's in
2213
// the pending (waiting for funding confirmation) state. The IsPending flag
2214
// will be set to true. When the channel's funding transaction is confirmed,
2215
// the channel should be marked as "open" and the IsPending flag set to false.
2216
// Note that this function also creates a LinkNode relationship between this
2217
// newly created channel and a new LinkNode instance. This allows listing all
2218
// channels in the database globally, or according to the LinkNode they were
2219
// created with.
2220
//
2221
// TODO(roasbeef): addr param should eventually be an lnwire.NetAddress type
2222
// that includes service bits.
2223
func (c *OpenChannel) SyncPending(addr net.Addr, pendingHeight uint32) error {
880✔
2224
        c.Lock()
880✔
2225
        defer c.Unlock()
880✔
2226

880✔
2227
        c.FundingBroadcastHeight = pendingHeight
880✔
2228

880✔
2229
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
1,760✔
2230
                return syncNewChannel(tx, c, []net.Addr{addr})
880✔
2231
        }, func() {})
1,760✔
2232
}
2233

2234
// syncNewChannel will write the passed channel to disk, and also create a
2235
// LinkNode (if needed) for the channel peer.
2236
func syncNewChannel(tx kvdb.RwTx, c *OpenChannel, addrs []net.Addr) error {
881✔
2237
        // First, sync all the persistent channel state to disk.
881✔
2238
        if err := c.fullSync(tx); err != nil {
885✔
2239
                return err
4✔
2240
        }
4✔
2241

2242
        nodeInfoBucket, err := tx.CreateTopLevelBucket(nodeInfoBucket)
881✔
2243
        if err != nil {
881✔
2244
                return err
×
2245
        }
×
2246

2247
        // If a LinkNode for this identity public key already exists,
2248
        // then we can exit early.
2249
        nodePub := c.IdentityPub.SerializeCompressed()
881✔
2250
        if nodeInfoBucket.Get(nodePub) != nil {
1,028✔
2251
                return nil
147✔
2252
        }
147✔
2253

2254
        // Next, we need to establish a (possibly) new LinkNode relationship
2255
        // for this channel. The LinkNode metadata contains reachability,
2256
        // up-time, and service bits related information.
2257
        linkNode := NewLinkNode(
738✔
2258
                &LinkNodeDB{backend: c.Db.backend},
738✔
2259
                wire.MainNet, c.IdentityPub, addrs...,
738✔
2260
        )
738✔
2261

738✔
2262
        // TODO(roasbeef): do away with link node all together?
738✔
2263

738✔
2264
        return putLinkNode(nodeInfoBucket, linkNode)
738✔
2265
}
2266

2267
// UpdateCommitment updates the local commitment state. It locks in the pending
2268
// local updates that were received by us from the remote party. The commitment
2269
// state completely describes the balance state at this point in the commitment
2270
// chain. In addition to that, it persists all the remote log updates that we
2271
// have acked, but not signed a remote commitment for yet. These need to be
2272
// persisted to be able to produce a valid commit signature if a restart would
2273
// occur. This method its to be called when we revoke our prior commitment
2274
// state.
2275
//
2276
// A map is returned of all the htlc resolutions that were locked in this
2277
// commitment. Keys correspond to htlc indices and values indicate whether the
2278
// htlc was settled or failed.
2279
func (c *OpenChannel) UpdateCommitment(newCommitment *ChannelCommitment,
2280
        unsignedAckedUpdates []LogUpdate) (map[uint64]bool, error) {
1,999✔
2281

1,999✔
2282
        c.Lock()
1,999✔
2283
        defer c.Unlock()
1,999✔
2284

1,999✔
2285
        // If this is a restored channel, then we want to avoid mutating the
1,999✔
2286
        // state as all, as it's impossible to do so in a protocol compliant
1,999✔
2287
        // manner.
1,999✔
2288
        if c.hasChanStatus(ChanStatusRestored) {
2,000✔
2289
                return nil, ErrNoRestoredChannelMutation
1✔
2290
        }
1✔
2291

2292
        var finalHtlcs = make(map[uint64]bool)
1,998✔
2293

1,998✔
2294
        err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
3,996✔
2295
                chanBucket, err := fetchChanBucketRw(
1,998✔
2296
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
1,998✔
2297
                )
1,998✔
2298
                if err != nil {
1,998✔
2299
                        return err
×
2300
                }
×
2301

2302
                // If the channel is marked as borked, then for safety reasons,
2303
                // we shouldn't attempt any further updates.
2304
                isBorked, err := c.isBorked(chanBucket)
1,998✔
2305
                if err != nil {
1,998✔
2306
                        return err
×
2307
                }
×
2308
                if isBorked {
1,999✔
2309
                        return ErrChanBorked
1✔
2310
                }
1✔
2311

2312
                if err = putChanInfo(chanBucket, c); err != nil {
1,997✔
2313
                        return fmt.Errorf("unable to store chan info: %w", err)
×
2314
                }
×
2315

2316
                // With the proper bucket fetched, we'll now write the latest
2317
                // commitment state to disk for the target party.
2318
                err = putChanCommitment(
1,997✔
2319
                        chanBucket, newCommitment, true,
1,997✔
2320
                )
1,997✔
2321
                if err != nil {
1,997✔
2322
                        return fmt.Errorf("unable to store chan "+
×
2323
                                "revocations: %v", err)
×
2324
                }
×
2325

2326
                // Persist unsigned but acked remote updates that need to be
2327
                // restored after a restart.
2328
                var b bytes.Buffer
1,997✔
2329
                err = serializeLogUpdates(&b, unsignedAckedUpdates)
1,997✔
2330
                if err != nil {
1,997✔
2331
                        return err
×
2332
                }
×
2333

2334
                err = chanBucket.Put(unsignedAckedUpdatesKey, b.Bytes())
1,997✔
2335
                if err != nil {
1,997✔
2336
                        return fmt.Errorf("unable to store dangline remote "+
×
2337
                                "updates: %v", err)
×
2338
                }
×
2339

2340
                // Since we have just sent the counterparty a revocation, store true
2341
                // under lastWasRevokeKey.
2342
                var b2 bytes.Buffer
1,997✔
2343
                if err := WriteElements(&b2, true); err != nil {
1,997✔
2344
                        return err
×
2345
                }
×
2346

2347
                if err := chanBucket.Put(lastWasRevokeKey, b2.Bytes()); err != nil {
1,997✔
2348
                        return err
×
2349
                }
×
2350

2351
                // Persist the remote unsigned local updates that are not included
2352
                // in our new commitment.
2353
                updateBytes := chanBucket.Get(remoteUnsignedLocalUpdatesKey)
1,997✔
2354
                if updateBytes == nil {
2,513✔
2355
                        return nil
516✔
2356
                }
516✔
2357

2358
                r := bytes.NewReader(updateBytes)
1,485✔
2359
                updates, err := deserializeLogUpdates(r)
1,485✔
2360
                if err != nil {
1,485✔
2361
                        return err
×
2362
                }
×
2363

2364
                // Get the bucket where settled htlcs are recorded if the user
2365
                // opted in to storing this information.
2366
                var finalHtlcsBucket kvdb.RwBucket
1,485✔
2367
                if c.Db.parent.storeFinalHtlcResolutions {
1,490✔
2368
                        bucket, err := fetchFinalHtlcsBucketRw(
5✔
2369
                                tx, c.ShortChannelID,
5✔
2370
                        )
5✔
2371
                        if err != nil {
5✔
2372
                                return err
×
2373
                        }
×
2374

2375
                        finalHtlcsBucket = bucket
5✔
2376
                }
2377

2378
                var unsignedUpdates []LogUpdate
1,485✔
2379
                for _, upd := range updates {
1,916✔
2380
                        // Gather updates that are not on our local commitment.
431✔
2381
                        if upd.LogIndex >= newCommitment.LocalLogIndex {
431✔
2382
                                unsignedUpdates = append(unsignedUpdates, upd)
×
2383

×
2384
                                continue
×
2385
                        }
2386

2387
                        // The update was locked in. If the update was a
2388
                        // resolution, then store it in the database.
2389
                        err := processFinalHtlc(
431✔
2390
                                finalHtlcsBucket, upd, finalHtlcs,
431✔
2391
                        )
431✔
2392
                        if err != nil {
431✔
2393
                                return err
×
2394
                        }
×
2395
                }
2396

2397
                var b3 bytes.Buffer
1,485✔
2398
                err = serializeLogUpdates(&b3, unsignedUpdates)
1,485✔
2399
                if err != nil {
1,485✔
2400
                        return fmt.Errorf("unable to serialize log updates: %w",
×
2401
                                err)
×
2402
                }
×
2403

2404
                err = chanBucket.Put(remoteUnsignedLocalUpdatesKey, b3.Bytes())
1,485✔
2405
                if err != nil {
1,485✔
2406
                        return fmt.Errorf("unable to restore chanbucket: %w",
×
2407
                                err)
×
2408
                }
×
2409

2410
                return nil
1,485✔
2411
        }, func() {
1,998✔
2412
                finalHtlcs = make(map[uint64]bool)
1,998✔
2413
        })
1,998✔
2414
        if err != nil {
1,999✔
2415
                return nil, err
1✔
2416
        }
1✔
2417

2418
        c.LocalCommitment = *newCommitment
1,997✔
2419

1,997✔
2420
        return finalHtlcs, nil
1,997✔
2421
}
2422

2423
// processFinalHtlc stores a final htlc outcome in the database if signaled via
2424
// the supplied log update. An in-memory htlcs map is updated too.
2425
func processFinalHtlc(finalHtlcsBucket walletdb.ReadWriteBucket, upd LogUpdate,
2426
        finalHtlcs map[uint64]bool) error {
431✔
2427

431✔
2428
        var (
431✔
2429
                settled bool
431✔
2430
                id      uint64
431✔
2431
        )
431✔
2432

431✔
2433
        switch msg := upd.UpdateMsg.(type) {
431✔
2434
        case *lnwire.UpdateFulfillHTLC:
289✔
2435
                settled = true
289✔
2436
                id = msg.ID
289✔
2437

2438
        case *lnwire.UpdateFailHTLC:
135✔
2439
                settled = false
135✔
2440
                id = msg.ID
135✔
2441

2442
        case *lnwire.UpdateFailMalformedHTLC:
7✔
2443
                settled = false
7✔
2444
                id = msg.ID
7✔
2445

2446
        default:
8✔
2447
                return nil
8✔
2448
        }
2449

2450
        // Store the final resolution in the database if a bucket is provided.
2451
        if finalHtlcsBucket != nil {
428✔
2452
                err := putFinalHtlc(
5✔
2453
                        finalHtlcsBucket, id,
5✔
2454
                        FinalHtlcInfo{
5✔
2455
                                Settled:  settled,
5✔
2456
                                Offchain: true,
5✔
2457
                        },
5✔
2458
                )
5✔
2459
                if err != nil {
5✔
2460
                        return err
×
2461
                }
×
2462
        }
2463

2464
        finalHtlcs[id] = settled
423✔
2465

423✔
2466
        return nil
423✔
2467
}
2468

2469
// ActiveHtlcs returns a slice of HTLC's which are currently active on *both*
2470
// commitment transactions.
2471
func (c *OpenChannel) ActiveHtlcs() []HTLC {
1,624✔
2472
        c.RLock()
1,624✔
2473
        defer c.RUnlock()
1,624✔
2474

1,624✔
2475
        // We'll only return HTLC's that are locked into *both* commitment
1,624✔
2476
        // transactions. So we'll iterate through their set of HTLC's to note
1,624✔
2477
        // which ones are present on their commitment.
1,624✔
2478
        remoteHtlcs := make(map[[32]byte]struct{})
1,624✔
2479
        for _, htlc := range c.RemoteCommitment.Htlcs {
8,350✔
2480
                log.Tracef("RemoteCommitment has htlc: id=%v, update=%v "+
6,726✔
2481
                        "incoming=%v", htlc.HtlcIndex, htlc.LogIndex,
6,726✔
2482
                        htlc.Incoming)
6,726✔
2483

6,726✔
2484
                onionHash := sha256.Sum256(htlc.OnionBlob[:])
6,726✔
2485
                remoteHtlcs[onionHash] = struct{}{}
6,726✔
2486
        }
6,726✔
2487

2488
        // Now that we know which HTLC's they have, we'll only mark the HTLC's
2489
        // as active if *we* know them as well.
2490
        activeHtlcs := make([]HTLC, 0, len(remoteHtlcs))
1,624✔
2491
        for _, htlc := range c.LocalCommitment.Htlcs {
8,335✔
2492
                log.Tracef("LocalCommitment has htlc: id=%v, update=%v "+
6,711✔
2493
                        "incoming=%v", htlc.HtlcIndex, htlc.LogIndex,
6,711✔
2494
                        htlc.Incoming)
6,711✔
2495

6,711✔
2496
                onionHash := sha256.Sum256(htlc.OnionBlob[:])
6,711✔
2497
                if _, ok := remoteHtlcs[onionHash]; !ok {
6,995✔
2498
                        log.Tracef("Skipped htlc due to onion mismatched: "+
284✔
2499
                                "id=%v, update=%v incoming=%v",
284✔
2500
                                htlc.HtlcIndex, htlc.LogIndex, htlc.Incoming)
284✔
2501

284✔
2502
                        continue
284✔
2503
                }
2504

2505
                activeHtlcs = append(activeHtlcs, htlc)
6,431✔
2506
        }
2507

2508
        return activeHtlcs
1,624✔
2509
}
2510

2511
// HTLC is the on-disk representation of a hash time-locked contract. HTLCs are
2512
// contained within ChannelDeltas which encode the current state of the
2513
// commitment between state updates.
2514
//
2515
// TODO(roasbeef): save space by using smaller ints at tail end?
2516
type HTLC struct {
2517
        // TODO(yy): can embed an HTLCEntry here.
2518

2519
        // Signature is the signature for the second level covenant transaction
2520
        // for this HTLC. The second level transaction is a timeout tx in the
2521
        // case that this is an outgoing HTLC, and a success tx in the case
2522
        // that this is an incoming HTLC.
2523
        //
2524
        // TODO(roasbeef): make [64]byte instead?
2525
        Signature []byte
2526

2527
        // RHash is the payment hash of the HTLC.
2528
        RHash [32]byte
2529

2530
        // Amt is the amount of milli-satoshis this HTLC escrows.
2531
        Amt lnwire.MilliSatoshi
2532

2533
        // RefundTimeout is the absolute timeout on the HTLC that the sender
2534
        // must wait before reclaiming the funds in limbo.
2535
        RefundTimeout uint32
2536

2537
        // OutputIndex is the output index for this particular HTLC output
2538
        // within the commitment transaction.
2539
        OutputIndex int32
2540

2541
        // Incoming denotes whether we're the receiver or the sender of this
2542
        // HTLC.
2543
        Incoming bool
2544

2545
        // OnionBlob is an opaque blob which is used to complete multi-hop
2546
        // routing.
2547
        OnionBlob [lnwire.OnionPacketSize]byte
2548

2549
        // HtlcIndex is the HTLC counter index of this active, outstanding
2550
        // HTLC. This differs from the LogIndex, as the HtlcIndex is only
2551
        // incremented for each offered HTLC, while they LogIndex is
2552
        // incremented for each update (includes settle+fail).
2553
        HtlcIndex uint64
2554

2555
        // LogIndex is the cumulative log index of this HTLC. This differs
2556
        // from the HtlcIndex as this will be incremented for each new log
2557
        // update added.
2558
        LogIndex uint64
2559

2560
        // ExtraData contains any additional information that was transmitted
2561
        // with the HTLC via TLVs. This data *must* already be encoded as a
2562
        // TLV stream, and may be empty. The length of this data is naturally
2563
        // limited by the space available to TLVs in update_add_htlc:
2564
        // = 65535 bytes (bolt 8 maximum message size):
2565
        // - 2 bytes (bolt 1 message_type)
2566
        // - 32 bytes (channel_id)
2567
        // - 8 bytes (id)
2568
        // - 8 bytes (amount_msat)
2569
        // - 32 bytes (payment_hash)
2570
        // - 4 bytes (cltv_expiry)
2571
        // - 1366 bytes (onion_routing_packet)
2572
        // = 64083 bytes maximum possible TLV stream
2573
        //
2574
        // Note that this extra data is stored inline with the OnionBlob for
2575
        // legacy reasons, see serialization/deserialization functions for
2576
        // detail.
2577
        ExtraData lnwire.ExtraOpaqueData
2578

2579
        // BlindingPoint is an optional blinding point included with the HTLC.
2580
        //
2581
        // Note: this field is not a part of on-disk representation of the
2582
        // HTLC. It is stored in the ExtraData field, which is used to store
2583
        // a TLV stream of additional information associated with the HTLC.
2584
        BlindingPoint lnwire.BlindingPointRecord
2585

2586
        // CustomRecords is a set of custom TLV records that are associated with
2587
        // this HTLC. These records are used to store additional information
2588
        // about the HTLC that is not part of the standard HTLC fields. This
2589
        // field is encoded within the ExtraData field.
2590
        CustomRecords lnwire.CustomRecords
2591
}
2592

2593
// serializeExtraData encodes a TLV stream of extra data to be stored with a
2594
// HTLC. It uses the update_add_htlc TLV types, because this is where extra
2595
// data is passed with a HTLC. At present blinding points are the only extra
2596
// data that we will store, and the function is a no-op if a nil blinding
2597
// point is provided.
2598
//
2599
// This function MUST be called to persist all HTLC values when they are
2600
// serialized.
2601
func (h *HTLC) serializeExtraData() error {
29,421✔
2602
        var records []tlv.RecordProducer
29,421✔
2603
        h.BlindingPoint.WhenSome(func(b tlv.RecordT[lnwire.BlindingPointTlvType,
29,421✔
2604
                *btcec.PublicKey]) {
29,429✔
2605

8✔
2606
                records = append(records, &b)
8✔
2607
        })
8✔
2608

2609
        records, err := h.CustomRecords.ExtendRecordProducers(records)
29,421✔
2610
        if err != nil {
29,421✔
2611
                return err
×
2612
        }
×
2613

2614
        return h.ExtraData.PackRecords(records...)
29,421✔
2615
}
2616

2617
// deserializeExtraData extracts TLVs from the extra data persisted for the
2618
// htlc and populates values in the struct accordingly.
2619
//
2620
// This function MUST be called to populate the struct properly when HTLCs
2621
// are deserialized.
2622
func (h *HTLC) deserializeExtraData() error {
66,817✔
2623
        if len(h.ExtraData) == 0 {
131,946✔
2624
                return nil
65,129✔
2625
        }
65,129✔
2626

2627
        blindingPoint := h.BlindingPoint.Zero()
1,692✔
2628
        tlvMap, err := h.ExtraData.ExtractRecords(&blindingPoint)
1,692✔
2629
        if err != nil {
1,692✔
2630
                return err
×
2631
        }
×
2632

2633
        if val, ok := tlvMap[h.BlindingPoint.TlvType()]; ok && val == nil {
1,700✔
2634
                h.BlindingPoint = tlv.SomeRecordT(blindingPoint)
8✔
2635

8✔
2636
                // Remove the entry from the TLV map. Anything left in the map
8✔
2637
                // will be included in the custom records field.
8✔
2638
                delete(tlvMap, h.BlindingPoint.TlvType())
8✔
2639
        }
8✔
2640

2641
        // Set the custom records field to the remaining TLV records.
2642
        customRecords, err := lnwire.NewCustomRecords(tlvMap)
1,692✔
2643
        if err != nil {
1,692✔
2644
                return err
×
2645
        }
×
2646
        h.CustomRecords = customRecords
1,692✔
2647

1,692✔
2648
        return nil
1,692✔
2649
}
2650

2651
// SerializeHtlcs writes out the passed set of HTLC's into the passed writer
2652
// using the current default on-disk serialization format.
2653
//
2654
// This inline serialization has been extended to allow storage of extra data
2655
// associated with a HTLC in the following way:
2656
//   - The known-length onion blob (1366 bytes) is serialized as var bytes in
2657
//     WriteElements (ie, the length 1366 was written, followed by the 1366
2658
//     onion bytes).
2659
//   - To include extra data, we append any extra data present to this one
2660
//     variable length of data. Since we know that the onion is strictly 1366
2661
//     bytes, any length after that should be considered to be extra data.
2662
//
2663
// NOTE: This API is NOT stable, the on-disk format will likely change in the
2664
// future.
2665
func SerializeHtlcs(b io.Writer, htlcs ...HTLC) error {
8,446✔
2666
        numHtlcs := uint16(len(htlcs))
8,446✔
2667
        if err := WriteElement(b, numHtlcs); err != nil {
8,446✔
2668
                return err
×
2669
        }
×
2670

2671
        for _, htlc := range htlcs {
37,867✔
2672
                // Populate TLV stream for any additional fields contained
29,421✔
2673
                // in the TLV.
29,421✔
2674
                if err := htlc.serializeExtraData(); err != nil {
29,421✔
2675
                        return err
×
2676
                }
×
2677

2678
                // The onion blob and hltc data are stored as a single var
2679
                // bytes blob.
2680
                onionAndExtraData := make(
29,421✔
2681
                        []byte, lnwire.OnionPacketSize+len(htlc.ExtraData),
29,421✔
2682
                )
29,421✔
2683
                copy(onionAndExtraData, htlc.OnionBlob[:])
29,421✔
2684
                copy(onionAndExtraData[lnwire.OnionPacketSize:], htlc.ExtraData)
29,421✔
2685

29,421✔
2686
                if err := WriteElements(b,
29,421✔
2687
                        htlc.Signature, htlc.RHash, htlc.Amt, htlc.RefundTimeout,
29,421✔
2688
                        htlc.OutputIndex, htlc.Incoming, onionAndExtraData,
29,421✔
2689
                        htlc.HtlcIndex, htlc.LogIndex,
29,421✔
2690
                ); err != nil {
29,421✔
2691
                        return err
×
2692
                }
×
2693
        }
2694

2695
        return nil
8,446✔
2696
}
2697

2698
// DeserializeHtlcs attempts to read out a slice of HTLC's from the passed
2699
// io.Reader. The bytes within the passed reader MUST have been previously
2700
// written to using the SerializeHtlcs function.
2701
//
2702
// This inline deserialization has been extended to allow storage of extra data
2703
// associated with a HTLC in the following way:
2704
//   - The known-length onion blob (1366 bytes) and any additional data present
2705
//     are read out as a single blob of variable byte data.
2706
//   - They are stored like this to take advantage of the variable space
2707
//     available for extension without migration (see SerializeHtlcs).
2708
//   - The first 1366 bytes are interpreted as the onion blob, and any remaining
2709
//     bytes as extra HTLC data.
2710
//   - This extra HTLC data is expected to be serialized as a TLV stream, and
2711
//     its parsing is left to higher layers.
2712
//
2713
// NOTE: This API is NOT stable, the on-disk format will likely change in the
2714
// future.
2715
func DeserializeHtlcs(r io.Reader) ([]HTLC, error) {
16,317✔
2716
        var numHtlcs uint16
16,317✔
2717
        if err := ReadElement(r, &numHtlcs); err != nil {
16,317✔
2718
                return nil, err
×
2719
        }
×
2720

2721
        var htlcs []HTLC
16,317✔
2722
        if numHtlcs == 0 {
23,183✔
2723
                return htlcs, nil
6,866✔
2724
        }
6,866✔
2725

2726
        htlcs = make([]HTLC, numHtlcs)
9,455✔
2727
        for i := uint16(0); i < numHtlcs; i++ {
76,273✔
2728
                var onionAndExtraData []byte
66,818✔
2729
                if err := ReadElements(r,
66,818✔
2730
                        &htlcs[i].Signature, &htlcs[i].RHash, &htlcs[i].Amt,
66,818✔
2731
                        &htlcs[i].RefundTimeout, &htlcs[i].OutputIndex,
66,818✔
2732
                        &htlcs[i].Incoming, &onionAndExtraData,
66,818✔
2733
                        &htlcs[i].HtlcIndex, &htlcs[i].LogIndex,
66,818✔
2734
                ); err != nil {
66,818✔
2735
                        return htlcs, err
×
2736
                }
×
2737

2738
                // Sanity check that we have at least the onion blob size we
2739
                // expect.
2740
                if len(onionAndExtraData) < lnwire.OnionPacketSize {
66,819✔
2741
                        return nil, ErrOnionBlobLength
1✔
2742
                }
1✔
2743

2744
                // First OnionPacketSize bytes are our fixed length onion
2745
                // packet.
2746
                copy(
66,817✔
2747
                        htlcs[i].OnionBlob[:],
66,817✔
2748
                        onionAndExtraData[0:lnwire.OnionPacketSize],
66,817✔
2749
                )
66,817✔
2750

66,817✔
2751
                // Any additional bytes belong to extra data. ExtraDataLen
66,817✔
2752
                // will be >= 0, because we know that we always have a fixed
66,817✔
2753
                // length onion packet.
66,817✔
2754
                extraDataLen := len(onionAndExtraData) - lnwire.OnionPacketSize
66,817✔
2755
                if extraDataLen > 0 {
68,509✔
2756
                        htlcs[i].ExtraData = make([]byte, extraDataLen)
1,692✔
2757

1,692✔
2758
                        copy(
1,692✔
2759
                                htlcs[i].ExtraData,
1,692✔
2760
                                onionAndExtraData[lnwire.OnionPacketSize:],
1,692✔
2761
                        )
1,692✔
2762
                }
1,692✔
2763

2764
                // Finally, deserialize any TLVs contained in that extra data
2765
                // if they are present.
2766
                if err := htlcs[i].deserializeExtraData(); err != nil {
66,817✔
2767
                        return nil, err
×
2768
                }
×
2769
        }
2770

2771
        return htlcs, nil
9,454✔
2772
}
2773

2774
// Copy returns a full copy of the target HTLC.
2775
func (h *HTLC) Copy() HTLC {
271✔
2776
        clone := HTLC{
271✔
2777
                Incoming:      h.Incoming,
271✔
2778
                Amt:           h.Amt,
271✔
2779
                RefundTimeout: h.RefundTimeout,
271✔
2780
                OutputIndex:   h.OutputIndex,
271✔
2781
        }
271✔
2782
        copy(clone.Signature[:], h.Signature)
271✔
2783
        copy(clone.RHash[:], h.RHash[:])
271✔
2784
        copy(clone.ExtraData, h.ExtraData)
271✔
2785
        clone.BlindingPoint = h.BlindingPoint
271✔
2786
        clone.CustomRecords = h.CustomRecords.Copy()
271✔
2787

271✔
2788
        return clone
271✔
2789
}
271✔
2790

2791
// LogUpdate represents a pending update to the remote commitment chain. The
2792
// log update may be an add, fail, or settle entry. We maintain this data in
2793
// order to be able to properly retransmit our proposed state if necessary.
2794
type LogUpdate struct {
2795
        // LogIndex is the log index of this proposed commitment update entry.
2796
        LogIndex uint64
2797

2798
        // UpdateMsg is the update message that was included within our
2799
        // local update log. The LogIndex value denotes the log index of this
2800
        // update which will be used when restoring our local update log if
2801
        // we're left with a dangling update on restart.
2802
        UpdateMsg lnwire.Message
2803
}
2804

2805
// serializeLogUpdate writes a log update to the provided io.Writer.
2806
func serializeLogUpdate(w io.Writer, l *LogUpdate) error {
1,249✔
2807
        return WriteElements(w, l.LogIndex, l.UpdateMsg)
1,249✔
2808
}
1,249✔
2809

2810
// deserializeLogUpdate reads a log update from the provided io.Reader.
2811
func deserializeLogUpdate(r io.Reader) (*LogUpdate, error) {
87✔
2812
        l := &LogUpdate{}
87✔
2813
        if err := ReadElements(r, &l.LogIndex, &l.UpdateMsg); err != nil {
87✔
2814
                return nil, err
×
2815
        }
×
2816

2817
        return l, nil
87✔
2818
}
2819

2820
// CommitDiff represents the delta needed to apply the state transition between
2821
// two subsequent commitment states. Given state N and state N+1, one is able
2822
// to apply the set of messages contained within the CommitDiff to N to arrive
2823
// at state N+1. Each time a new commitment is extended, we'll write a new
2824
// commitment (along with the full commitment state) to disk so we can
2825
// re-transmit the state in the case of a connection loss or message drop.
2826
type CommitDiff struct {
2827
        // ChannelCommitment is the full commitment state that one would arrive
2828
        // at by applying the set of messages contained in the UpdateDiff to
2829
        // the prior accepted commitment.
2830
        Commitment ChannelCommitment
2831

2832
        // LogUpdates is the set of messages sent prior to the commitment state
2833
        // transition in question. Upon reconnection, if we detect that they
2834
        // don't have the commitment, then we re-send this along with the
2835
        // proper signature.
2836
        LogUpdates []LogUpdate
2837

2838
        // CommitSig is the exact CommitSig message that should be sent after
2839
        // the set of LogUpdates above has been retransmitted. The signatures
2840
        // within this message should properly cover the new commitment state
2841
        // and also the HTLC's within the new commitment state.
2842
        CommitSig *lnwire.CommitSig
2843

2844
        // OpenedCircuitKeys is a set of unique identifiers for any downstream
2845
        // Add packets included in this commitment txn. After a restart, this
2846
        // set of htlcs is acked from the link's incoming mailbox to ensure
2847
        // there isn't an attempt to re-add them to this commitment txn.
2848
        OpenedCircuitKeys []models.CircuitKey
2849

2850
        // ClosedCircuitKeys records the unique identifiers for any settle/fail
2851
        // packets that were resolved by this commitment txn. After a restart,
2852
        // this is used to ensure those circuits are removed from the circuit
2853
        // map, and the downstream packets in the link's mailbox are removed.
2854
        ClosedCircuitKeys []models.CircuitKey
2855

2856
        // AddAcks specifies the locations (commit height, pkg index) of any
2857
        // Adds that were failed/settled in this commit diff. This will ack
2858
        // entries in *this* channel's forwarding packages.
2859
        //
2860
        // NOTE: This value is not serialized, it is used to atomically mark the
2861
        // resolution of adds, such that they will not be reprocessed after a
2862
        // restart.
2863
        AddAcks []AddRef
2864

2865
        // SettleFailAcks specifies the locations (chan id, commit height, pkg
2866
        // index) of any Settles or Fails that were locked into this commit
2867
        // diff, and originate from *another* channel, i.e. the outgoing link.
2868
        //
2869
        // NOTE: This value is not serialized, it is used to atomically acks
2870
        // settles and fails from the forwarding packages of other channels,
2871
        // such that they will not be reforwarded internally after a restart.
2872
        SettleFailAcks []SettleFailRef
2873
}
2874

2875
// serializeLogUpdates serializes provided list of updates to a stream.
2876
func serializeLogUpdates(w io.Writer, logUpdates []LogUpdate) error {
9,001✔
2877
        numUpdates := uint16(len(logUpdates))
9,001✔
2878
        if err := binary.Write(w, byteOrder, numUpdates); err != nil {
9,001✔
2879
                return err
×
2880
        }
×
2881

2882
        for _, diff := range logUpdates {
12,738✔
2883
                err := WriteElements(w, diff.LogIndex, diff.UpdateMsg)
3,737✔
2884
                if err != nil {
3,737✔
2885
                        return err
×
2886
                }
×
2887
        }
2888

2889
        return nil
9,001✔
2890
}
2891

2892
// deserializeLogUpdates deserializes a list of updates from a stream.
2893
func deserializeLogUpdates(r io.Reader) ([]LogUpdate, error) {
5,373✔
2894
        var numUpdates uint16
5,373✔
2895
        if err := binary.Read(r, byteOrder, &numUpdates); err != nil {
5,373✔
2896
                return nil, err
×
2897
        }
×
2898

2899
        logUpdates := make([]LogUpdate, numUpdates)
5,373✔
2900
        for i := 0; i < int(numUpdates); i++ {
8,753✔
2901
                err := ReadElements(r,
3,380✔
2902
                        &logUpdates[i].LogIndex, &logUpdates[i].UpdateMsg,
3,380✔
2903
                )
3,380✔
2904
                if err != nil {
3,380✔
2905
                        return nil, err
×
2906
                }
×
2907
        }
2908
        return logUpdates, nil
5,373✔
2909
}
2910

2911
func serializeCommitDiff(w io.Writer, diff *CommitDiff) error { // nolint: dupl
2,043✔
2912
        if err := serializeChanCommit(w, &diff.Commitment); err != nil {
2,043✔
2913
                return err
×
2914
        }
×
2915

2916
        if err := WriteElements(w, diff.CommitSig); err != nil {
2,043✔
2917
                return err
×
2918
        }
×
2919

2920
        if err := serializeLogUpdates(w, diff.LogUpdates); err != nil {
2,043✔
2921
                return err
×
2922
        }
×
2923

2924
        numOpenRefs := uint16(len(diff.OpenedCircuitKeys))
2,043✔
2925
        if err := binary.Write(w, byteOrder, numOpenRefs); err != nil {
2,043✔
2926
                return err
×
2927
        }
×
2928

2929
        for _, openRef := range diff.OpenedCircuitKeys {
2,508✔
2930
                err := WriteElements(w, openRef.ChanID, openRef.HtlcID)
465✔
2931
                if err != nil {
465✔
2932
                        return err
×
2933
                }
×
2934
        }
2935

2936
        numClosedRefs := uint16(len(diff.ClosedCircuitKeys))
2,043✔
2937
        if err := binary.Write(w, byteOrder, numClosedRefs); err != nil {
2,043✔
2938
                return err
×
2939
        }
×
2940

2941
        for _, closedRef := range diff.ClosedCircuitKeys {
2,086✔
2942
                err := WriteElements(w, closedRef.ChanID, closedRef.HtlcID)
43✔
2943
                if err != nil {
43✔
2944
                        return err
×
2945
                }
×
2946
        }
2947

2948
        // We'll also encode the commit aux data stream here. We do this here
2949
        // rather than above (at the call to serializeChanCommit), to ensure
2950
        // backwards compat for reads to existing non-custom channels.
2951
        auxData := diff.Commitment.extractTlvData()
2,043✔
2952
        if err := auxData.encode(w); err != nil {
2,043✔
2953
                return fmt.Errorf("unable to write aux data: %w", err)
×
2954
        }
×
2955

2956
        return nil
2,043✔
2957
}
2958

2959
func deserializeCommitDiff(r io.Reader) (*CommitDiff, error) {
2,036✔
2960
        var (
2,036✔
2961
                d   CommitDiff
2,036✔
2962
                err error
2,036✔
2963
        )
2,036✔
2964

2,036✔
2965
        d.Commitment, err = deserializeChanCommit(r)
2,036✔
2966
        if err != nil {
2,036✔
2967
                return nil, err
×
2968
        }
×
2969

2970
        var msg lnwire.Message
2,036✔
2971
        if err := ReadElements(r, &msg); err != nil {
2,036✔
2972
                return nil, err
×
2973
        }
×
2974
        commitSig, ok := msg.(*lnwire.CommitSig)
2,036✔
2975
        if !ok {
2,036✔
2976
                return nil, fmt.Errorf("expected lnwire.CommitSig, instead "+
×
2977
                        "read: %T", msg)
×
2978
        }
×
2979
        d.CommitSig = commitSig
2,036✔
2980

2,036✔
2981
        d.LogUpdates, err = deserializeLogUpdates(r)
2,036✔
2982
        if err != nil {
2,036✔
2983
                return nil, err
×
2984
        }
×
2985

2986
        var numOpenRefs uint16
2,036✔
2987
        if err := binary.Read(r, byteOrder, &numOpenRefs); err != nil {
2,036✔
2988
                return nil, err
×
2989
        }
×
2990

2991
        d.OpenedCircuitKeys = make([]models.CircuitKey, numOpenRefs)
2,036✔
2992
        for i := 0; i < int(numOpenRefs); i++ {
2,528✔
2993
                err := ReadElements(r,
492✔
2994
                        &d.OpenedCircuitKeys[i].ChanID,
492✔
2995
                        &d.OpenedCircuitKeys[i].HtlcID)
492✔
2996
                if err != nil {
492✔
2997
                        return nil, err
×
2998
                }
×
2999
        }
3000

3001
        var numClosedRefs uint16
2,036✔
3002
        if err := binary.Read(r, byteOrder, &numClosedRefs); err != nil {
2,036✔
3003
                return nil, err
×
3004
        }
×
3005

3006
        d.ClosedCircuitKeys = make([]models.CircuitKey, numClosedRefs)
2,036✔
3007
        for i := 0; i < int(numClosedRefs); i++ {
2,076✔
3008
                err := ReadElements(r,
40✔
3009
                        &d.ClosedCircuitKeys[i].ChanID,
40✔
3010
                        &d.ClosedCircuitKeys[i].HtlcID)
40✔
3011
                if err != nil {
40✔
3012
                        return nil, err
×
3013
                }
×
3014
        }
3015

3016
        // As a final step, we'll read out any aux commit data that we have at
3017
        // the end of this byte stream. We do this here to ensure backward
3018
        // compatibility, as otherwise we risk erroneously reading into the
3019
        // wrong field.
3020
        var auxData commitTlvData
2,036✔
3021
        if err := auxData.decode(r); err != nil {
2,036✔
3022
                return nil, fmt.Errorf("unable to decode aux data: %w", err)
×
3023
        }
×
3024

3025
        d.Commitment.amendTlvData(auxData)
2,036✔
3026

2,036✔
3027
        return &d, nil
2,036✔
3028
}
3029

3030
// AppendRemoteCommitChain appends a new CommitDiff to the end of the
3031
// commitment chain for the remote party. This method is to be used once we
3032
// have prepared a new commitment state for the remote party, but before we
3033
// transmit it to the remote party. The contents of the argument should be
3034
// sufficient to retransmit the updates and signature needed to reconstruct the
3035
// state in full, in the case that we need to retransmit.
3036
func (c *OpenChannel) AppendRemoteCommitChain(diff *CommitDiff) error {
2,045✔
3037
        c.Lock()
2,045✔
3038
        defer c.Unlock()
2,045✔
3039

2,045✔
3040
        // If this is a restored channel, then we want to avoid mutating the
2,045✔
3041
        // state at all, as it's impossible to do so in a protocol compliant
2,045✔
3042
        // manner.
2,045✔
3043
        if c.hasChanStatus(ChanStatusRestored) {
2,046✔
3044
                return ErrNoRestoredChannelMutation
1✔
3045
        }
1✔
3046

3047
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
4,088✔
3048
                // First, we'll grab the writable bucket where this channel's
2,044✔
3049
                // data resides.
2,044✔
3050
                chanBucket, err := fetchChanBucketRw(
2,044✔
3051
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
2,044✔
3052
                )
2,044✔
3053
                if err != nil {
2,044✔
3054
                        return err
×
3055
                }
×
3056

3057
                // If the channel is marked as borked, then for safety reasons,
3058
                // we shouldn't attempt any further updates.
3059
                isBorked, err := c.isBorked(chanBucket)
2,044✔
3060
                if err != nil {
2,044✔
3061
                        return err
×
3062
                }
×
3063
                if isBorked {
2,046✔
3064
                        return ErrChanBorked
2✔
3065
                }
2✔
3066

3067
                // Any outgoing settles and fails necessarily have a
3068
                // corresponding adds in this channel's forwarding packages.
3069
                // Mark all of these as being fully processed in our forwarding
3070
                // package, which prevents us from reprocessing them after
3071
                // startup.
3072
                err = c.Packager.AckAddHtlcs(tx, diff.AddAcks...)
2,043✔
3073
                if err != nil {
2,043✔
3074
                        return err
×
3075
                }
×
3076

3077
                // Additionally, we ack from any fails or settles that are
3078
                // persisted in another channel's forwarding package. This
3079
                // prevents the same fails and settles from being retransmitted
3080
                // after restarts. The actual fail or settle we need to
3081
                // propagate to the remote party is now in the commit diff.
3082
                err = c.Packager.AckSettleFails(tx, diff.SettleFailAcks...)
2,043✔
3083
                if err != nil {
2,043✔
3084
                        return err
×
3085
                }
×
3086

3087
                // We are sending a commitment signature so lastWasRevokeKey should
3088
                // store false.
3089
                var b bytes.Buffer
2,043✔
3090
                if err := WriteElements(&b, false); err != nil {
2,043✔
3091
                        return err
×
3092
                }
×
3093
                if err := chanBucket.Put(lastWasRevokeKey, b.Bytes()); err != nil {
2,043✔
3094
                        return err
×
3095
                }
×
3096

3097
                // TODO(roasbeef): use seqno to derive key for later LCP
3098

3099
                // With the bucket retrieved, we'll now serialize the commit
3100
                // diff itself, and write it to disk.
3101
                var b2 bytes.Buffer
2,043✔
3102
                if err := serializeCommitDiff(&b2, diff); err != nil {
2,043✔
3103
                        return err
×
3104
                }
×
3105
                return chanBucket.Put(commitDiffKey, b2.Bytes())
2,043✔
3106
        }, func() {})
2,044✔
3107
}
3108

3109
// RemoteCommitChainTip returns the "tip" of the current remote commitment
3110
// chain. This value will be non-nil iff, we've created a new commitment for
3111
// the remote party that they haven't yet ACK'd. In this case, their commitment
3112
// chain will have a length of two: their current unrevoked commitment, and
3113
// this new pending commitment. Once they revoked their prior state, we'll swap
3114
// these pointers, causing the tip and the tail to point to the same entry.
3115
func (c *OpenChannel) RemoteCommitChainTip() (*CommitDiff, error) {
1,243✔
3116
        var cd *CommitDiff
1,243✔
3117
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
2,486✔
3118
                chanBucket, err := fetchChanBucket(
1,243✔
3119
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
1,243✔
3120
                )
1,243✔
3121
                switch err {
1,243✔
3122
                case nil:
873✔
3123
                case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
373✔
3124
                        return ErrNoPendingCommit
373✔
3125
                default:
×
3126
                        return err
×
3127
                }
3128

3129
                tipBytes := chanBucket.Get(commitDiffKey)
873✔
3130
                if tipBytes == nil {
1,665✔
3131
                        return ErrNoPendingCommit
792✔
3132
                }
792✔
3133

3134
                tipReader := bytes.NewReader(tipBytes)
85✔
3135
                dcd, err := deserializeCommitDiff(tipReader)
85✔
3136
                if err != nil {
85✔
3137
                        return err
×
3138
                }
×
3139

3140
                cd = dcd
85✔
3141
                return nil
85✔
3142
        }, func() {
1,243✔
3143
                cd = nil
1,243✔
3144
        })
1,243✔
3145
        if err != nil {
2,405✔
3146
                return nil, err
1,162✔
3147
        }
1,162✔
3148

3149
        return cd, err
85✔
3150
}
3151

3152
// UnsignedAckedUpdates retrieves the persisted unsigned acked remote log
3153
// updates that still need to be signed for.
3154
func (c *OpenChannel) UnsignedAckedUpdates() ([]LogUpdate, error) {
809✔
3155
        var updates []LogUpdate
809✔
3156
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
1,618✔
3157
                chanBucket, err := fetchChanBucket(
809✔
3158
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
809✔
3159
                )
809✔
3160
                switch err {
809✔
3161
                case nil:
439✔
3162
                case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
372✔
3163
                        return nil
372✔
3164
                default:
×
3165
                        return err
×
3166
                }
3167

3168
                updateBytes := chanBucket.Get(unsignedAckedUpdatesKey)
439✔
3169
                if updateBytes == nil {
805✔
3170
                        return nil
366✔
3171
                }
366✔
3172

3173
                r := bytes.NewReader(updateBytes)
77✔
3174
                updates, err = deserializeLogUpdates(r)
77✔
3175
                return err
77✔
3176
        }, func() {
809✔
3177
                updates = nil
809✔
3178
        })
809✔
3179
        if err != nil {
809✔
3180
                return nil, err
×
3181
        }
×
3182

3183
        return updates, nil
809✔
3184
}
3185

3186
// RemoteUnsignedLocalUpdates retrieves the persisted, unsigned local log
3187
// updates that the remote still needs to sign for.
3188
func (c *OpenChannel) RemoteUnsignedLocalUpdates() ([]LogUpdate, error) {
808✔
3189
        var updates []LogUpdate
808✔
3190
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
1,616✔
3191
                chanBucket, err := fetchChanBucket(
808✔
3192
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
808✔
3193
                )
808✔
3194
                switch err {
808✔
3195
                case nil:
438✔
3196
                        break
438✔
3197
                case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
372✔
3198
                        return nil
372✔
3199
                default:
×
3200
                        return err
×
3201
                }
3202

3203
                updateBytes := chanBucket.Get(remoteUnsignedLocalUpdatesKey)
438✔
3204
                if updateBytes == nil {
835✔
3205
                        return nil
397✔
3206
                }
397✔
3207

3208
                r := bytes.NewReader(updateBytes)
45✔
3209
                updates, err = deserializeLogUpdates(r)
45✔
3210
                return err
45✔
3211
        }, func() {
808✔
3212
                updates = nil
808✔
3213
        })
808✔
3214
        if err != nil {
808✔
3215
                return nil, err
×
3216
        }
×
3217

3218
        return updates, nil
808✔
3219
}
3220

3221
// InsertNextRevocation inserts the _next_ commitment point (revocation) into
3222
// the database, and also modifies the internal RemoteNextRevocation attribute
3223
// to point to the passed key. This method is to be using during final channel
3224
// set up, _after_ the channel has been fully confirmed.
3225
//
3226
// NOTE: If this method isn't called, then the target channel won't be able to
3227
// propose new states for the commitment state of the remote party.
3228
func (c *OpenChannel) InsertNextRevocation(revKey *btcec.PublicKey) error {
626✔
3229
        c.Lock()
626✔
3230
        defer c.Unlock()
626✔
3231

626✔
3232
        c.RemoteNextRevocation = revKey
626✔
3233

626✔
3234
        err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
1,252✔
3235
                chanBucket, err := fetchChanBucketRw(
626✔
3236
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
626✔
3237
                )
626✔
3238
                if err != nil {
626✔
3239
                        return err
×
3240
                }
×
3241

3242
                return putChanRevocationState(chanBucket, c)
626✔
3243
        }, func() {})
626✔
3244
        if err != nil {
626✔
3245
                return err
×
3246
        }
×
3247

3248
        return nil
626✔
3249
}
3250

3251
// AdvanceCommitChainTail records the new state transition within an on-disk
3252
// append-only log which records all state transitions by the remote peer. In
3253
// the case of an uncooperative broadcast of a prior state by the remote peer,
3254
// this log can be consulted in order to reconstruct the state needed to
3255
// rectify the situation. This method will add the current commitment for the
3256
// remote party to the revocation log, and promote the current pending
3257
// commitment to the current remote commitment. The updates parameter is the
3258
// set of local updates that the peer still needs to send us a signature for.
3259
// We store this set of updates in case we go down.
3260
func (c *OpenChannel) AdvanceCommitChainTail(fwdPkg *FwdPkg,
3261
        updates []LogUpdate, ourOutputIndex, theirOutputIndex uint32) error {
1,957✔
3262

1,957✔
3263
        c.Lock()
1,957✔
3264
        defer c.Unlock()
1,957✔
3265

1,957✔
3266
        // If this is a restored channel, then we want to avoid mutating the
1,957✔
3267
        // state at all, as it's impossible to do so in a protocol compliant
1,957✔
3268
        // manner.
1,957✔
3269
        if c.hasChanStatus(ChanStatusRestored) {
1,958✔
3270
                return ErrNoRestoredChannelMutation
1✔
3271
        }
1✔
3272

3273
        var newRemoteCommit *ChannelCommitment
1,956✔
3274

1,956✔
3275
        err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
3,912✔
3276
                chanBucket, err := fetchChanBucketRw(
1,956✔
3277
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
1,956✔
3278
                )
1,956✔
3279
                if err != nil {
1,956✔
3280
                        return err
×
3281
                }
×
3282

3283
                // If the channel is marked as borked, then for safety reasons,
3284
                // we shouldn't attempt any further updates.
3285
                isBorked, err := c.isBorked(chanBucket)
1,956✔
3286
                if err != nil {
1,956✔
3287
                        return err
×
3288
                }
×
3289
                if isBorked {
1,957✔
3290
                        return ErrChanBorked
1✔
3291
                }
1✔
3292

3293
                // Persist the latest preimage state to disk as the remote peer
3294
                // has just added to our local preimage store, and given us a
3295
                // new pending revocation key.
3296
                if err := putChanRevocationState(chanBucket, c); err != nil {
1,955✔
3297
                        return err
×
3298
                }
×
3299

3300
                // With the current preimage producer/store state updated,
3301
                // append a new log entry recording this the delta of this
3302
                // state transition.
3303
                //
3304
                // TODO(roasbeef): could make the deltas relative, would save
3305
                // space, but then tradeoff for more disk-seeks to recover the
3306
                // full state.
3307
                logKey := revocationLogBucket
1,955✔
3308
                logBucket, err := chanBucket.CreateBucketIfNotExists(logKey)
1,955✔
3309
                if err != nil {
1,955✔
3310
                        return err
×
3311
                }
×
3312

3313
                // Before we append this revoked state to the revocation log,
3314
                // we'll swap out what's currently the tail of the commit tip,
3315
                // with the current locked-in commitment for the remote party.
3316
                tipBytes := chanBucket.Get(commitDiffKey)
1,955✔
3317
                tipReader := bytes.NewReader(tipBytes)
1,955✔
3318
                newCommit, err := deserializeCommitDiff(tipReader)
1,955✔
3319
                if err != nil {
1,955✔
3320
                        return err
×
3321
                }
×
3322
                err = putChanCommitment(
1,955✔
3323
                        chanBucket, &newCommit.Commitment, false,
1,955✔
3324
                )
1,955✔
3325
                if err != nil {
1,955✔
3326
                        return err
×
3327
                }
×
3328
                if err := chanBucket.Delete(commitDiffKey); err != nil {
1,955✔
3329
                        return err
×
3330
                }
×
3331

3332
                // With the commitment pointer swapped, we can now add the
3333
                // revoked (prior) state to the revocation log.
3334
                err = putRevocationLog(
1,955✔
3335
                        logBucket, &c.RemoteCommitment, ourOutputIndex,
1,955✔
3336
                        theirOutputIndex, c.Db.parent.noRevLogAmtData,
1,955✔
3337
                )
1,955✔
3338
                if err != nil {
1,955✔
3339
                        return err
×
3340
                }
×
3341

3342
                // Lastly, we write the forwarding package to disk so that we
3343
                // can properly recover from failures and reforward HTLCs that
3344
                // have not received a corresponding settle/fail.
3345
                if err := c.Packager.AddFwdPkg(tx, fwdPkg); err != nil {
1,955✔
3346
                        return err
×
3347
                }
×
3348

3349
                // Persist the unsigned acked updates that are not included
3350
                // in their new commitment.
3351
                updateBytes := chanBucket.Get(unsignedAckedUpdatesKey)
1,955✔
3352
                if updateBytes == nil {
2,168✔
3353
                        // This shouldn't normally happen as we always store
213✔
3354
                        // the number of updates, but could still be
213✔
3355
                        // encountered by nodes that are upgrading.
213✔
3356
                        newRemoteCommit = &newCommit.Commitment
213✔
3357
                        return nil
213✔
3358
                }
213✔
3359

3360
                r := bytes.NewReader(updateBytes)
1,746✔
3361
                unsignedUpdates, err := deserializeLogUpdates(r)
1,746✔
3362
                if err != nil {
1,746✔
3363
                        return err
×
3364
                }
×
3365

3366
                var validUpdates []LogUpdate
1,746✔
3367
                for _, upd := range unsignedUpdates {
3,149✔
3368
                        lIdx := upd.LogIndex
1,403✔
3369

1,403✔
3370
                        // Filter for updates that are not on the remote
1,403✔
3371
                        // commitment.
1,403✔
3372
                        if lIdx >= newCommit.Commitment.RemoteLogIndex {
1,551✔
3373
                                validUpdates = append(validUpdates, upd)
148✔
3374
                        }
148✔
3375
                }
3376

3377
                var b bytes.Buffer
1,746✔
3378
                err = serializeLogUpdates(&b, validUpdates)
1,746✔
3379
                if err != nil {
1,746✔
3380
                        return fmt.Errorf("unable to serialize log updates: %w",
×
3381
                                err)
×
3382
                }
×
3383

3384
                err = chanBucket.Put(unsignedAckedUpdatesKey, b.Bytes())
1,746✔
3385
                if err != nil {
1,746✔
3386
                        return fmt.Errorf("unable to store under "+
×
3387
                                "unsignedAckedUpdatesKey: %w", err)
×
3388
                }
×
3389

3390
                // Persist the local updates the peer hasn't yet signed so they
3391
                // can be restored after restart.
3392
                var b2 bytes.Buffer
1,746✔
3393
                err = serializeLogUpdates(&b2, updates)
1,746✔
3394
                if err != nil {
1,746✔
3395
                        return err
×
3396
                }
×
3397

3398
                err = chanBucket.Put(remoteUnsignedLocalUpdatesKey, b2.Bytes())
1,746✔
3399
                if err != nil {
1,746✔
3400
                        return fmt.Errorf("unable to restore remote unsigned "+
×
3401
                                "local updates: %v", err)
×
3402
                }
×
3403

3404
                newRemoteCommit = &newCommit.Commitment
1,746✔
3405

1,746✔
3406
                return nil
1,746✔
3407
        }, func() {
1,956✔
3408
                newRemoteCommit = nil
1,956✔
3409
        })
1,956✔
3410
        if err != nil {
1,957✔
3411
                return err
1✔
3412
        }
1✔
3413

3414
        // With the db transaction complete, we'll swap over the in-memory
3415
        // pointer of the new remote commitment, which was previously the tip
3416
        // of the commit chain.
3417
        c.RemoteCommitment = *newRemoteCommit
1,955✔
3418

1,955✔
3419
        return nil
1,955✔
3420
}
3421

3422
// FinalHtlcInfo contains information about the final outcome of an htlc.
3423
type FinalHtlcInfo struct {
3424
        // Settled is true is the htlc was settled. If false, the htlc was
3425
        // failed.
3426
        Settled bool
3427

3428
        // Offchain indicates whether the htlc was resolved off-chain or
3429
        // on-chain.
3430
        Offchain bool
3431
}
3432

3433
// putFinalHtlc writes the final htlc outcome to the database. Additionally it
3434
// records whether the htlc was resolved off-chain or on-chain.
3435
func putFinalHtlc(finalHtlcsBucket kvdb.RwBucket, id uint64,
3436
        info FinalHtlcInfo) error {
7✔
3437

7✔
3438
        var key [8]byte
7✔
3439
        byteOrder.PutUint64(key[:], id)
7✔
3440

7✔
3441
        var finalHtlcByte FinalHtlcByte
7✔
3442
        if info.Settled {
14✔
3443
                finalHtlcByte |= FinalHtlcSettledBit
7✔
3444
        }
7✔
3445
        if info.Offchain {
13✔
3446
                finalHtlcByte |= FinalHtlcOffchainBit
6✔
3447
        }
6✔
3448

3449
        return finalHtlcsBucket.Put(key[:], []byte{byte(finalHtlcByte)})
7✔
3450
}
3451

3452
// NextLocalHtlcIndex returns the next unallocated local htlc index. To ensure
3453
// this always returns the next index that has been not been allocated, this
3454
// will first try to examine any pending commitments, before falling back to the
3455
// last locked-in remote commitment.
3456
func (c *OpenChannel) NextLocalHtlcIndex() (uint64, error) {
383✔
3457
        // First, load the most recent commit diff that we initiated for the
383✔
3458
        // remote party. If no pending commit is found, this is not treated as
383✔
3459
        // a critical error, since we can always fall back.
383✔
3460
        pendingRemoteCommit, err := c.RemoteCommitChainTip()
383✔
3461
        if err != nil && err != ErrNoPendingCommit {
383✔
3462
                return 0, err
×
3463
        }
×
3464

3465
        // If a pending commit was found, its local htlc index will be at least
3466
        // as large as the one on our local commitment.
3467
        if pendingRemoteCommit != nil {
399✔
3468
                return pendingRemoteCommit.Commitment.LocalHtlcIndex, nil
16✔
3469
        }
16✔
3470

3471
        // Otherwise, fallback to using the local htlc index of their commitment.
3472
        return c.RemoteCommitment.LocalHtlcIndex, nil
367✔
3473
}
3474

3475
// LoadFwdPkgs scans the forwarding log for any packages that haven't been
3476
// processed, and returns their deserialized log updates in map indexed by the
3477
// remote commitment height at which the updates were locked in.
3478
func (c *OpenChannel) LoadFwdPkgs() ([]*FwdPkg, error) {
451✔
3479
        c.RLock()
451✔
3480
        defer c.RUnlock()
451✔
3481

451✔
3482
        var fwdPkgs []*FwdPkg
451✔
3483
        if err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
885✔
3484
                var err error
434✔
3485
                fwdPkgs, err = c.Packager.LoadFwdPkgs(tx)
434✔
3486
                return err
434✔
3487
        }, func() {
885✔
3488
                fwdPkgs = nil
451✔
3489
        }); err != nil {
468✔
3490
                return nil, err
17✔
3491
        }
17✔
3492

3493
        return fwdPkgs, nil
434✔
3494
}
3495

3496
// AckAddHtlcs updates the AckAddFilter containing any of the provided AddRefs
3497
// indicating that a response to this Add has been committed to the remote party.
3498
// Doing so will prevent these Add HTLCs from being reforwarded internally.
3499
func (c *OpenChannel) AckAddHtlcs(addRefs ...AddRef) error {
1✔
3500
        c.Lock()
1✔
3501
        defer c.Unlock()
1✔
3502

1✔
3503
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
2✔
3504
                return c.Packager.AckAddHtlcs(tx, addRefs...)
1✔
3505
        }, func() {})
2✔
3506
}
3507

3508
// AckSettleFails updates the SettleFailFilter containing any of the provided
3509
// SettleFailRefs, indicating that the response has been delivered to the
3510
// incoming link, corresponding to a particular AddRef. Doing so will prevent
3511
// the responses from being retransmitted internally.
3512
func (c *OpenChannel) AckSettleFails(settleFailRefs ...SettleFailRef) error {
×
3513
        c.Lock()
×
3514
        defer c.Unlock()
×
3515

×
3516
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
×
3517
                return c.Packager.AckSettleFails(tx, settleFailRefs...)
×
3518
        }, func() {})
×
3519
}
3520

3521
// SetFwdFilter atomically sets the forwarding filter for the forwarding package
3522
// identified by `height`.
3523
func (c *OpenChannel) SetFwdFilter(height uint64, fwdFilter *PkgFilter) error {
1,173✔
3524
        c.Lock()
1,173✔
3525
        defer c.Unlock()
1,173✔
3526

1,173✔
3527
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
2,346✔
3528
                return c.Packager.SetFwdFilter(tx, height, fwdFilter)
1,173✔
3529
        }, func() {})
2,346✔
3530
}
3531

3532
// RemoveFwdPkgs atomically removes forwarding packages specified by the remote
3533
// commitment heights. If one of the intermediate RemovePkg calls fails, then the
3534
// later packages won't be removed.
3535
//
3536
// NOTE: This method should only be called on packages marked FwdStateCompleted.
3537
func (c *OpenChannel) RemoveFwdPkgs(heights ...uint64) error {
5✔
3538
        c.Lock()
5✔
3539
        defer c.Unlock()
5✔
3540

5✔
3541
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
10✔
3542
                for _, height := range heights {
10✔
3543
                        err := c.Packager.RemovePkg(tx, height)
5✔
3544
                        if err != nil {
5✔
UNCOV
3545
                                return err
×
UNCOV
3546
                        }
×
3547
                }
3548

3549
                return nil
5✔
3550
        }, func() {})
5✔
3551
}
3552

3553
// revocationLogTailCommitHeight returns the commit height at the end of the
3554
// revocation log. This entry represents the last previous state for the remote
3555
// node's commitment chain. The ChannelDelta returned by this method will
3556
// always lag one state behind the most current (unrevoked) state of the remote
3557
// node's commitment chain.
3558
// NOTE: used in unit test only.
3559
func (c *OpenChannel) revocationLogTailCommitHeight() (uint64, error) {
2✔
3560
        c.RLock()
2✔
3561
        defer c.RUnlock()
2✔
3562

2✔
3563
        var height uint64
2✔
3564

2✔
3565
        // If we haven't created any state updates yet, then we'll exit early as
2✔
3566
        // there's nothing to be found on disk in the revocation bucket.
2✔
3567
        if c.RemoteCommitment.CommitHeight == 0 {
2✔
3568
                return height, nil
×
3569
        }
×
3570

3571
        if err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
4✔
3572
                chanBucket, err := fetchChanBucket(
2✔
3573
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
2✔
3574
                )
2✔
3575
                if err != nil {
2✔
3576
                        return err
×
3577
                }
×
3578

3579
                logBucket, err := fetchLogBucket(chanBucket)
2✔
3580
                if err != nil {
2✔
3581
                        return err
×
3582
                }
×
3583

3584
                // Once we have the bucket that stores the revocation log from
3585
                // this channel, we'll jump to the _last_ key in bucket. Since
3586
                // the key is the commit height, we'll decode the bytes and
3587
                // return it.
3588
                cursor := logBucket.ReadCursor()
2✔
3589
                rawHeight, _ := cursor.Last()
2✔
3590
                height = byteOrder.Uint64(rawHeight)
2✔
3591

2✔
3592
                return nil
2✔
3593
        }, func() {}); err != nil {
2✔
3594
                return height, err
×
3595
        }
×
3596

3597
        return height, nil
2✔
3598
}
3599

3600
// CommitmentHeight returns the current commitment height. The commitment
3601
// height represents the number of updates to the commitment state to date.
3602
// This value is always monotonically increasing. This method is provided in
3603
// order to allow multiple instances of a particular open channel to obtain a
3604
// consistent view of the number of channel updates to date.
3605
func (c *OpenChannel) CommitmentHeight() (uint64, error) {
1✔
3606
        c.RLock()
1✔
3607
        defer c.RUnlock()
1✔
3608

1✔
3609
        var height uint64
1✔
3610
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
2✔
3611
                // Get the bucket dedicated to storing the metadata for open
1✔
3612
                // channels.
1✔
3613
                chanBucket, err := fetchChanBucket(
1✔
3614
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
1✔
3615
                )
1✔
3616
                if err != nil {
1✔
3617
                        return err
×
3618
                }
×
3619

3620
                commit, err := fetchChanCommitment(chanBucket, true)
1✔
3621
                if err != nil {
1✔
3622
                        return err
×
3623
                }
×
3624

3625
                height = commit.CommitHeight
1✔
3626
                return nil
1✔
3627
        }, func() {
1✔
3628
                height = 0
1✔
3629
        })
1✔
3630
        if err != nil {
1✔
3631
                return 0, err
×
3632
        }
×
3633

3634
        return height, nil
1✔
3635
}
3636

3637
// FindPreviousState scans through the append-only log in an attempt to recover
3638
// the previous channel state indicated by the update number. This method is
3639
// intended to be used for obtaining the relevant data needed to claim all
3640
// funds rightfully spendable in the case of an on-chain broadcast of the
3641
// commitment transaction.
3642
func (c *OpenChannel) FindPreviousState(
3643
        updateNum uint64) (*RevocationLog, *ChannelCommitment, error) {
35✔
3644

35✔
3645
        c.RLock()
35✔
3646
        defer c.RUnlock()
35✔
3647

35✔
3648
        commit := &ChannelCommitment{}
35✔
3649
        rl := &RevocationLog{}
35✔
3650

35✔
3651
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
70✔
3652
                chanBucket, err := fetchChanBucket(
35✔
3653
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
35✔
3654
                )
35✔
3655
                if err != nil {
36✔
3656
                        return err
1✔
3657
                }
1✔
3658

3659
                // Find the revocation log from both the new and the old
3660
                // bucket.
3661
                r, c, err := fetchRevocationLogCompatible(chanBucket, updateNum)
34✔
3662
                if err != nil {
57✔
3663
                        return err
23✔
3664
                }
23✔
3665

3666
                rl = r
15✔
3667
                commit = c
15✔
3668
                return nil
15✔
3669
        }, func() {})
35✔
3670
        if err != nil {
59✔
3671
                return nil, nil, err
24✔
3672
        }
24✔
3673

3674
        // Either the `rl` or the `commit` is nil here. We return them as-is
3675
        // and leave it to the caller to decide its following action.
3676
        return rl, commit, nil
15✔
3677
}
3678

3679
// ClosureType is an enum like structure that details exactly _how_ a channel
3680
// was closed. Three closure types are currently possible: none, cooperative,
3681
// local force close, remote force close, and (remote) breach.
3682
type ClosureType uint8
3683

3684
const (
3685
        // CooperativeClose indicates that a channel has been closed
3686
        // cooperatively.  This means that both channel peers were online and
3687
        // signed a new transaction paying out the settled balance of the
3688
        // contract.
3689
        CooperativeClose ClosureType = 0
3690

3691
        // LocalForceClose indicates that we have unilaterally broadcast our
3692
        // current commitment state on-chain.
3693
        LocalForceClose ClosureType = 1
3694

3695
        // RemoteForceClose indicates that the remote peer has unilaterally
3696
        // broadcast their current commitment state on-chain.
3697
        RemoteForceClose ClosureType = 4
3698

3699
        // BreachClose indicates that the remote peer attempted to broadcast a
3700
        // prior _revoked_ channel state.
3701
        BreachClose ClosureType = 2
3702

3703
        // FundingCanceled indicates that the channel never was fully opened
3704
        // before it was marked as closed in the database. This can happen if
3705
        // we or the remote fail at some point during the opening workflow, or
3706
        // we timeout waiting for the funding transaction to be confirmed.
3707
        FundingCanceled ClosureType = 3
3708

3709
        // Abandoned indicates that the channel state was removed without
3710
        // any further actions. This is intended to clean up unusable
3711
        // channels during development.
3712
        Abandoned ClosureType = 5
3713
)
3714

3715
// ChannelCloseSummary contains the final state of a channel at the point it
3716
// was closed. Once a channel is closed, all the information pertaining to that
3717
// channel within the openChannelBucket is deleted, and a compact summary is
3718
// put in place instead.
3719
type ChannelCloseSummary struct {
3720
        // ChanPoint is the outpoint for this channel's funding transaction,
3721
        // and is used as a unique identifier for the channel.
3722
        ChanPoint wire.OutPoint
3723

3724
        // ShortChanID encodes the exact location in the chain in which the
3725
        // channel was initially confirmed. This includes: the block height,
3726
        // transaction index, and the output within the target transaction.
3727
        ShortChanID lnwire.ShortChannelID
3728

3729
        // ChainHash is the hash of the genesis block that this channel resides
3730
        // within.
3731
        ChainHash chainhash.Hash
3732

3733
        // ClosingTXID is the txid of the transaction which ultimately closed
3734
        // this channel.
3735
        ClosingTXID chainhash.Hash
3736

3737
        // RemotePub is the public key of the remote peer that we formerly had
3738
        // a channel with.
3739
        RemotePub *btcec.PublicKey
3740

3741
        // Capacity was the total capacity of the channel.
3742
        Capacity btcutil.Amount
3743

3744
        // CloseHeight is the height at which the funding transaction was
3745
        // spent.
3746
        CloseHeight uint32
3747

3748
        // SettledBalance is our total balance settled balance at the time of
3749
        // channel closure. This _does not_ include the sum of any outputs that
3750
        // have been time-locked as a result of the unilateral channel closure.
3751
        SettledBalance btcutil.Amount
3752

3753
        // TimeLockedBalance is the sum of all the time-locked outputs at the
3754
        // time of channel closure. If we triggered the force closure of this
3755
        // channel, then this value will be non-zero if our settled output is
3756
        // above the dust limit. If we were on the receiving side of a channel
3757
        // force closure, then this value will be non-zero if we had any
3758
        // outstanding outgoing HTLC's at the time of channel closure.
3759
        TimeLockedBalance btcutil.Amount
3760

3761
        // CloseType details exactly _how_ the channel was closed. Five closure
3762
        // types are possible: cooperative, local force, remote force, breach
3763
        // and funding canceled.
3764
        CloseType ClosureType
3765

3766
        // IsPending indicates whether this channel is in the 'pending close'
3767
        // state, which means the channel closing transaction has been
3768
        // confirmed, but not yet been fully resolved. In the case of a channel
3769
        // that has been cooperatively closed, it will go straight into the
3770
        // fully resolved state as soon as the closing transaction has been
3771
        // confirmed. However, for channels that have been force closed, they'll
3772
        // stay marked as "pending" until _all_ the pending funds have been
3773
        // swept.
3774
        IsPending bool
3775

3776
        // RemoteCurrentRevocation is the current revocation for their
3777
        // commitment transaction. However, since this is the derived public key,
3778
        // we don't yet have the private key so we aren't yet able to verify
3779
        // that it's actually in the hash chain.
3780
        RemoteCurrentRevocation *btcec.PublicKey
3781

3782
        // RemoteNextRevocation is the revocation key to be used for the *next*
3783
        // commitment transaction we create for the local node. Within the
3784
        // specification, this value is referred to as the
3785
        // per-commitment-point.
3786
        RemoteNextRevocation *btcec.PublicKey
3787

3788
        // LocalChanConfig is the channel configuration for the local node.
3789
        LocalChanConfig ChannelConfig
3790

3791
        // LastChanSyncMsg is the ChannelReestablish message for this channel
3792
        // for the state at the point where it was closed.
3793
        LastChanSyncMsg *lnwire.ChannelReestablish
3794
}
3795

3796
// CloseChannel closes a previously active Lightning channel. Closing a channel
3797
// entails deleting all saved state within the database concerning this
3798
// channel. This method also takes a struct that summarizes the state of the
3799
// channel at closing, this compact representation will be the only component
3800
// of a channel left over after a full closing. It takes an optional set of
3801
// channel statuses which will be written to the historical channel bucket.
3802
// These statuses are used to record close initiators.
3803
func (c *OpenChannel) CloseChannel(summary *ChannelCloseSummary,
3804
        statuses ...ChannelStatus) error {
118✔
3805

118✔
3806
        c.Lock()
118✔
3807
        defer c.Unlock()
118✔
3808

118✔
3809
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
236✔
3810
                openChanBucket := tx.ReadWriteBucket(openChannelBucket)
118✔
3811
                if openChanBucket == nil {
118✔
3812
                        return ErrNoChanDBExists
×
3813
                }
×
3814

3815
                nodePub := c.IdentityPub.SerializeCompressed()
118✔
3816
                nodeChanBucket := openChanBucket.NestedReadWriteBucket(nodePub)
118✔
3817
                if nodeChanBucket == nil {
118✔
3818
                        return ErrNoActiveChannels
×
3819
                }
×
3820

3821
                chainBucket := nodeChanBucket.NestedReadWriteBucket(c.ChainHash[:])
118✔
3822
                if chainBucket == nil {
118✔
3823
                        return ErrNoActiveChannels
×
3824
                }
×
3825

3826
                var chanPointBuf bytes.Buffer
118✔
3827
                err := graphdb.WriteOutpoint(&chanPointBuf, &c.FundingOutpoint)
118✔
3828
                if err != nil {
118✔
3829
                        return err
×
3830
                }
×
3831
                chanKey := chanPointBuf.Bytes()
118✔
3832
                chanBucket := chainBucket.NestedReadWriteBucket(
118✔
3833
                        chanKey,
118✔
3834
                )
118✔
3835
                if chanBucket == nil {
118✔
3836
                        return ErrNoActiveChannels
×
3837
                }
×
3838

3839
                // Before we delete the channel state, we'll read out the full
3840
                // details, as we'll also store portions of this information
3841
                // for record keeping.
3842
                chanState, err := fetchOpenChannel(
118✔
3843
                        chanBucket, &c.FundingOutpoint,
118✔
3844
                )
118✔
3845
                if err != nil {
118✔
3846
                        return err
×
3847
                }
×
3848

3849
                // Delete all the forwarding packages stored for this particular
3850
                // channel.
3851
                if err = chanState.Packager.Wipe(tx); err != nil {
118✔
3852
                        return err
×
3853
                }
×
3854

3855
                // Now that the index to this channel has been deleted, purge
3856
                // the remaining channel metadata from the database.
3857
                err = deleteOpenChannel(chanBucket)
118✔
3858
                if err != nil {
118✔
3859
                        return err
×
3860
                }
×
3861

3862
                // We'll also remove the channel from the frozen channel bucket
3863
                // if we need to.
3864
                if c.ChanType.IsFrozen() || c.ChanType.HasLeaseExpiration() {
229✔
3865
                        err := deleteThawHeight(chanBucket)
111✔
3866
                        if err != nil {
111✔
3867
                                return err
×
3868
                        }
×
3869
                }
3870

3871
                // With the base channel data deleted, attempt to delete the
3872
                // information stored within the revocation log.
3873
                if err := deleteLogBucket(chanBucket); err != nil {
118✔
3874
                        return err
×
3875
                }
×
3876

3877
                err = chainBucket.DeleteNestedBucket(chanPointBuf.Bytes())
118✔
3878
                if err != nil {
118✔
3879
                        return err
×
3880
                }
×
3881

3882
                // Fetch the outpoint bucket to see if the outpoint exists or
3883
                // not.
3884
                opBucket := tx.ReadWriteBucket(outpointBucket)
118✔
3885
                if opBucket == nil {
118✔
3886
                        return ErrNoChanDBExists
×
3887
                }
×
3888

3889
                // Add the closed outpoint to our outpoint index. This should
3890
                // replace an open outpoint in the index.
3891
                if opBucket.Get(chanPointBuf.Bytes()) == nil {
118✔
3892
                        return ErrMissingIndexEntry
×
3893
                }
×
3894

3895
                status := uint8(outpointClosed)
118✔
3896

118✔
3897
                // Write the IndexStatus of this outpoint as the first entry in a tlv
118✔
3898
                // stream.
118✔
3899
                statusRecord := tlv.MakePrimitiveRecord(indexStatusType, &status)
118✔
3900
                opStream, err := tlv.NewStream(statusRecord)
118✔
3901
                if err != nil {
118✔
3902
                        return err
×
3903
                }
×
3904

3905
                var b bytes.Buffer
118✔
3906
                if err := opStream.Encode(&b); err != nil {
118✔
3907
                        return err
×
3908
                }
×
3909

3910
                // Finally add the closed outpoint and tlv stream to the index.
3911
                if err := opBucket.Put(chanPointBuf.Bytes(), b.Bytes()); err != nil {
118✔
3912
                        return err
×
3913
                }
×
3914

3915
                // Add channel state to the historical channel bucket.
3916
                historicalBucket, err := tx.CreateTopLevelBucket(
118✔
3917
                        historicalChannelBucket,
118✔
3918
                )
118✔
3919
                if err != nil {
118✔
3920
                        return err
×
3921
                }
×
3922

3923
                historicalChanBucket, err :=
118✔
3924
                        historicalBucket.CreateBucketIfNotExists(chanKey)
118✔
3925
                if err != nil {
118✔
3926
                        return err
×
3927
                }
×
3928

3929
                // Apply any additional statuses to the channel state.
3930
                for _, status := range statuses {
127✔
3931
                        chanState.chanStatus |= status
9✔
3932
                }
9✔
3933

3934
                err = putOpenChannel(historicalChanBucket, chanState)
118✔
3935
                if err != nil {
118✔
3936
                        return err
×
3937
                }
×
3938

3939
                // Finally, create a summary of this channel in the closed
3940
                // channel bucket for this node.
3941
                return putChannelCloseSummary(
118✔
3942
                        tx, chanPointBuf.Bytes(), summary, chanState,
118✔
3943
                )
118✔
3944
        }, func() {})
118✔
3945
}
3946

3947
// ChannelSnapshot is a frozen snapshot of the current channel state. A
3948
// snapshot is detached from the original channel that generated it, providing
3949
// read-only access to the current or prior state of an active channel.
3950
//
3951
// TODO(roasbeef): remove all together? pretty much just commitment
3952
type ChannelSnapshot struct {
3953
        // RemoteIdentity is the identity public key of the remote node that we
3954
        // are maintaining the open channel with.
3955
        RemoteIdentity btcec.PublicKey
3956

3957
        // ChanPoint is the outpoint that created the channel. This output is
3958
        // found within the funding transaction and uniquely identified the
3959
        // channel on the resident chain.
3960
        ChannelPoint wire.OutPoint
3961

3962
        // ChainHash is the genesis hash of the chain that the channel resides
3963
        // within.
3964
        ChainHash chainhash.Hash
3965

3966
        // Capacity is the total capacity of the channel.
3967
        Capacity btcutil.Amount
3968

3969
        // TotalMSatSent is the total number of milli-satoshis we've sent
3970
        // within this channel.
3971
        TotalMSatSent lnwire.MilliSatoshi
3972

3973
        // TotalMSatReceived is the total number of milli-satoshis we've
3974
        // received within this channel.
3975
        TotalMSatReceived lnwire.MilliSatoshi
3976

3977
        // ChannelCommitment is the current up-to-date commitment for the
3978
        // target channel.
3979
        ChannelCommitment
3980
}
3981

3982
// Snapshot returns a read-only snapshot of the current channel state. This
3983
// snapshot includes information concerning the current settled balance within
3984
// the channel, metadata detailing total flows, and any outstanding HTLCs.
3985
func (c *OpenChannel) Snapshot() *ChannelSnapshot {
76✔
3986
        c.RLock()
76✔
3987
        defer c.RUnlock()
76✔
3988

76✔
3989
        localCommit := c.LocalCommitment
76✔
3990
        snapshot := &ChannelSnapshot{
76✔
3991
                RemoteIdentity:    *c.IdentityPub,
76✔
3992
                ChannelPoint:      c.FundingOutpoint,
76✔
3993
                Capacity:          c.Capacity,
76✔
3994
                TotalMSatSent:     c.TotalMSatSent,
76✔
3995
                TotalMSatReceived: c.TotalMSatReceived,
76✔
3996
                ChainHash:         c.ChainHash,
76✔
3997
                ChannelCommitment: ChannelCommitment{
76✔
3998
                        LocalBalance:  localCommit.LocalBalance,
76✔
3999
                        RemoteBalance: localCommit.RemoteBalance,
76✔
4000
                        CommitHeight:  localCommit.CommitHeight,
76✔
4001
                        CommitFee:     localCommit.CommitFee,
76✔
4002
                },
76✔
4003
        }
76✔
4004

76✔
4005
        localCommit.CustomBlob.WhenSome(func(blob tlv.Blob) {
76✔
4006
                blobCopy := make([]byte, len(blob))
×
4007
                copy(blobCopy, blob)
×
4008

×
4009
                snapshot.ChannelCommitment.CustomBlob = fn.Some(blobCopy)
×
4010
        })
×
4011

4012
        // Copy over the current set of HTLCs to ensure the caller can't mutate
4013
        // our internal state.
4014
        snapshot.Htlcs = make([]HTLC, len(localCommit.Htlcs))
76✔
4015
        for i, h := range localCommit.Htlcs {
347✔
4016
                snapshot.Htlcs[i] = h.Copy()
271✔
4017
        }
271✔
4018

4019
        return snapshot
76✔
4020
}
4021

4022
// LatestCommitments returns the two latest commitments for both the local and
4023
// remote party. These commitments are read from disk to ensure that only the
4024
// latest fully committed state is returned. The first commitment returned is
4025
// the local commitment, and the second returned is the remote commitment.
4026
func (c *OpenChannel) LatestCommitments() (*ChannelCommitment, *ChannelCommitment, error) {
19✔
4027
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
38✔
4028
                chanBucket, err := fetchChanBucket(
19✔
4029
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
19✔
4030
                )
19✔
4031
                if err != nil {
19✔
4032
                        return err
×
4033
                }
×
4034

4035
                return fetchChanCommitments(chanBucket, c)
19✔
4036
        }, func() {})
19✔
4037
        if err != nil {
19✔
4038
                return nil, nil, err
×
4039
        }
×
4040

4041
        return &c.LocalCommitment, &c.RemoteCommitment, nil
19✔
4042
}
4043

4044
// RemoteRevocationStore returns the most up to date commitment version of the
4045
// revocation storage tree for the remote party. This method can be used when
4046
// acting on a possible contract breach to ensure, that the caller has the most
4047
// up to date information required to deliver justice.
4048
func (c *OpenChannel) RemoteRevocationStore() (shachain.Store, error) {
19✔
4049
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
38✔
4050
                chanBucket, err := fetchChanBucket(
19✔
4051
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
19✔
4052
                )
19✔
4053
                if err != nil {
19✔
4054
                        return err
×
4055
                }
×
4056

4057
                return fetchChanRevocationState(chanBucket, c)
19✔
4058
        }, func() {})
19✔
4059
        if err != nil {
19✔
4060
                return nil, err
×
4061
        }
×
4062

4063
        return c.RevocationStore, nil
19✔
4064
}
4065

4066
// AbsoluteThawHeight determines a frozen channel's absolute thaw height. If the
4067
// channel is not frozen, then 0 is returned.
4068
func (c *OpenChannel) AbsoluteThawHeight() (uint32, error) {
4✔
4069
        // Only frozen channels have a thaw height.
4✔
4070
        if !c.ChanType.IsFrozen() && !c.ChanType.HasLeaseExpiration() {
8✔
4071
                return 0, nil
4✔
4072
        }
4✔
4073

4074
        // If the channel has the frozen bit set and it's thaw height is below
4075
        // the absolute threshold, then it's interpreted as a relative height to
4076
        // the chain's current height.
4077
        if c.ChanType.IsFrozen() && c.ThawHeight < AbsoluteThawHeightThreshold {
8✔
4078
                // We'll only known of the channel's short ID once it's
4✔
4079
                // confirmed.
4✔
4080
                if c.IsPending {
4✔
4081
                        return 0, errors.New("cannot use relative thaw " +
×
4082
                                "height for unconfirmed channel")
×
4083
                }
×
4084

4085
                // For non-zero-conf channels, this is the base height to use.
4086
                blockHeightBase := c.ShortChannelID.BlockHeight
4✔
4087

4✔
4088
                // If this is a zero-conf channel, the ShortChannelID will be
4✔
4089
                // an alias.
4✔
4090
                if c.IsZeroConf() {
4✔
4091
                        if !c.ZeroConfConfirmed() {
×
4092
                                return 0, errors.New("cannot use relative " +
×
4093
                                        "height for unconfirmed zero-conf " +
×
4094
                                        "channel")
×
4095
                        }
×
4096

4097
                        // Use the confirmed SCID's BlockHeight.
4098
                        blockHeightBase = c.confirmedScid.BlockHeight
×
4099
                }
4100

4101
                return blockHeightBase + c.ThawHeight, nil
4✔
4102
        }
4103

4104
        return c.ThawHeight, nil
4✔
4105
}
4106

4107
func putChannelCloseSummary(tx kvdb.RwTx, chanID []byte,
4108
        summary *ChannelCloseSummary, lastChanState *OpenChannel) error {
118✔
4109

118✔
4110
        closedChanBucket, err := tx.CreateTopLevelBucket(closedChannelBucket)
118✔
4111
        if err != nil {
118✔
4112
                return err
×
4113
        }
×
4114

4115
        summary.RemoteCurrentRevocation = lastChanState.RemoteCurrentRevocation
118✔
4116
        summary.RemoteNextRevocation = lastChanState.RemoteNextRevocation
118✔
4117
        summary.LocalChanConfig = lastChanState.LocalChanCfg
118✔
4118

118✔
4119
        var b bytes.Buffer
118✔
4120
        if err := serializeChannelCloseSummary(&b, summary); err != nil {
118✔
4121
                return err
×
4122
        }
×
4123

4124
        return closedChanBucket.Put(chanID, b.Bytes())
118✔
4125
}
4126

4127
func serializeChannelCloseSummary(w io.Writer, cs *ChannelCloseSummary) error {
125✔
4128
        err := WriteElements(w,
125✔
4129
                cs.ChanPoint, cs.ShortChanID, cs.ChainHash, cs.ClosingTXID,
125✔
4130
                cs.CloseHeight, cs.RemotePub, cs.Capacity, cs.SettledBalance,
125✔
4131
                cs.TimeLockedBalance, cs.CloseType, cs.IsPending,
125✔
4132
        )
125✔
4133
        if err != nil {
125✔
4134
                return err
×
4135
        }
×
4136

4137
        // If this is a close channel summary created before the addition of
4138
        // the new fields, then we can exit here.
4139
        if cs.RemoteCurrentRevocation == nil {
125✔
4140
                return WriteElements(w, false)
×
4141
        }
×
4142

4143
        // If fields are present, write boolean to indicate this, and continue.
4144
        if err := WriteElements(w, true); err != nil {
125✔
4145
                return err
×
4146
        }
×
4147

4148
        if err := WriteElements(w, cs.RemoteCurrentRevocation); err != nil {
125✔
4149
                return err
×
4150
        }
×
4151

4152
        if err := writeChanConfig(w, &cs.LocalChanConfig); err != nil {
125✔
4153
                return err
×
4154
        }
×
4155

4156
        // The RemoteNextRevocation field is optional, as it's possible for a
4157
        // channel to be closed before we learn of the next unrevoked
4158
        // revocation point for the remote party. Write a boolean indicating
4159
        // whether this field is present or not.
4160
        if err := WriteElements(w, cs.RemoteNextRevocation != nil); err != nil {
125✔
4161
                return err
×
4162
        }
×
4163

4164
        // Write the field, if present.
4165
        if cs.RemoteNextRevocation != nil {
248✔
4166
                if err = WriteElements(w, cs.RemoteNextRevocation); err != nil {
123✔
4167
                        return err
×
4168
                }
×
4169
        }
4170

4171
        // Write whether the channel sync message is present.
4172
        if err := WriteElements(w, cs.LastChanSyncMsg != nil); err != nil {
125✔
4173
                return err
×
4174
        }
×
4175

4176
        // Write the channel sync message, if present.
4177
        if cs.LastChanSyncMsg != nil {
129✔
4178
                if err := WriteElements(w, cs.LastChanSyncMsg); err != nil {
4✔
4179
                        return err
×
4180
                }
×
4181
        }
4182

4183
        return nil
125✔
4184
}
4185

4186
func deserializeCloseChannelSummary(r io.Reader) (*ChannelCloseSummary, error) {
134✔
4187
        c := &ChannelCloseSummary{}
134✔
4188

134✔
4189
        err := ReadElements(r,
134✔
4190
                &c.ChanPoint, &c.ShortChanID, &c.ChainHash, &c.ClosingTXID,
134✔
4191
                &c.CloseHeight, &c.RemotePub, &c.Capacity, &c.SettledBalance,
134✔
4192
                &c.TimeLockedBalance, &c.CloseType, &c.IsPending,
134✔
4193
        )
134✔
4194
        if err != nil {
134✔
4195
                return nil, err
×
4196
        }
×
4197

4198
        // We'll now check to see if the channel close summary was encoded with
4199
        // any of the additional optional fields.
4200
        var hasNewFields bool
134✔
4201
        err = ReadElements(r, &hasNewFields)
134✔
4202
        if err != nil {
134✔
4203
                return nil, err
×
4204
        }
×
4205

4206
        // If fields are not present, we can return.
4207
        if !hasNewFields {
142✔
4208
                return c, nil
8✔
4209
        }
8✔
4210

4211
        // Otherwise read the new fields.
4212
        if err := ReadElements(r, &c.RemoteCurrentRevocation); err != nil {
126✔
4213
                return nil, err
×
4214
        }
×
4215

4216
        if err := readChanConfig(r, &c.LocalChanConfig); err != nil {
126✔
4217
                return nil, err
×
4218
        }
×
4219

4220
        // Finally, we'll attempt to read the next unrevoked commitment point
4221
        // for the remote party. If we closed the channel before receiving a
4222
        // channel_ready message then this might not be present. A boolean
4223
        // indicating whether the field is present will come first.
4224
        var hasRemoteNextRevocation bool
126✔
4225
        err = ReadElements(r, &hasRemoteNextRevocation)
126✔
4226
        if err != nil {
126✔
4227
                return nil, err
×
4228
        }
×
4229

4230
        // If this field was written, read it.
4231
        if hasRemoteNextRevocation {
252✔
4232
                err = ReadElements(r, &c.RemoteNextRevocation)
126✔
4233
                if err != nil {
126✔
4234
                        return nil, err
×
4235
                }
×
4236
        }
4237

4238
        // Check if we have a channel sync message to read.
4239
        var hasChanSyncMsg bool
126✔
4240
        err = ReadElements(r, &hasChanSyncMsg)
126✔
4241
        if err == io.EOF {
126✔
4242
                return c, nil
×
4243
        } else if err != nil {
126✔
4244
                return nil, err
×
4245
        }
×
4246

4247
        // If a chan sync message is present, read it.
4248
        if hasChanSyncMsg {
130✔
4249
                // We must pass in reference to a lnwire.Message for the codec
4✔
4250
                // to support it.
4✔
4251
                var msg lnwire.Message
4✔
4252
                if err := ReadElements(r, &msg); err != nil {
4✔
4253
                        return nil, err
×
4254
                }
×
4255

4256
                chanSync, ok := msg.(*lnwire.ChannelReestablish)
4✔
4257
                if !ok {
4✔
4258
                        return nil, errors.New("unable cast db Message to " +
×
4259
                                "ChannelReestablish")
×
4260
                }
×
4261
                c.LastChanSyncMsg = chanSync
4✔
4262
        }
4263

4264
        return c, nil
126✔
4265
}
4266

4267
func writeChanConfig(b io.Writer, c *ChannelConfig) error {
6,551✔
4268
        return WriteElements(b,
6,551✔
4269
                c.DustLimit, c.MaxPendingAmount, c.ChanReserve, c.MinHTLC,
6,551✔
4270
                c.MaxAcceptedHtlcs, c.CsvDelay, c.MultiSigKey,
6,551✔
4271
                c.RevocationBasePoint, c.PaymentBasePoint, c.DelayBasePoint,
6,551✔
4272
                c.HtlcBasePoint,
6,551✔
4273
        )
6,551✔
4274
}
6,551✔
4275

4276
// fundingTxPresent returns true if expect the funding transcation to be found
4277
// on disk or already populated within the passed open channel struct.
4278
func fundingTxPresent(channel *OpenChannel) bool {
10,334✔
4279
        chanType := channel.ChanType
10,334✔
4280

10,334✔
4281
        return chanType.IsSingleFunder() && chanType.HasFundingTx() &&
10,334✔
4282
                channel.IsInitiator &&
10,334✔
4283
                !channel.hasChanStatus(ChanStatusRestored)
10,334✔
4284
}
10,334✔
4285

4286
func putChanInfo(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
3,217✔
4287
        var w bytes.Buffer
3,217✔
4288
        if err := WriteElements(&w,
3,217✔
4289
                channel.ChanType, channel.ChainHash, channel.FundingOutpoint,
3,217✔
4290
                channel.ShortChannelID, channel.IsPending, channel.IsInitiator,
3,217✔
4291
                channel.chanStatus, channel.FundingBroadcastHeight,
3,217✔
4292
                channel.NumConfsRequired, channel.ChannelFlags,
3,217✔
4293
                channel.IdentityPub, channel.Capacity, channel.TotalMSatSent,
3,217✔
4294
                channel.TotalMSatReceived,
3,217✔
4295
        ); err != nil {
3,217✔
4296
                return err
×
4297
        }
×
4298

4299
        // For single funder channels that we initiated, and we have the
4300
        // funding transaction, then write the funding txn.
4301
        if fundingTxPresent(channel) {
5,106✔
4302
                if err := WriteElement(&w, channel.FundingTxn); err != nil {
1,889✔
4303
                        return err
×
4304
                }
×
4305
        }
4306

4307
        if err := writeChanConfig(&w, &channel.LocalChanCfg); err != nil {
3,217✔
4308
                return err
×
4309
        }
×
4310
        if err := writeChanConfig(&w, &channel.RemoteChanCfg); err != nil {
3,217✔
4311
                return err
×
4312
        }
×
4313

4314
        auxData := channel.extractTlvData()
3,217✔
4315
        if err := auxData.encode(&w); err != nil {
3,217✔
4316
                return fmt.Errorf("unable to encode aux data: %w", err)
×
4317
        }
×
4318

4319
        if err := chanBucket.Put(chanInfoKey, w.Bytes()); err != nil {
3,217✔
4320
                return err
×
4321
        }
×
4322

4323
        // Finally, add optional shutdown scripts for the local and remote peer if
4324
        // they are present.
4325
        if err := putOptionalUpfrontShutdownScript(
3,217✔
4326
                chanBucket, localUpfrontShutdownKey, channel.LocalShutdownScript,
3,217✔
4327
        ); err != nil {
3,217✔
4328
                return err
×
4329
        }
×
4330

4331
        return putOptionalUpfrontShutdownScript(
3,217✔
4332
                chanBucket, remoteUpfrontShutdownKey, channel.RemoteShutdownScript,
3,217✔
4333
        )
3,217✔
4334
}
4335

4336
// putOptionalUpfrontShutdownScript adds a shutdown script under the key
4337
// provided if it has a non-zero length.
4338
func putOptionalUpfrontShutdownScript(chanBucket kvdb.RwBucket, key []byte,
4339
        script []byte) error {
6,430✔
4340
        // If the script is empty, we do not need to add anything.
6,430✔
4341
        if len(script) == 0 {
12,850✔
4342
                return nil
6,420✔
4343
        }
6,420✔
4344

4345
        var w bytes.Buffer
14✔
4346
        if err := WriteElement(&w, script); err != nil {
14✔
4347
                return err
×
4348
        }
×
4349

4350
        return chanBucket.Put(key, w.Bytes())
14✔
4351
}
4352

4353
// getOptionalUpfrontShutdownScript reads the shutdown script stored under the
4354
// key provided if it is present. Upfront shutdown scripts are optional, so the
4355
// function returns with no error if the key is not present.
4356
func getOptionalUpfrontShutdownScript(chanBucket kvdb.RBucket, key []byte,
4357
        script *lnwire.DeliveryAddress) error {
14,238✔
4358

14,238✔
4359
        // Return early if the bucket does not exit, a shutdown script was not set.
14,238✔
4360
        bs := chanBucket.Get(key)
14,238✔
4361
        if bs == nil {
28,472✔
4362
                return nil
14,234✔
4363
        }
14,234✔
4364

4365
        var tempScript []byte
8✔
4366
        r := bytes.NewReader(bs)
8✔
4367
        if err := ReadElement(r, &tempScript); err != nil {
8✔
4368
                return err
×
4369
        }
×
4370
        *script = tempScript
8✔
4371

8✔
4372
        return nil
8✔
4373
}
4374

4375
func serializeChanCommit(w io.Writer, c *ChannelCommitment) error {
8,428✔
4376
        if err := WriteElements(w,
8,428✔
4377
                c.CommitHeight, c.LocalLogIndex, c.LocalHtlcIndex,
8,428✔
4378
                c.RemoteLogIndex, c.RemoteHtlcIndex, c.LocalBalance,
8,428✔
4379
                c.RemoteBalance, c.CommitFee, c.FeePerKw, c.CommitTx,
8,428✔
4380
                c.CommitSig,
8,428✔
4381
        ); err != nil {
8,428✔
4382
                return err
×
4383
        }
×
4384

4385
        return SerializeHtlcs(w, c.Htlcs...)
8,428✔
4386
}
4387

4388
func putChanCommitment(chanBucket kvdb.RwBucket, c *ChannelCommitment,
4389
        local bool) error {
6,386✔
4390

6,386✔
4391
        var commitKey []byte
6,386✔
4392
        if local {
9,602✔
4393
                commitKey = append(chanCommitmentKey, byte(0x00))
3,216✔
4394
        } else {
6,390✔
4395
                commitKey = append(chanCommitmentKey, byte(0x01))
3,174✔
4396
        }
3,174✔
4397

4398
        var b bytes.Buffer
6,386✔
4399
        if err := serializeChanCommit(&b, c); err != nil {
6,386✔
4400
                return err
×
4401
        }
×
4402

4403
        // Before we write to disk, we'll also write our aux data as well.
4404
        auxData := c.extractTlvData()
6,386✔
4405
        if err := auxData.encode(&b); err != nil {
6,386✔
4406
                return fmt.Errorf("unable to write aux data: %w", err)
×
4407
        }
×
4408

4409
        return chanBucket.Put(commitKey, b.Bytes())
6,386✔
4410
}
4411

4412
func putChanCommitments(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
1,224✔
4413
        // If this is a restored channel, then we don't have any commitments to
1,224✔
4414
        // write.
1,224✔
4415
        if channel.hasChanStatus(ChanStatusRestored) {
1,229✔
4416
                return nil
5✔
4417
        }
5✔
4418

4419
        err := putChanCommitment(
1,223✔
4420
                chanBucket, &channel.LocalCommitment, true,
1,223✔
4421
        )
1,223✔
4422
        if err != nil {
1,223✔
4423
                return err
×
4424
        }
×
4425

4426
        return putChanCommitment(
1,223✔
4427
                chanBucket, &channel.RemoteCommitment, false,
1,223✔
4428
        )
1,223✔
4429
}
4430

4431
func putChanRevocationState(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
3,797✔
4432
        var b bytes.Buffer
3,797✔
4433
        err := WriteElements(
3,797✔
4434
                &b, channel.RemoteCurrentRevocation, channel.RevocationProducer,
3,797✔
4435
                channel.RevocationStore,
3,797✔
4436
        )
3,797✔
4437
        if err != nil {
3,797✔
4438
                return err
×
4439
        }
×
4440

4441
        // If the next revocation is present, which is only the case after the
4442
        // ChannelReady message has been sent, then we'll write it to disk.
4443
        if channel.RemoteNextRevocation != nil {
6,837✔
4444
                err = WriteElements(&b, channel.RemoteNextRevocation)
3,040✔
4445
                if err != nil {
3,040✔
4446
                        return err
×
4447
                }
×
4448
        }
4449

4450
        return chanBucket.Put(revocationStateKey, b.Bytes())
3,797✔
4451
}
4452

4453
func readChanConfig(b io.Reader, c *ChannelConfig) error {
14,360✔
4454
        return ReadElements(b,
14,360✔
4455
                &c.DustLimit, &c.MaxPendingAmount, &c.ChanReserve,
14,360✔
4456
                &c.MinHTLC, &c.MaxAcceptedHtlcs, &c.CsvDelay,
14,360✔
4457
                &c.MultiSigKey, &c.RevocationBasePoint,
14,360✔
4458
                &c.PaymentBasePoint, &c.DelayBasePoint,
14,360✔
4459
                &c.HtlcBasePoint,
14,360✔
4460
        )
14,360✔
4461
}
14,360✔
4462

4463
func fetchChanInfo(chanBucket kvdb.RBucket, channel *OpenChannel) error {
7,121✔
4464
        infoBytes := chanBucket.Get(chanInfoKey)
7,121✔
4465
        if infoBytes == nil {
7,121✔
4466
                return ErrNoChanInfoFound
×
4467
        }
×
4468
        r := bytes.NewReader(infoBytes)
7,121✔
4469

7,121✔
4470
        if err := ReadElements(r,
7,121✔
4471
                &channel.ChanType, &channel.ChainHash, &channel.FundingOutpoint,
7,121✔
4472
                &channel.ShortChannelID, &channel.IsPending, &channel.IsInitiator,
7,121✔
4473
                &channel.chanStatus, &channel.FundingBroadcastHeight,
7,121✔
4474
                &channel.NumConfsRequired, &channel.ChannelFlags,
7,121✔
4475
                &channel.IdentityPub, &channel.Capacity, &channel.TotalMSatSent,
7,121✔
4476
                &channel.TotalMSatReceived,
7,121✔
4477
        ); err != nil {
7,121✔
4478
                return err
×
4479
        }
×
4480

4481
        // For single funder channels that we initiated and have the funding
4482
        // transaction to, read the funding txn.
4483
        if fundingTxPresent(channel) {
10,894✔
4484
                if err := ReadElement(r, &channel.FundingTxn); err != nil {
3,773✔
4485
                        return err
×
4486
                }
×
4487
        }
4488

4489
        if err := readChanConfig(r, &channel.LocalChanCfg); err != nil {
7,121✔
4490
                return err
×
4491
        }
×
4492
        if err := readChanConfig(r, &channel.RemoteChanCfg); err != nil {
7,121✔
4493
                return err
×
4494
        }
×
4495

4496
        // Retrieve the boolean stored under lastWasRevokeKey.
4497
        lastWasRevokeBytes := chanBucket.Get(lastWasRevokeKey)
7,121✔
4498
        if lastWasRevokeBytes == nil {
8,452✔
4499
                // If nothing has been stored under this key, we store false in the
1,331✔
4500
                // OpenChannel struct.
1,331✔
4501
                channel.LastWasRevoke = false
1,331✔
4502
        } else {
7,125✔
4503
                // Otherwise, read the value into the LastWasRevoke field.
5,794✔
4504
                revokeReader := bytes.NewReader(lastWasRevokeBytes)
5,794✔
4505
                err := ReadElements(revokeReader, &channel.LastWasRevoke)
5,794✔
4506
                if err != nil {
5,794✔
4507
                        return err
×
4508
                }
×
4509
        }
4510

4511
        var auxData openChannelTlvData
7,121✔
4512
        if err := auxData.decode(r); err != nil {
7,121✔
4513
                return fmt.Errorf("unable to decode aux data: %w", err)
×
4514
        }
×
4515

4516
        // Assign all the relevant fields from the aux data into the actual
4517
        // open channel.
4518
        channel.amendTlvData(auxData)
7,121✔
4519

7,121✔
4520
        channel.Packager = NewChannelPackager(channel.ShortChannelID)
7,121✔
4521

7,121✔
4522
        // Finally, read the optional shutdown scripts.
7,121✔
4523
        if err := getOptionalUpfrontShutdownScript(
7,121✔
4524
                chanBucket, localUpfrontShutdownKey, &channel.LocalShutdownScript,
7,121✔
4525
        ); err != nil {
7,121✔
4526
                return err
×
4527
        }
×
4528

4529
        return getOptionalUpfrontShutdownScript(
7,121✔
4530
                chanBucket, remoteUpfrontShutdownKey, &channel.RemoteShutdownScript,
7,121✔
4531
        )
7,121✔
4532
}
4533

4534
func deserializeChanCommit(r io.Reader) (ChannelCommitment, error) {
16,298✔
4535
        var c ChannelCommitment
16,298✔
4536

16,298✔
4537
        err := ReadElements(r,
16,298✔
4538
                &c.CommitHeight, &c.LocalLogIndex, &c.LocalHtlcIndex, &c.RemoteLogIndex,
16,298✔
4539
                &c.RemoteHtlcIndex, &c.LocalBalance, &c.RemoteBalance,
16,298✔
4540
                &c.CommitFee, &c.FeePerKw, &c.CommitTx, &c.CommitSig,
16,298✔
4541
        )
16,298✔
4542
        if err != nil {
16,298✔
4543
                return c, err
×
4544
        }
×
4545

4546
        c.Htlcs, err = DeserializeHtlcs(r)
16,298✔
4547
        if err != nil {
16,298✔
4548
                return c, err
×
4549
        }
×
4550

4551
        return c, nil
16,298✔
4552
}
4553

4554
func fetchChanCommitment(chanBucket kvdb.RBucket,
4555
        local bool) (ChannelCommitment, error) {
14,265✔
4556

14,265✔
4557
        var commitKey []byte
14,265✔
4558
        if local {
21,400✔
4559
                commitKey = append(chanCommitmentKey, byte(0x00))
7,135✔
4560
        } else {
14,269✔
4561
                commitKey = append(chanCommitmentKey, byte(0x01))
7,134✔
4562
        }
7,134✔
4563

4564
        commitBytes := chanBucket.Get(commitKey)
14,265✔
4565
        if commitBytes == nil {
14,265✔
4566
                return ChannelCommitment{}, ErrNoCommitmentsFound
×
4567
        }
×
4568

4569
        r := bytes.NewReader(commitBytes)
14,265✔
4570
        chanCommit, err := deserializeChanCommit(r)
14,265✔
4571
        if err != nil {
14,265✔
4572
                return ChannelCommitment{}, fmt.Errorf("unable to decode "+
×
4573
                        "chan commit: %w", err)
×
4574
        }
×
4575

4576
        // We'll also check to see if we have any aux data stored as the end of
4577
        // the stream.
4578
        var auxData commitTlvData
14,265✔
4579
        if err := auxData.decode(r); err != nil {
14,265✔
4580
                return ChannelCommitment{}, fmt.Errorf("unable to decode "+
×
4581
                        "chan aux data: %w", err)
×
4582
        }
×
4583

4584
        chanCommit.amendTlvData(auxData)
14,265✔
4585

14,265✔
4586
        return chanCommit, nil
14,265✔
4587
}
4588

4589
func fetchChanCommitments(chanBucket kvdb.RBucket, channel *OpenChannel) error {
7,136✔
4590
        var err error
7,136✔
4591

7,136✔
4592
        // If this is a restored channel, then we don't have any commitments to
7,136✔
4593
        // read.
7,136✔
4594
        if channel.hasChanStatus(ChanStatusRestored) {
7,142✔
4595
                return nil
6✔
4596
        }
6✔
4597

4598
        channel.LocalCommitment, err = fetchChanCommitment(chanBucket, true)
7,134✔
4599
        if err != nil {
7,134✔
4600
                return err
×
4601
        }
×
4602
        channel.RemoteCommitment, err = fetchChanCommitment(chanBucket, false)
7,134✔
4603
        if err != nil {
7,134✔
4604
                return err
×
4605
        }
×
4606

4607
        return nil
7,134✔
4608
}
4609

4610
func fetchChanRevocationState(chanBucket kvdb.RBucket, channel *OpenChannel) error {
7,136✔
4611
        revBytes := chanBucket.Get(revocationStateKey)
7,136✔
4612
        if revBytes == nil {
7,136✔
4613
                return ErrNoRevocationsFound
×
4614
        }
×
4615
        r := bytes.NewReader(revBytes)
7,136✔
4616

7,136✔
4617
        err := ReadElements(
7,136✔
4618
                r, &channel.RemoteCurrentRevocation, &channel.RevocationProducer,
7,136✔
4619
                &channel.RevocationStore,
7,136✔
4620
        )
7,136✔
4621
        if err != nil {
7,136✔
4622
                return err
×
4623
        }
×
4624

4625
        // If there aren't any bytes left in the buffer, then we don't yet have
4626
        // the next remote revocation, so we can exit early here.
4627
        if r.Len() == 0 {
7,349✔
4628
                return nil
213✔
4629
        }
213✔
4630

4631
        // Otherwise we'll read the next revocation for the remote party which
4632
        // is always the last item within the buffer.
4633
        return ReadElements(r, &channel.RemoteNextRevocation)
6,927✔
4634
}
4635

4636
func deleteOpenChannel(chanBucket kvdb.RwBucket) error {
118✔
4637
        if err := chanBucket.Delete(chanInfoKey); err != nil {
118✔
4638
                return err
×
4639
        }
×
4640

4641
        err := chanBucket.Delete(append(chanCommitmentKey, byte(0x00)))
118✔
4642
        if err != nil {
118✔
4643
                return err
×
4644
        }
×
4645
        err = chanBucket.Delete(append(chanCommitmentKey, byte(0x01)))
118✔
4646
        if err != nil {
118✔
4647
                return err
×
4648
        }
×
4649

4650
        if err := chanBucket.Delete(revocationStateKey); err != nil {
118✔
4651
                return err
×
4652
        }
×
4653

4654
        if diff := chanBucket.Get(commitDiffKey); diff != nil {
122✔
4655
                return chanBucket.Delete(commitDiffKey)
4✔
4656
        }
4✔
4657

4658
        return nil
118✔
4659
}
4660

4661
// makeLogKey converts a uint64 into an 8 byte array.
4662
func makeLogKey(updateNum uint64) [8]byte {
10,007✔
4663
        var key [8]byte
10,007✔
4664
        byteOrder.PutUint64(key[:], updateNum)
10,007✔
4665
        return key
10,007✔
4666
}
10,007✔
4667

4668
func fetchThawHeight(chanBucket kvdb.RBucket) (uint32, error) {
338✔
4669
        var height uint32
338✔
4670

338✔
4671
        heightBytes := chanBucket.Get(frozenChanKey)
338✔
4672
        heightReader := bytes.NewReader(heightBytes)
338✔
4673

338✔
4674
        if err := ReadElements(heightReader, &height); err != nil {
338✔
4675
                return 0, err
×
4676
        }
×
4677

4678
        return height, nil
338✔
4679
}
4680

4681
func storeThawHeight(chanBucket kvdb.RwBucket, height uint32) error {
432✔
4682
        var heightBuf bytes.Buffer
432✔
4683
        if err := WriteElements(&heightBuf, height); err != nil {
432✔
4684
                return err
×
4685
        }
×
4686

4687
        return chanBucket.Put(frozenChanKey, heightBuf.Bytes())
432✔
4688
}
4689

4690
func deleteThawHeight(chanBucket kvdb.RwBucket) error {
111✔
4691
        return chanBucket.Delete(frozenChanKey)
111✔
4692
}
111✔
4693

4694
// keyLocRecord is a wrapper struct around keychain.KeyLocator to implement the
4695
// tlv.RecordProducer interface.
4696
type keyLocRecord struct {
4697
        keychain.KeyLocator
4698
}
4699

4700
// Record creates a Record out of a KeyLocator using the passed Type and the
4701
// EKeyLocator and DKeyLocator functions. The size will always be 8 as
4702
// KeyFamily is uint32 and the Index is uint32.
4703
//
4704
// NOTE: This is part of the tlv.RecordProducer interface.
4705
func (k *keyLocRecord) Record() tlv.Record {
10,334✔
4706
        // Note that we set the type here as zero, as when used with a
10,334✔
4707
        // tlv.RecordT, the type param will be used as the type.
10,334✔
4708
        return tlv.MakeStaticRecord(
10,334✔
4709
                0, &k.KeyLocator, 8, EKeyLocator, DKeyLocator,
10,334✔
4710
        )
10,334✔
4711
}
10,334✔
4712

4713
// EKeyLocator is an encoder for keychain.KeyLocator.
4714
func EKeyLocator(w io.Writer, val interface{}, buf *[8]byte) error {
3,218✔
4715
        if v, ok := val.(*keychain.KeyLocator); ok {
6,436✔
4716
                err := tlv.EUint32T(w, uint32(v.Family), buf)
3,218✔
4717
                if err != nil {
3,218✔
4718
                        return err
×
4719
                }
×
4720

4721
                return tlv.EUint32T(w, v.Index, buf)
3,218✔
4722
        }
4723
        return tlv.NewTypeForEncodingErr(val, "keychain.KeyLocator")
×
4724
}
4725

4726
// DKeyLocator is a decoder for keychain.KeyLocator.
4727
func DKeyLocator(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
7,122✔
4728
        if v, ok := val.(*keychain.KeyLocator); ok {
14,244✔
4729
                var family uint32
7,122✔
4730
                err := tlv.DUint32(r, &family, buf, 4)
7,122✔
4731
                if err != nil {
7,122✔
4732
                        return err
×
4733
                }
×
4734
                v.Family = keychain.KeyFamily(family)
7,122✔
4735

7,122✔
4736
                return tlv.DUint32(r, &v.Index, buf, 4)
7,122✔
4737
        }
4738
        return tlv.NewTypeForDecodingErr(val, "keychain.KeyLocator", l, 8)
×
4739
}
4740

4741
// ShutdownInfo contains various info about the shutdown initiation of a
4742
// channel.
4743
type ShutdownInfo struct {
4744
        // DeliveryScript is the address that we have included in any previous
4745
        // Shutdown message for a particular channel and so should include in
4746
        // any future re-sends of the Shutdown message.
4747
        DeliveryScript tlv.RecordT[tlv.TlvType0, lnwire.DeliveryAddress]
4748

4749
        // LocalInitiator is true if we sent a Shutdown message before ever
4750
        // receiving a Shutdown message from the remote peer.
4751
        LocalInitiator tlv.RecordT[tlv.TlvType1, bool]
4752
}
4753

4754
// NewShutdownInfo constructs a new ShutdownInfo object.
4755
func NewShutdownInfo(deliveryScript lnwire.DeliveryAddress,
4756
        locallyInitiated bool) *ShutdownInfo {
17✔
4757

17✔
4758
        return &ShutdownInfo{
17✔
4759
                DeliveryScript: tlv.NewRecordT[tlv.TlvType0](deliveryScript),
17✔
4760
                LocalInitiator: tlv.NewPrimitiveRecord[tlv.TlvType1](
17✔
4761
                        locallyInitiated,
17✔
4762
                ),
17✔
4763
        }
17✔
4764
}
17✔
4765

4766
// Closer identifies the ChannelParty that initiated the coop-closure process.
4767
func (s ShutdownInfo) Closer() lntypes.ChannelParty {
4✔
4768
        if s.LocalInitiator.Val {
8✔
4769
                return lntypes.Local
4✔
4770
        }
4✔
4771

4772
        return lntypes.Remote
4✔
4773
}
4774

4775
// encode serialises the ShutdownInfo to the given io.Writer.
4776
func (s *ShutdownInfo) encode(w io.Writer) error {
15✔
4777
        records := []tlv.Record{
15✔
4778
                s.DeliveryScript.Record(),
15✔
4779
                s.LocalInitiator.Record(),
15✔
4780
        }
15✔
4781

15✔
4782
        stream, err := tlv.NewStream(records...)
15✔
4783
        if err != nil {
15✔
4784
                return err
×
4785
        }
×
4786

4787
        return stream.Encode(w)
15✔
4788
}
4789

4790
// decodeShutdownInfo constructs a ShutdownInfo struct by decoding the given
4791
// byte slice.
4792
func decodeShutdownInfo(b []byte) (*ShutdownInfo, error) {
6✔
4793
        tlvStream := lnwire.ExtraOpaqueData(b)
6✔
4794

6✔
4795
        var info ShutdownInfo
6✔
4796
        records := []tlv.RecordProducer{
6✔
4797
                &info.DeliveryScript,
6✔
4798
                &info.LocalInitiator,
6✔
4799
        }
6✔
4800

6✔
4801
        _, err := tlvStream.ExtractRecords(records...)
6✔
4802

6✔
4803
        return &info, err
6✔
4804
}
6✔
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