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

lightningnetwork / lnd / 14463180103

15 Apr 2025 06:54AM UTC coverage: 69.094% (+10.5%) from 58.608%
14463180103

Pull #9677

github

web-flow
Merge 8a13679dd into 7d3b5a1bc
Pull Request #9677: Expose confirmation count for pending 'channel open' transactions

121 of 156 new or added lines in 3 files covered. (77.56%)

36 existing lines in 5 files now uncovered.

133720 of 193533 relevant lines covered (69.09%)

22134.89 hits per line

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

78.21
/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/v2"
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,282✔
268
        tlvRecords := []tlv.Record{
3,282✔
269
                c.revokeKeyLoc.Record(),
3,282✔
270
                c.initialLocalBalance.Record(),
3,282✔
271
                c.initialRemoteBalance.Record(),
3,282✔
272
                c.realScid.Record(),
3,282✔
273
        }
3,282✔
274
        c.memo.WhenSome(func(memo tlv.RecordT[tlv.TlvType5, []byte]) {
3,714✔
275
                tlvRecords = append(tlvRecords, memo.Record())
432✔
276
        })
432✔
277
        c.tapscriptRoot.WhenSome(
3,282✔
278
                func(root tlv.RecordT[tlv.TlvType6, [32]byte]) {
3,763✔
279
                        tlvRecords = append(tlvRecords, root.Record())
481✔
280
                },
481✔
281
        )
282
        c.customBlob.WhenSome(func(blob tlv.RecordT[tlv.TlvType7, tlv.Blob]) {
3,711✔
283
                tlvRecords = append(tlvRecords, blob.Record())
429✔
284
        })
429✔
285

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

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

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

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

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

320
        if _, ok := tlvs[memo.TlvType()]; ok {
7,581✔
321
                c.memo = tlv.SomeRecordT(memo)
342✔
322
        }
342✔
323
        if _, ok := tlvs[tapscriptRoot.TlvType()]; ok {
7,686✔
324
                c.tapscriptRoot = tlv.SomeRecordT(tapscriptRoot)
447✔
325
        }
447✔
326
        if _, ok := tlvs[c.customBlob.TlvType()]; ok {
7,578✔
327
                c.customBlob = tlv.SomeRecordT(blob)
339✔
328
        }
339✔
329

330
        return nil
7,239✔
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,604✔
420
        return c&DualFunderBit == 0
10,604✔
421
}
10,604✔
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,728✔
431
        return c&SingleFunderTweaklessBit == SingleFunderTweaklessBit
10,728✔
432
}
10,728✔
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,614✔
437
        return c&NoFundingTxBit == 0
10,614✔
438
}
10,614✔
439

440
// HasAnchors returns true if this channel type has anchor outputs on its
441
// commitment.
442
func (c ChannelType) HasAnchors() bool {
253,057✔
443
        return c&AnchorOutputsBit == AnchorOutputsBit
253,057✔
444
}
253,057✔
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 {
202,159✔
449
        return c&ZeroHtlcTxFeeBit == ZeroHtlcTxFeeBit
202,159✔
450
}
202,159✔
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,638✔
456
        return c&FrozenBit == FrozenBit
8,638✔
457
}
8,638✔
458

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

464
// HasZeroConf returns true if the channel is a zero-conf channel.
465
func (c ChannelType) HasZeroConf() bool {
705✔
466
        return c&ZeroConfBit == ZeroConfBit
705✔
467
}
705✔
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 {
504✔
477
        return c&ScidAliasFeatureBit == ScidAliasFeatureBit
504✔
478
}
504✔
479

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

485
// HasTapscriptRoot returns true if the channel is using a top level tapscript
486
// root commitment.
487
func (c ChannelType) HasTapscriptRoot() bool {
298✔
488
        return c&TapscriptRootBit == TapscriptRootBit
298✔
489
}
298✔
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,584✔
602
        var tlvRecords []tlv.Record
8,584✔
603
        c.customBlob.WhenSome(func(blob tlv.RecordT[tlv.TlvType1, tlv.Blob]) {
9,445✔
604
                tlvRecords = append(tlvRecords, blob.Record())
861✔
605
        })
861✔
606

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

613
        return tlvStream.Encode(w)
8,584✔
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,562✔
618
        blob := c.customBlob.Zero()
16,562✔
619

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

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

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

636
        return nil
16,562✔
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,562✔
723
        auxData.customBlob.WhenSomeV(func(blob tlv.Blob) {
17,244✔
724
                c.CustomBlob = fn.Some(blob)
682✔
725
        })
682✔
726
}
727

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

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

738
        return auxData
8,584✔
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 {
4✔
816
        // If no flags are set, then this is the default case.
4✔
817
        if c == ChanStatusDefault {
7✔
818
                return chanStatusStrings[ChanStatusDefault]
3✔
819
        }
3✔
820

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

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

4✔
833
        // Add any remaining flags which aren't accounted for as hex.
4✔
834
        if c != 0 {
4✔
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, "|")
4✔
841

4✔
842
        return statusStr
4✔
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 {
3✔
1052
        indexStr := "height=%v, local_htlc_index=%v, local_log_index=%v, " +
3✔
1053
                "remote_htlc_index=%v, remote_log_index=%v"
3✔
1054

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

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

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

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

15,565✔
1079
        if c.IsInitiator {
25,186✔
1080
                return lntypes.Local
9,621✔
1081
        }
9,621✔
1082

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

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

8,260✔
1091
        return c.ShortChannelID
8,260✔
1092
}
8,260✔
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 {
29✔
1097
        c.RLock()
29✔
1098
        defer c.RUnlock()
29✔
1099

29✔
1100
        return c.confirmedScid
29✔
1101
}
29✔
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 {
39✔
1106
        c.RLock()
39✔
1107
        defer c.RUnlock()
39✔
1108

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

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

705✔
1117
        return c.ChanType.HasZeroConf()
705✔
1118
}
705✔
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 {
485✔
1132
        c.RLock()
485✔
1133
        defer c.RUnlock()
485✔
1134

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

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

216✔
1143
        return c.chanStatus
216✔
1144
}
216✔
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 {
376✔
1168
        c.RLock()
376✔
1169
        defer c.RUnlock()
376✔
1170

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

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

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

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

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

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

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

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

7,239✔
1211
        auxData.memo.WhenSomeV(func(memo []byte) {
7,581✔
1212
                c.Memo = memo
342✔
1213
        })
342✔
1214
        auxData.tapscriptRoot.WhenSomeV(func(h [32]byte) {
7,686✔
1215
                c.TapscriptRoot = fn.Some[chainhash.Hash](h)
447✔
1216
        })
447✔
1217
        auxData.customBlob.WhenSomeV(func(blob tlv.Blob) {
7,578✔
1218
                c.CustomBlob = fn.Some(blob)
339✔
1219
        })
339✔
1220
}
1221

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

3,282✔
1239
        if len(c.Memo) != 0 {
3,714✔
1240
                auxData.memo = tlv.SomeRecordT(
432✔
1241
                        tlv.NewPrimitiveRecord[tlv.TlvType5](c.Memo),
432✔
1242
                )
432✔
1243
        }
432✔
1244
        c.TapscriptRoot.WhenSome(func(h chainhash.Hash) {
3,763✔
1245
                auxData.tapscriptRoot = tlv.SomeRecordT(
481✔
1246
                        tlv.NewPrimitiveRecord[tlv.TlvType6, [32]byte](h),
481✔
1247
                )
481✔
1248
        })
481✔
1249
        c.CustomBlob.WhenSome(func(blob tlv.Blob) {
3,711✔
1250
                auxData.customBlob = tlv.SomeRecordT(
429✔
1251
                        tlv.NewPrimitiveRecord[tlv.TlvType7](blob),
429✔
1252
                )
429✔
1253
        })
429✔
1254

1255
        return auxData
3,282✔
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 {
12✔
1269
                        return err
3✔
1270
                }
3✔
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 {
12✔
1294
                return err
3✔
1295
        }
3✔
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,963✔
1305

2,963✔
1306
        // First fetch the top level bucket which stores all data related to
2,963✔
1307
        // current, active channels.
2,963✔
1308
        openChanBucket := tx.ReadBucket(openChannelBucket)
2,963✔
1309
        if openChanBucket == nil {
2,963✔
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,963✔
1319
        nodeChanBucket := openChanBucket.NestedReadBucket(nodePub)
2,963✔
1320
        if nodeChanBucket == nil {
4,091✔
1321
                return nil, ErrNoActiveChannels
1,128✔
1322
        }
1,128✔
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,839✔
1339
                return nil, ErrChannelNotFound
4✔
1340
        }
4✔
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,968✔
1352

6,968✔
1353
        // First fetch the top level bucket which stores all data related to
6,968✔
1354
        // current, active channels.
6,968✔
1355
        openChanBucket := tx.ReadWriteBucket(openChannelBucket)
6,968✔
1356
        if openChanBucket == nil {
6,968✔
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,968✔
1366
        nodeChanBucket := openChanBucket.NestedReadWriteBucket(nodePub)
6,968✔
1367
        if nodeChanBucket == nil {
6,968✔
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,968✔
1374
        if chainBucket == nil {
6,968✔
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,968✔
1381
        if err := graphdb.WriteOutpoint(&chanPointBuf, outPoint); err != nil {
6,968✔
1382
                return nil, err
×
1383
        }
×
1384
        chanBucket := chainBucket.NestedReadWriteBucket(chanPointBuf.Bytes())
6,968✔
1385
        if chanBucket == nil {
6,969✔
1386
                return nil, ErrChannelNotFound
1✔
1387
        }
1✔
1388

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

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

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

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

1409
        return chanBucket, nil
6✔
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 {
890✔
1415
        // Fetch the outpoint bucket and check if the outpoint already exists.
890✔
1416
        opBucket := tx.ReadWriteBucket(outpointBucket)
890✔
1417
        if opBucket == nil {
890✔
1418
                return ErrNoChanDBExists
×
1419
        }
×
1420
        cidBucket := tx.ReadWriteBucket(chanIDBucket)
890✔
1421
        if cidBucket == nil {
890✔
1422
                return ErrNoChanDBExists
×
1423
        }
×
1424

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

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

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

1441
        status := uint8(outpointOpen)
890✔
1442

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

1451
        var b bytes.Buffer
890✔
1452
        if err := opStream.Encode(&b); err != nil {
890✔
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 {
890✔
1458
                return err
×
1459
        }
×
1460

1461
        if err := cidBucket.Put(cid[:], []byte{}); err != nil {
890✔
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)
890✔
1468
        if err != nil {
890✔
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()
890✔
1475
        nodeChanBucket, err := openChanBucket.CreateBucketIfNotExists(nodePub)
890✔
1476
        if err != nil {
890✔
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[:])
890✔
1483
        if err != nil {
890✔
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(
890✔
1490
                chanPointBuf.Bytes(),
890✔
1491
        )
890✔
1492
        switch {
890✔
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)
890✔
1502
}
1503

1504
// MarkConfirmedScid updates the channel's ShortChannelID once the channel
1505
// opening transaction receives one confirmation.
1506
func (c *OpenChannel) MarkConfirmedScid(scid lnwire.ShortChannelID) error {
28✔
1507
        c.Lock()
28✔
1508
        defer c.Unlock()
28✔
1509

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

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

1523
                channel.ShortChannelID = scid
28✔
1524

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

1530
        c.ShortChannelID = scid
28✔
1531

28✔
1532
        return nil
28✔
1533
}
1534

1535
// MarkAsOpen marks a channel as fully open given a locator that uniquely
1536
// describes its location within the chain.
1537
func (c *OpenChannel) MarkAsOpen(openLoc lnwire.ShortChannelID) error {
168✔
1538
        c.Lock()
168✔
1539
        defer c.Unlock()
168✔
1540

168✔
1541
        if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
336✔
1542
                chanBucket, err := fetchChanBucketRw(
168✔
1543
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
168✔
1544
                )
168✔
1545
                if err != nil {
168✔
1546
                        return err
×
1547
                }
×
1548

1549
                channel, err := fetchOpenChannel(chanBucket, &c.FundingOutpoint)
168✔
1550
                if err != nil {
168✔
1551
                        return err
×
1552
                }
×
1553

1554
                channel.IsPending = false
168✔
1555
                channel.ShortChannelID = openLoc
168✔
1556

168✔
1557
                return putOpenChannel(chanBucket, channel)
168✔
1558
        }, func() {}); err != nil {
168✔
1559
                return err
×
1560
        }
×
1561

1562
        c.IsPending = false
168✔
1563
        c.ShortChannelID = openLoc
168✔
1564
        c.Packager = NewChannelPackager(openLoc)
168✔
1565

168✔
1566
        return nil
168✔
1567
}
1568

1569
// MarkRealScid marks the zero-conf channel's confirmed ShortChannelID. This
1570
// should only be done if IsZeroConf returns true.
1571
func (c *OpenChannel) MarkRealScid(realScid lnwire.ShortChannelID) error {
10✔
1572
        c.Lock()
10✔
1573
        defer c.Unlock()
10✔
1574

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

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

1590
                channel.confirmedScid = realScid
10✔
1591

10✔
1592
                return putOpenChannel(chanBucket, channel)
10✔
1593
        }, func() {}); err != nil {
10✔
1594
                return err
×
1595
        }
×
1596

1597
        c.confirmedScid = realScid
10✔
1598

10✔
1599
        return nil
10✔
1600
}
1601

1602
// MarkScidAliasNegotiated adds ScidAliasFeatureBit to ChanType in-memory and
1603
// in the database.
1604
func (c *OpenChannel) MarkScidAliasNegotiated() error {
3✔
1605
        c.Lock()
3✔
1606
        defer c.Unlock()
3✔
1607

3✔
1608
        if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
6✔
1609
                chanBucket, err := fetchChanBucketRw(
3✔
1610
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
3✔
1611
                )
3✔
1612
                if err != nil {
3✔
1613
                        return err
×
1614
                }
×
1615

1616
                channel, err := fetchOpenChannel(
3✔
1617
                        chanBucket, &c.FundingOutpoint,
3✔
1618
                )
3✔
1619
                if err != nil {
3✔
1620
                        return err
×
1621
                }
×
1622

1623
                channel.ChanType |= ScidAliasFeatureBit
3✔
1624
                return putOpenChannel(chanBucket, channel)
3✔
1625
        }, func() {}); err != nil {
3✔
1626
                return err
×
1627
        }
×
1628

1629
        c.ChanType |= ScidAliasFeatureBit
3✔
1630

3✔
1631
        return nil
3✔
1632
}
1633

1634
// MarkDataLoss marks sets the channel status to LocalDataLoss and stores the
1635
// passed commitPoint for use to retrieve funds in case the remote force closes
1636
// the channel.
1637
func (c *OpenChannel) MarkDataLoss(commitPoint *btcec.PublicKey) error {
7✔
1638
        c.Lock()
7✔
1639
        defer c.Unlock()
7✔
1640

7✔
1641
        var b bytes.Buffer
7✔
1642
        if err := WriteElement(&b, commitPoint); err != nil {
7✔
1643
                return err
×
1644
        }
×
1645

1646
        putCommitPoint := func(chanBucket kvdb.RwBucket) error {
14✔
1647
                return chanBucket.Put(dataLossCommitPointKey, b.Bytes())
7✔
1648
        }
7✔
1649

1650
        return c.putChanStatus(ChanStatusLocalDataLoss, putCommitPoint)
7✔
1651
}
1652

1653
// DataLossCommitPoint retrieves the stored commit point set during
1654
// MarkDataLoss. If not found ErrNoCommitPoint is returned.
1655
func (c *OpenChannel) DataLossCommitPoint() (*btcec.PublicKey, error) {
4✔
1656
        var commitPoint *btcec.PublicKey
4✔
1657

4✔
1658
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
8✔
1659
                chanBucket, err := fetchChanBucket(
4✔
1660
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
4✔
1661
                )
4✔
1662
                switch err {
4✔
1663
                case nil:
4✔
1664
                case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
×
1665
                        return ErrNoCommitPoint
×
1666
                default:
×
1667
                        return err
×
1668
                }
1669

1670
                bs := chanBucket.Get(dataLossCommitPointKey)
4✔
1671
                if bs == nil {
4✔
1672
                        return ErrNoCommitPoint
×
1673
                }
×
1674
                r := bytes.NewReader(bs)
4✔
1675
                if err := ReadElements(r, &commitPoint); err != nil {
4✔
1676
                        return err
×
1677
                }
×
1678

1679
                return nil
4✔
1680
        }, func() {
4✔
1681
                commitPoint = nil
4✔
1682
        })
4✔
1683
        if err != nil {
4✔
1684
                return nil, err
×
1685
        }
×
1686

1687
        return commitPoint, nil
4✔
1688
}
1689

1690
// MarkBorked marks the event when the channel as reached an irreconcilable
1691
// state, such as a channel breach or state desynchronization. Borked channels
1692
// should never be added to the switch.
1693
func (c *OpenChannel) MarkBorked() error {
5✔
1694
        c.Lock()
5✔
1695
        defer c.Unlock()
5✔
1696

5✔
1697
        return c.putChanStatus(ChanStatusBorked)
5✔
1698
}
5✔
1699

1700
// SecondCommitmentPoint returns the second per-commitment-point for use in the
1701
// channel_ready message.
1702
func (c *OpenChannel) SecondCommitmentPoint() (*btcec.PublicKey, error) {
3✔
1703
        c.RLock()
3✔
1704
        defer c.RUnlock()
3✔
1705

3✔
1706
        // Since we start at commitment height = 0, the second per commitment
3✔
1707
        // point is actually at the 1st index.
3✔
1708
        revocation, err := c.RevocationProducer.AtIndex(1)
3✔
1709
        if err != nil {
3✔
1710
                return nil, err
×
1711
        }
×
1712

1713
        return input.ComputeCommitmentPoint(revocation[:]), nil
3✔
1714
}
1715

1716
var (
1717
        // taprootRevRootKey is the key used to derive the revocation root for
1718
        // the taproot nonces. This is done via HMAC of the existing revocation
1719
        // root.
1720
        taprootRevRootKey = []byte("taproot-rev-root")
1721
)
1722

1723
// DeriveMusig2Shachain derives a shachain producer for the taproot channel
1724
// from normal shachain revocation root.
1725
func DeriveMusig2Shachain(revRoot shachain.Producer) (shachain.Producer, error) { //nolint:ll
985✔
1726
        // In order to obtain the revocation root hash to create the taproot
985✔
1727
        // revocation, we'll encode the producer into a buffer, then use that
985✔
1728
        // to derive the shachain root needed.
985✔
1729
        var rootHashBuf bytes.Buffer
985✔
1730
        if err := revRoot.Encode(&rootHashBuf); err != nil {
985✔
1731
                return nil, fmt.Errorf("unable to encode producer: %w", err)
×
1732
        }
×
1733

1734
        revRootHash := chainhash.HashH(rootHashBuf.Bytes())
985✔
1735

985✔
1736
        // For taproot channel types, we'll also generate a distinct shachain
985✔
1737
        // root using the same seed information. We'll use this to generate
985✔
1738
        // verification nonces for the channel. We'll bind with this a simple
985✔
1739
        // hmac.
985✔
1740
        taprootRevHmac := hmac.New(sha256.New, taprootRevRootKey)
985✔
1741
        if _, err := taprootRevHmac.Write(revRootHash[:]); err != nil {
985✔
1742
                return nil, err
×
1743
        }
×
1744

1745
        taprootRevRoot := taprootRevHmac.Sum(nil)
985✔
1746

985✔
1747
        // Once we have the root, we can then generate our shachain producer
985✔
1748
        // and from that generate the per-commitment point.
985✔
1749
        return shachain.NewRevocationProducerFromBytes(
985✔
1750
                taprootRevRoot,
985✔
1751
        )
985✔
1752
}
1753

1754
// NewMusigVerificationNonce generates the local or verification nonce for
1755
// another musig2 session. In order to permit our implementation to not have to
1756
// write any secret nonce state to disk, we'll use the _next_ shachain
1757
// pre-image as our primary randomness source. When used to generate the nonce
1758
// again to broadcast our commitment hte current height will be used.
1759
func NewMusigVerificationNonce(pubKey *btcec.PublicKey, targetHeight uint64,
1760
        shaGen shachain.Producer) (*musig2.Nonces, error) {
218✔
1761

218✔
1762
        // Now that we know what height we need, we'll grab the shachain
218✔
1763
        // pre-image at the target destination.
218✔
1764
        nextPreimage, err := shaGen.AtIndex(targetHeight)
218✔
1765
        if err != nil {
218✔
1766
                return nil, err
×
1767
        }
×
1768

1769
        shaChainRand := musig2.WithCustomRand(bytes.NewBuffer(nextPreimage[:]))
218✔
1770
        pubKeyOpt := musig2.WithPublicKey(pubKey)
218✔
1771

218✔
1772
        return musig2.GenNonces(pubKeyOpt, shaChainRand)
218✔
1773
}
1774

1775
// ChanSyncMsg returns the ChannelReestablish message that should be sent upon
1776
// reconnection with the remote peer that we're maintaining this channel with.
1777
// The information contained within this message is necessary to re-sync our
1778
// commitment chains in the case of a last or only partially processed message.
1779
// When the remote party receives this message one of three things may happen:
1780
//
1781
//  1. We're fully synced and no messages need to be sent.
1782
//  2. We didn't get the last CommitSig message they sent, so they'll re-send
1783
//     it.
1784
//  3. We didn't get the last RevokeAndAck message they sent, so they'll
1785
//     re-send it.
1786
//
1787
// If this is a restored channel, having status ChanStatusRestored, then we'll
1788
// modify our typical chan sync message to ensure they force close even if
1789
// we're on the very first state.
1790
func (c *OpenChannel) ChanSyncMsg() (*lnwire.ChannelReestablish, error) {
257✔
1791
        c.Lock()
257✔
1792
        defer c.Unlock()
257✔
1793

257✔
1794
        // The remote commitment height that we'll send in the
257✔
1795
        // ChannelReestablish message is our current commitment height plus
257✔
1796
        // one. If the receiver thinks that our commitment height is actually
257✔
1797
        // *equal* to this value, then they'll re-send the last commitment that
257✔
1798
        // they sent but we never fully processed.
257✔
1799
        localHeight := c.LocalCommitment.CommitHeight
257✔
1800
        nextLocalCommitHeight := localHeight + 1
257✔
1801

257✔
1802
        // The second value we'll send is the height of the remote commitment
257✔
1803
        // from our PoV. If the receiver thinks that their height is actually
257✔
1804
        // *one plus* this value, then they'll re-send their last revocation.
257✔
1805
        remoteChainTipHeight := c.RemoteCommitment.CommitHeight
257✔
1806

257✔
1807
        // If this channel has undergone a commitment update, then in order to
257✔
1808
        // prove to the remote party our knowledge of their prior commitment
257✔
1809
        // state, we'll also send over the last commitment secret that the
257✔
1810
        // remote party sent.
257✔
1811
        var lastCommitSecret [32]byte
257✔
1812
        if remoteChainTipHeight != 0 {
328✔
1813
                remoteSecret, err := c.RevocationStore.LookUp(
71✔
1814
                        remoteChainTipHeight - 1,
71✔
1815
                )
71✔
1816
                if err != nil {
71✔
1817
                        return nil, err
×
1818
                }
×
1819
                lastCommitSecret = [32]byte(*remoteSecret)
71✔
1820
        }
1821

1822
        // Additionally, we'll send over the current unrevoked commitment on
1823
        // our local commitment transaction.
1824
        currentCommitSecret, err := c.RevocationProducer.AtIndex(
257✔
1825
                localHeight,
257✔
1826
        )
257✔
1827
        if err != nil {
257✔
1828
                return nil, err
×
1829
        }
×
1830

1831
        // If we've restored this channel, then we'll purposefully give them an
1832
        // invalid LocalUnrevokedCommitPoint so they'll force close the channel
1833
        // allowing us to sweep our funds.
1834
        if c.hasChanStatus(ChanStatusRestored) {
260✔
1835
                currentCommitSecret[0] ^= 1
3✔
1836

3✔
1837
                // If this is a tweakless channel, then we'll purposefully send
3✔
1838
                // a next local height taht's invalid to trigger a force close
3✔
1839
                // on their end. We do this as tweakless channels don't require
3✔
1840
                // that the commitment point is valid, only that it's present.
3✔
1841
                if c.ChanType.IsTweakless() {
6✔
1842
                        nextLocalCommitHeight = 0
3✔
1843
                }
3✔
1844
        }
1845

1846
        // If this is a taproot channel, then we'll need to generate our next
1847
        // verification nonce to send to the remote party. They'll use this to
1848
        // sign the next update to our commitment transaction.
1849
        var nextTaprootNonce lnwire.OptMusig2NonceTLV
257✔
1850
        if c.ChanType.IsTaproot() {
281✔
1851
                taprootRevProducer, err := DeriveMusig2Shachain(
24✔
1852
                        c.RevocationProducer,
24✔
1853
                )
24✔
1854
                if err != nil {
24✔
1855
                        return nil, err
×
1856
                }
×
1857

1858
                nextNonce, err := NewMusigVerificationNonce(
24✔
1859
                        c.LocalChanCfg.MultiSigKey.PubKey,
24✔
1860
                        nextLocalCommitHeight, taprootRevProducer,
24✔
1861
                )
24✔
1862
                if err != nil {
24✔
1863
                        return nil, fmt.Errorf("unable to gen next "+
×
1864
                                "nonce: %w", err)
×
1865
                }
×
1866

1867
                nextTaprootNonce = lnwire.SomeMusig2Nonce(nextNonce.PubNonce)
24✔
1868
        }
1869

1870
        return &lnwire.ChannelReestablish{
257✔
1871
                ChanID: lnwire.NewChanIDFromOutPoint(
257✔
1872
                        c.FundingOutpoint,
257✔
1873
                ),
257✔
1874
                NextLocalCommitHeight:  nextLocalCommitHeight,
257✔
1875
                RemoteCommitTailHeight: remoteChainTipHeight,
257✔
1876
                LastRemoteCommitSecret: lastCommitSecret,
257✔
1877
                LocalUnrevokedCommitPoint: input.ComputeCommitmentPoint(
257✔
1878
                        currentCommitSecret[:],
257✔
1879
                ),
257✔
1880
                LocalNonce: nextTaprootNonce,
257✔
1881
        }, nil
257✔
1882
}
1883

1884
// MarkShutdownSent serialises and persist the given ShutdownInfo for this
1885
// channel. Persisting this info represents the fact that we have sent the
1886
// Shutdown message to the remote side and hence that we should re-transmit the
1887
// same Shutdown message on re-establish.
1888
func (c *OpenChannel) MarkShutdownSent(info *ShutdownInfo) error {
14✔
1889
        c.Lock()
14✔
1890
        defer c.Unlock()
14✔
1891

14✔
1892
        return c.storeShutdownInfo(info)
14✔
1893
}
14✔
1894

1895
// storeShutdownInfo serialises the ShutdownInfo and persists it under the
1896
// shutdownInfoKey.
1897
func (c *OpenChannel) storeShutdownInfo(info *ShutdownInfo) error {
14✔
1898
        var b bytes.Buffer
14✔
1899
        err := info.encode(&b)
14✔
1900
        if err != nil {
14✔
1901
                return err
×
1902
        }
×
1903

1904
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
28✔
1905
                chanBucket, err := fetchChanBucketRw(
14✔
1906
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
14✔
1907
                )
14✔
1908
                if err != nil {
14✔
1909
                        return err
×
1910
                }
×
1911

1912
                return chanBucket.Put(shutdownInfoKey, b.Bytes())
14✔
1913
        }, func() {})
14✔
1914
}
1915

1916
// ShutdownInfo decodes the shutdown info stored for this channel and returns
1917
// the result. If no shutdown info has been persisted for this channel then the
1918
// ErrNoShutdownInfo error is returned.
1919
func (c *OpenChannel) ShutdownInfo() (fn.Option[ShutdownInfo], error) {
7✔
1920
        c.RLock()
7✔
1921
        defer c.RUnlock()
7✔
1922

7✔
1923
        var shutdownInfo *ShutdownInfo
7✔
1924
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
14✔
1925
                chanBucket, err := fetchChanBucket(
7✔
1926
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
7✔
1927
                )
7✔
1928
                switch {
7✔
1929
                case err == nil:
7✔
1930
                case errors.Is(err, ErrNoChanDBExists),
1931
                        errors.Is(err, ErrNoActiveChannels),
1932
                        errors.Is(err, ErrChannelNotFound):
2✔
1933

2✔
1934
                        return ErrNoShutdownInfo
2✔
1935
                default:
×
1936
                        return err
×
1937
                }
1938

1939
                shutdownInfoBytes := chanBucket.Get(shutdownInfoKey)
7✔
1940
                if shutdownInfoBytes == nil {
12✔
1941
                        return ErrNoShutdownInfo
5✔
1942
                }
5✔
1943

1944
                shutdownInfo, err = decodeShutdownInfo(shutdownInfoBytes)
5✔
1945

5✔
1946
                return err
5✔
1947
        }, func() {
7✔
1948
                shutdownInfo = nil
7✔
1949
        })
7✔
1950
        if err != nil {
12✔
1951
                return fn.None[ShutdownInfo](), err
5✔
1952
        }
5✔
1953

1954
        return fn.Some[ShutdownInfo](*shutdownInfo), nil
5✔
1955
}
1956

1957
// isBorked returns true if the channel has been marked as borked in the
1958
// database. This requires an existing database transaction to already be
1959
// active.
1960
//
1961
// NOTE: The primary mutex should already be held before this method is called.
1962
func (c *OpenChannel) isBorked(chanBucket kvdb.RBucket) (bool, error) {
6,073✔
1963
        channel, err := fetchOpenChannel(chanBucket, &c.FundingOutpoint)
6,073✔
1964
        if err != nil {
6,073✔
1965
                return false, err
×
1966
        }
×
1967

1968
        return channel.chanStatus != ChanStatusDefault, nil
6,073✔
1969
}
1970

1971
// MarkCommitmentBroadcasted marks the channel as a commitment transaction has
1972
// been broadcast, either our own or the remote, and we should watch the chain
1973
// for it to confirm before taking any further action. It takes as argument the
1974
// closing tx _we believe_ will appear in the chain. This is only used to
1975
// republish this tx at startup to ensure propagation, and we should still
1976
// handle the case where a different tx actually hits the chain.
1977
func (c *OpenChannel) MarkCommitmentBroadcasted(closeTx *wire.MsgTx,
1978
        closer lntypes.ChannelParty) error {
11✔
1979

11✔
1980
        return c.markBroadcasted(
11✔
1981
                ChanStatusCommitBroadcasted, forceCloseTxKey, closeTx,
11✔
1982
                closer,
11✔
1983
        )
11✔
1984
}
11✔
1985

1986
// MarkCoopBroadcasted marks the channel to indicate that a cooperative close
1987
// transaction has been broadcast, either our own or the remote, and that we
1988
// should watch the chain for it to confirm before taking further action. It
1989
// takes as argument a cooperative close tx that could appear on chain, and
1990
// should be rebroadcast upon startup. This is only used to republish and
1991
// ensure propagation, and we should still handle the case where a different tx
1992
// actually hits the chain.
1993
func (c *OpenChannel) MarkCoopBroadcasted(closeTx *wire.MsgTx,
1994
        closer lntypes.ChannelParty) error {
41✔
1995

41✔
1996
        return c.markBroadcasted(
41✔
1997
                ChanStatusCoopBroadcasted, coopCloseTxKey, closeTx,
41✔
1998
                closer,
41✔
1999
        )
41✔
2000
}
41✔
2001

2002
// markBroadcasted is a helper function which modifies the channel status of the
2003
// receiving channel and inserts a close transaction under the requested key,
2004
// which should specify either a coop or force close. It adds a status which
2005
// indicates the party that initiated the channel close.
2006
func (c *OpenChannel) markBroadcasted(status ChannelStatus, key []byte,
2007
        closeTx *wire.MsgTx, closer lntypes.ChannelParty) error {
49✔
2008

49✔
2009
        c.Lock()
49✔
2010
        defer c.Unlock()
49✔
2011

49✔
2012
        // If a closing tx is provided, we'll generate a closure to write the
49✔
2013
        // transaction in the appropriate bucket under the given key.
49✔
2014
        var putClosingTx func(kvdb.RwBucket) error
49✔
2015
        if closeTx != nil {
73✔
2016
                var b bytes.Buffer
24✔
2017
                if err := WriteElement(&b, closeTx); err != nil {
24✔
2018
                        return err
×
2019
                }
×
2020

2021
                putClosingTx = func(chanBucket kvdb.RwBucket) error {
48✔
2022
                        return chanBucket.Put(key, b.Bytes())
24✔
2023
                }
24✔
2024
        }
2025

2026
        // Add the initiator status to the status provided. These statuses are
2027
        // set in addition to the broadcast status so that we do not need to
2028
        // migrate the original logic which does not store initiator.
2029
        if closer.IsLocal() {
92✔
2030
                status |= ChanStatusLocalCloseInitiator
43✔
2031
        } else {
52✔
2032
                status |= ChanStatusRemoteCloseInitiator
9✔
2033
        }
9✔
2034

2035
        return c.putChanStatus(status, putClosingTx)
49✔
2036
}
2037

2038
// BroadcastedCommitment retrieves the stored unilateral closing tx set during
2039
// MarkCommitmentBroadcasted. If not found ErrNoCloseTx is returned.
2040
func (c *OpenChannel) BroadcastedCommitment() (*wire.MsgTx, error) {
10✔
2041
        return c.getClosingTx(forceCloseTxKey)
10✔
2042
}
10✔
2043

2044
// BroadcastedCooperative retrieves the stored cooperative closing tx set during
2045
// MarkCoopBroadcasted. If not found ErrNoCloseTx is returned.
2046
func (c *OpenChannel) BroadcastedCooperative() (*wire.MsgTx, error) {
12✔
2047
        return c.getClosingTx(coopCloseTxKey)
12✔
2048
}
12✔
2049

2050
// getClosingTx is a helper method which returns the stored closing transaction
2051
// for key. The caller should use either the force or coop closing keys.
2052
func (c *OpenChannel) getClosingTx(key []byte) (*wire.MsgTx, error) {
19✔
2053
        var closeTx *wire.MsgTx
19✔
2054

19✔
2055
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
38✔
2056
                chanBucket, err := fetchChanBucket(
19✔
2057
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
19✔
2058
                )
19✔
2059
                switch err {
19✔
2060
                case nil:
19✔
2061
                case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
×
2062
                        return ErrNoCloseTx
×
2063
                default:
×
2064
                        return err
×
2065
                }
2066

2067
                bs := chanBucket.Get(key)
19✔
2068
                if bs == nil {
24✔
2069
                        return ErrNoCloseTx
5✔
2070
                }
5✔
2071
                r := bytes.NewReader(bs)
17✔
2072
                return ReadElement(r, &closeTx)
17✔
2073
        }, func() {
19✔
2074
                closeTx = nil
19✔
2075
        })
19✔
2076
        if err != nil {
24✔
2077
                return nil, err
5✔
2078
        }
5✔
2079

2080
        return closeTx, nil
17✔
2081
}
2082

2083
// putChanStatus appends the given status to the channel. fs is an optional
2084
// list of closures that are given the chanBucket in order to atomically add
2085
// extra information together with the new status.
2086
func (c *OpenChannel) putChanStatus(status ChannelStatus,
2087
        fs ...func(kvdb.RwBucket) error) error {
58✔
2088

58✔
2089
        if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
116✔
2090
                chanBucket, err := fetchChanBucketRw(
58✔
2091
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
58✔
2092
                )
58✔
2093
                if err != nil {
59✔
2094
                        return err
1✔
2095
                }
1✔
2096

2097
                channel, err := fetchOpenChannel(chanBucket, &c.FundingOutpoint)
58✔
2098
                if err != nil {
58✔
2099
                        return err
×
2100
                }
×
2101

2102
                // Add this status to the existing bitvector found in the DB.
2103
                status = channel.chanStatus | status
58✔
2104
                channel.chanStatus = status
58✔
2105

58✔
2106
                if err := putOpenChannel(chanBucket, channel); err != nil {
58✔
2107
                        return err
×
2108
                }
×
2109

2110
                for _, f := range fs {
111✔
2111
                        // Skip execution of nil closures.
53✔
2112
                        if f == nil {
81✔
2113
                                continue
28✔
2114
                        }
2115

2116
                        if err := f(chanBucket); err != nil {
28✔
2117
                                return err
×
2118
                        }
×
2119
                }
2120

2121
                return nil
58✔
2122
        }, func() {}); err != nil {
59✔
2123
                return err
1✔
2124
        }
1✔
2125

2126
        // Update the in-memory representation to keep it in sync with the DB.
2127
        c.chanStatus = status
58✔
2128

58✔
2129
        return nil
58✔
2130
}
2131

2132
func (c *OpenChannel) clearChanStatus(status ChannelStatus) error {
4✔
2133
        if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
8✔
2134
                chanBucket, err := fetchChanBucketRw(
4✔
2135
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
4✔
2136
                )
4✔
2137
                if err != nil {
4✔
2138
                        return err
×
2139
                }
×
2140

2141
                channel, err := fetchOpenChannel(chanBucket, &c.FundingOutpoint)
4✔
2142
                if err != nil {
4✔
2143
                        return err
×
2144
                }
×
2145

2146
                // Unset this bit in the bitvector on disk.
2147
                status = channel.chanStatus & ^status
4✔
2148
                channel.chanStatus = status
4✔
2149

4✔
2150
                return putOpenChannel(chanBucket, channel)
4✔
2151
        }, func() {}); err != nil {
4✔
2152
                return err
×
2153
        }
×
2154

2155
        // Update the in-memory representation to keep it in sync with the DB.
2156
        c.chanStatus = status
4✔
2157

4✔
2158
        return nil
4✔
2159
}
2160

2161
// putOpenChannel serializes, and stores the current state of the channel in its
2162
// entirety.
2163
func putOpenChannel(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
1,261✔
2164
        // First, we'll write out all the relatively static fields, that are
1,261✔
2165
        // decided upon initial channel creation.
1,261✔
2166
        if err := putChanInfo(chanBucket, channel); err != nil {
1,261✔
2167
                return fmt.Errorf("unable to store chan info: %w", err)
×
2168
        }
×
2169

2170
        // With the static channel info written out, we'll now write out the
2171
        // current commitment state for both parties.
2172
        if err := putChanCommitments(chanBucket, channel); err != nil {
1,261✔
2173
                return fmt.Errorf("unable to store chan commitments: %w", err)
×
2174
        }
×
2175

2176
        // Next, if this is a frozen channel, we'll add in the axillary
2177
        // information we need to store.
2178
        if channel.ChanType.IsFrozen() || channel.ChanType.HasLeaseExpiration() {
1,700✔
2179
                err := storeThawHeight(
439✔
2180
                        chanBucket, channel.ThawHeight,
439✔
2181
                )
439✔
2182
                if err != nil {
439✔
2183
                        return fmt.Errorf("unable to store thaw height: %w",
×
2184
                                err)
×
2185
                }
×
2186
        }
2187

2188
        // Finally, we'll write out the revocation state for both parties
2189
        // within a distinct key space.
2190
        if err := putChanRevocationState(chanBucket, channel); err != nil {
1,261✔
2191
                return fmt.Errorf("unable to store chan revocations: %w", err)
×
2192
        }
×
2193

2194
        return nil
1,261✔
2195
}
2196

2197
// fetchOpenChannel retrieves, and deserializes (including decrypting
2198
// sensitive) the complete channel currently active with the passed nodeID.
2199
func fetchOpenChannel(chanBucket kvdb.RBucket,
2200
        chanPoint *wire.OutPoint) (*OpenChannel, error) {
7,233✔
2201

7,233✔
2202
        channel := &OpenChannel{
7,233✔
2203
                FundingOutpoint: *chanPoint,
7,233✔
2204
        }
7,233✔
2205

7,233✔
2206
        // First, we'll read all the static information that changes less
7,233✔
2207
        // frequently from disk.
7,233✔
2208
        if err := fetchChanInfo(chanBucket, channel); err != nil {
7,233✔
2209
                return nil, fmt.Errorf("unable to fetch chan info: %w", err)
×
2210
        }
×
2211

2212
        // With the static information read, we'll now read the current
2213
        // commitment state for both sides of the channel.
2214
        if err := fetchChanCommitments(chanBucket, channel); err != nil {
7,233✔
2215
                return nil, fmt.Errorf("unable to fetch chan commitments: %w",
×
2216
                        err)
×
2217
        }
×
2218

2219
        // Next, if this is a frozen channel, we'll add in the axillary
2220
        // information we need to store.
2221
        if channel.ChanType.IsFrozen() || channel.ChanType.HasLeaseExpiration() {
7,581✔
2222
                thawHeight, err := fetchThawHeight(chanBucket)
348✔
2223
                if err != nil {
348✔
2224
                        return nil, fmt.Errorf("unable to store thaw "+
×
2225
                                "height: %v", err)
×
2226
                }
×
2227

2228
                channel.ThawHeight = thawHeight
348✔
2229
        }
2230

2231
        // Finally, we'll retrieve the current revocation state so we can
2232
        // properly
2233
        if err := fetchChanRevocationState(chanBucket, channel); err != nil {
7,233✔
2234
                return nil, fmt.Errorf("unable to fetch chan revocations: %w",
×
2235
                        err)
×
2236
        }
×
2237

2238
        channel.Packager = NewChannelPackager(channel.ShortChannelID)
7,233✔
2239

7,233✔
2240
        return channel, nil
7,233✔
2241
}
2242

2243
// SyncPending writes the contents of the channel to the database while it's in
2244
// the pending (waiting for funding confirmation) state. The IsPending flag
2245
// will be set to true. When the channel's funding transaction is confirmed,
2246
// the channel should be marked as "open" and the IsPending flag set to false.
2247
// Note that this function also creates a LinkNode relationship between this
2248
// newly created channel and a new LinkNode instance. This allows listing all
2249
// channels in the database globally, or according to the LinkNode they were
2250
// created with.
2251
//
2252
// TODO(roasbeef): addr param should eventually be an lnwire.NetAddress type
2253
// that includes service bits.
2254
func (c *OpenChannel) SyncPending(addr net.Addr, pendingHeight uint32) error {
889✔
2255
        c.Lock()
889✔
2256
        defer c.Unlock()
889✔
2257

889✔
2258
        c.FundingBroadcastHeight = pendingHeight
889✔
2259

889✔
2260
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
1,778✔
2261
                return syncNewChannel(tx, c, []net.Addr{addr})
889✔
2262
        }, func() {})
1,778✔
2263
}
2264

2265
// syncNewChannel will write the passed channel to disk, and also create a
2266
// LinkNode (if needed) for the channel peer.
2267
func syncNewChannel(tx kvdb.RwTx, c *OpenChannel, addrs []net.Addr) error {
890✔
2268
        // First, sync all the persistent channel state to disk.
890✔
2269
        if err := c.fullSync(tx); err != nil {
893✔
2270
                return err
3✔
2271
        }
3✔
2272

2273
        nodeInfoBucket, err := tx.CreateTopLevelBucket(nodeInfoBucket)
890✔
2274
        if err != nil {
890✔
2275
                return err
×
2276
        }
×
2277

2278
        // If a LinkNode for this identity public key already exists,
2279
        // then we can exit early.
2280
        nodePub := c.IdentityPub.SerializeCompressed()
890✔
2281
        if nodeInfoBucket.Get(nodePub) != nil {
1,036✔
2282
                return nil
146✔
2283
        }
146✔
2284

2285
        // Next, we need to establish a (possibly) new LinkNode relationship
2286
        // for this channel. The LinkNode metadata contains reachability,
2287
        // up-time, and service bits related information.
2288
        linkNode := NewLinkNode(
747✔
2289
                &LinkNodeDB{backend: c.Db.backend},
747✔
2290
                wire.MainNet, c.IdentityPub, addrs...,
747✔
2291
        )
747✔
2292

747✔
2293
        // TODO(roasbeef): do away with link node all together?
747✔
2294

747✔
2295
        return putLinkNode(nodeInfoBucket, linkNode)
747✔
2296
}
2297

2298
// UpdateCommitment updates the local commitment state. It locks in the pending
2299
// local updates that were received by us from the remote party. The commitment
2300
// state completely describes the balance state at this point in the commitment
2301
// chain. In addition to that, it persists all the remote log updates that we
2302
// have acked, but not signed a remote commitment for yet. These need to be
2303
// persisted to be able to produce a valid commit signature if a restart would
2304
// occur. This method its to be called when we revoke our prior commitment
2305
// state.
2306
//
2307
// A map is returned of all the htlc resolutions that were locked in this
2308
// commitment. Keys correspond to htlc indices and values indicate whether the
2309
// htlc was settled or failed.
2310
func (c *OpenChannel) UpdateCommitment(newCommitment *ChannelCommitment,
2311
        unsignedAckedUpdates []LogUpdate) (map[uint64]bool, error) {
2,026✔
2312

2,026✔
2313
        c.Lock()
2,026✔
2314
        defer c.Unlock()
2,026✔
2315

2,026✔
2316
        // If this is a restored channel, then we want to avoid mutating the
2,026✔
2317
        // state as all, as it's impossible to do so in a protocol compliant
2,026✔
2318
        // manner.
2,026✔
2319
        if c.hasChanStatus(ChanStatusRestored) {
2,027✔
2320
                return nil, ErrNoRestoredChannelMutation
1✔
2321
        }
1✔
2322

2323
        var finalHtlcs = make(map[uint64]bool)
2,025✔
2324

2,025✔
2325
        err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
4,050✔
2326
                chanBucket, err := fetchChanBucketRw(
2,025✔
2327
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
2,025✔
2328
                )
2,025✔
2329
                if err != nil {
2,025✔
2330
                        return err
×
2331
                }
×
2332

2333
                // If the channel is marked as borked, then for safety reasons,
2334
                // we shouldn't attempt any further updates.
2335
                isBorked, err := c.isBorked(chanBucket)
2,025✔
2336
                if err != nil {
2,025✔
2337
                        return err
×
2338
                }
×
2339
                if isBorked {
2,026✔
2340
                        return ErrChanBorked
1✔
2341
                }
1✔
2342

2343
                if err = putChanInfo(chanBucket, c); err != nil {
2,024✔
2344
                        return fmt.Errorf("unable to store chan info: %w", err)
×
2345
                }
×
2346

2347
                // With the proper bucket fetched, we'll now write the latest
2348
                // commitment state to disk for the target party.
2349
                err = putChanCommitment(
2,024✔
2350
                        chanBucket, newCommitment, true,
2,024✔
2351
                )
2,024✔
2352
                if err != nil {
2,024✔
2353
                        return fmt.Errorf("unable to store chan "+
×
2354
                                "revocations: %v", err)
×
2355
                }
×
2356

2357
                // Persist unsigned but acked remote updates that need to be
2358
                // restored after a restart.
2359
                var b bytes.Buffer
2,024✔
2360
                err = serializeLogUpdates(&b, unsignedAckedUpdates)
2,024✔
2361
                if err != nil {
2,024✔
2362
                        return err
×
2363
                }
×
2364

2365
                err = chanBucket.Put(unsignedAckedUpdatesKey, b.Bytes())
2,024✔
2366
                if err != nil {
2,024✔
2367
                        return fmt.Errorf("unable to store dangline remote "+
×
2368
                                "updates: %v", err)
×
2369
                }
×
2370

2371
                // Since we have just sent the counterparty a revocation, store true
2372
                // under lastWasRevokeKey.
2373
                var b2 bytes.Buffer
2,024✔
2374
                if err := WriteElements(&b2, true); err != nil {
2,024✔
2375
                        return err
×
2376
                }
×
2377

2378
                if err := chanBucket.Put(lastWasRevokeKey, b2.Bytes()); err != nil {
2,024✔
2379
                        return err
×
2380
                }
×
2381

2382
                // Persist the remote unsigned local updates that are not included
2383
                // in our new commitment.
2384
                updateBytes := chanBucket.Get(remoteUnsignedLocalUpdatesKey)
2,024✔
2385
                if updateBytes == nil {
2,539✔
2386
                        return nil
515✔
2387
                }
515✔
2388

2389
                r := bytes.NewReader(updateBytes)
1,512✔
2390
                updates, err := deserializeLogUpdates(r)
1,512✔
2391
                if err != nil {
1,512✔
2392
                        return err
×
2393
                }
×
2394

2395
                // Get the bucket where settled htlcs are recorded if the user
2396
                // opted in to storing this information.
2397
                var finalHtlcsBucket kvdb.RwBucket
1,512✔
2398
                if c.Db.parent.storeFinalHtlcResolutions {
1,516✔
2399
                        bucket, err := fetchFinalHtlcsBucketRw(
4✔
2400
                                tx, c.ShortChannelID,
4✔
2401
                        )
4✔
2402
                        if err != nil {
4✔
2403
                                return err
×
2404
                        }
×
2405

2406
                        finalHtlcsBucket = bucket
4✔
2407
                }
2408

2409
                var unsignedUpdates []LogUpdate
1,512✔
2410
                for _, upd := range updates {
1,942✔
2411
                        // Gather updates that are not on our local commitment.
430✔
2412
                        if upd.LogIndex >= newCommitment.LocalLogIndex {
430✔
2413
                                unsignedUpdates = append(unsignedUpdates, upd)
×
2414

×
2415
                                continue
×
2416
                        }
2417

2418
                        // The update was locked in. If the update was a
2419
                        // resolution, then store it in the database.
2420
                        err := processFinalHtlc(
430✔
2421
                                finalHtlcsBucket, upd, finalHtlcs,
430✔
2422
                        )
430✔
2423
                        if err != nil {
430✔
2424
                                return err
×
2425
                        }
×
2426
                }
2427

2428
                var b3 bytes.Buffer
1,512✔
2429
                err = serializeLogUpdates(&b3, unsignedUpdates)
1,512✔
2430
                if err != nil {
1,512✔
2431
                        return fmt.Errorf("unable to serialize log updates: %w",
×
2432
                                err)
×
2433
                }
×
2434

2435
                err = chanBucket.Put(remoteUnsignedLocalUpdatesKey, b3.Bytes())
1,512✔
2436
                if err != nil {
1,512✔
2437
                        return fmt.Errorf("unable to restore chanbucket: %w",
×
2438
                                err)
×
2439
                }
×
2440

2441
                return nil
1,512✔
2442
        }, func() {
2,025✔
2443
                finalHtlcs = make(map[uint64]bool)
2,025✔
2444
        })
2,025✔
2445
        if err != nil {
2,026✔
2446
                return nil, err
1✔
2447
        }
1✔
2448

2449
        c.LocalCommitment = *newCommitment
2,024✔
2450

2,024✔
2451
        return finalHtlcs, nil
2,024✔
2452
}
2453

2454
// processFinalHtlc stores a final htlc outcome in the database if signaled via
2455
// the supplied log update. An in-memory htlcs map is updated too.
2456
func processFinalHtlc(finalHtlcsBucket walletdb.ReadWriteBucket, upd LogUpdate,
2457
        finalHtlcs map[uint64]bool) error {
430✔
2458

430✔
2459
        var (
430✔
2460
                settled bool
430✔
2461
                id      uint64
430✔
2462
        )
430✔
2463

430✔
2464
        switch msg := upd.UpdateMsg.(type) {
430✔
2465
        case *lnwire.UpdateFulfillHTLC:
288✔
2466
                settled = true
288✔
2467
                id = msg.ID
288✔
2468

2469
        case *lnwire.UpdateFailHTLC:
134✔
2470
                settled = false
134✔
2471
                id = msg.ID
134✔
2472

2473
        case *lnwire.UpdateFailMalformedHTLC:
6✔
2474
                settled = false
6✔
2475
                id = msg.ID
6✔
2476

2477
        default:
8✔
2478
                return nil
8✔
2479
        }
2480

2481
        // Store the final resolution in the database if a bucket is provided.
2482
        if finalHtlcsBucket != nil {
426✔
2483
                err := putFinalHtlc(
4✔
2484
                        finalHtlcsBucket, id,
4✔
2485
                        FinalHtlcInfo{
4✔
2486
                                Settled:  settled,
4✔
2487
                                Offchain: true,
4✔
2488
                        },
4✔
2489
                )
4✔
2490
                if err != nil {
4✔
2491
                        return err
×
2492
                }
×
2493
        }
2494

2495
        finalHtlcs[id] = settled
422✔
2496

422✔
2497
        return nil
422✔
2498
}
2499

2500
// ActiveHtlcs returns a slice of HTLC's which are currently active on *both*
2501
// commitment transactions.
2502
func (c *OpenChannel) ActiveHtlcs() []HTLC {
1,644✔
2503
        c.RLock()
1,644✔
2504
        defer c.RUnlock()
1,644✔
2505

1,644✔
2506
        // We'll only return HTLC's that are locked into *both* commitment
1,644✔
2507
        // transactions. So we'll iterate through their set of HTLC's to note
1,644✔
2508
        // which ones are present on their commitment.
1,644✔
2509
        remoteHtlcs := make(map[[32]byte]struct{})
1,644✔
2510
        for _, htlc := range c.RemoteCommitment.Htlcs {
8,096✔
2511
                log.Tracef("RemoteCommitment has htlc: id=%v, update=%v "+
6,452✔
2512
                        "incoming=%v", htlc.HtlcIndex, htlc.LogIndex,
6,452✔
2513
                        htlc.Incoming)
6,452✔
2514

6,452✔
2515
                onionHash := sha256.Sum256(htlc.OnionBlob[:])
6,452✔
2516
                remoteHtlcs[onionHash] = struct{}{}
6,452✔
2517
        }
6,452✔
2518

2519
        // Now that we know which HTLC's they have, we'll only mark the HTLC's
2520
        // as active if *we* know them as well.
2521
        activeHtlcs := make([]HTLC, 0, len(remoteHtlcs))
1,644✔
2522
        for _, htlc := range c.LocalCommitment.Htlcs {
8,100✔
2523
                log.Tracef("LocalCommitment has htlc: id=%v, update=%v "+
6,456✔
2524
                        "incoming=%v", htlc.HtlcIndex, htlc.LogIndex,
6,456✔
2525
                        htlc.Incoming)
6,456✔
2526

6,456✔
2527
                onionHash := sha256.Sum256(htlc.OnionBlob[:])
6,456✔
2528
                if _, ok := remoteHtlcs[onionHash]; !ok {
6,734✔
2529
                        log.Tracef("Skipped htlc due to onion mismatched: "+
278✔
2530
                                "id=%v, update=%v incoming=%v",
278✔
2531
                                htlc.HtlcIndex, htlc.LogIndex, htlc.Incoming)
278✔
2532

278✔
2533
                        continue
278✔
2534
                }
2535

2536
                activeHtlcs = append(activeHtlcs, htlc)
6,181✔
2537
        }
2538

2539
        return activeHtlcs
1,644✔
2540
}
2541

2542
// HTLC is the on-disk representation of a hash time-locked contract. HTLCs are
2543
// contained within ChannelDeltas which encode the current state of the
2544
// commitment between state updates.
2545
//
2546
// TODO(roasbeef): save space by using smaller ints at tail end?
2547
type HTLC struct {
2548
        // TODO(yy): can embed an HTLCEntry here.
2549

2550
        // Signature is the signature for the second level covenant transaction
2551
        // for this HTLC. The second level transaction is a timeout tx in the
2552
        // case that this is an outgoing HTLC, and a success tx in the case
2553
        // that this is an incoming HTLC.
2554
        //
2555
        // TODO(roasbeef): make [64]byte instead?
2556
        Signature []byte
2557

2558
        // RHash is the payment hash of the HTLC.
2559
        RHash [32]byte
2560

2561
        // Amt is the amount of milli-satoshis this HTLC escrows.
2562
        Amt lnwire.MilliSatoshi
2563

2564
        // RefundTimeout is the absolute timeout on the HTLC that the sender
2565
        // must wait before reclaiming the funds in limbo.
2566
        RefundTimeout uint32
2567

2568
        // OutputIndex is the output index for this particular HTLC output
2569
        // within the commitment transaction.
2570
        OutputIndex int32
2571

2572
        // Incoming denotes whether we're the receiver or the sender of this
2573
        // HTLC.
2574
        Incoming bool
2575

2576
        // OnionBlob is an opaque blob which is used to complete multi-hop
2577
        // routing.
2578
        OnionBlob [lnwire.OnionPacketSize]byte
2579

2580
        // HtlcIndex is the HTLC counter index of this active, outstanding
2581
        // HTLC. This differs from the LogIndex, as the HtlcIndex is only
2582
        // incremented for each offered HTLC, while they LogIndex is
2583
        // incremented for each update (includes settle+fail).
2584
        HtlcIndex uint64
2585

2586
        // LogIndex is the cumulative log index of this HTLC. This differs
2587
        // from the HtlcIndex as this will be incremented for each new log
2588
        // update added.
2589
        LogIndex uint64
2590

2591
        // ExtraData contains any additional information that was transmitted
2592
        // with the HTLC via TLVs. This data *must* already be encoded as a
2593
        // TLV stream, and may be empty. The length of this data is naturally
2594
        // limited by the space available to TLVs in update_add_htlc:
2595
        // = 65535 bytes (bolt 8 maximum message size):
2596
        // - 2 bytes (bolt 1 message_type)
2597
        // - 32 bytes (channel_id)
2598
        // - 8 bytes (id)
2599
        // - 8 bytes (amount_msat)
2600
        // - 32 bytes (payment_hash)
2601
        // - 4 bytes (cltv_expiry)
2602
        // - 1366 bytes (onion_routing_packet)
2603
        // = 64083 bytes maximum possible TLV stream
2604
        //
2605
        // Note that this extra data is stored inline with the OnionBlob for
2606
        // legacy reasons, see serialization/deserialization functions for
2607
        // detail.
2608
        ExtraData lnwire.ExtraOpaqueData
2609

2610
        // BlindingPoint is an optional blinding point included with the HTLC.
2611
        //
2612
        // Note: this field is not a part of on-disk representation of the
2613
        // HTLC. It is stored in the ExtraData field, which is used to store
2614
        // a TLV stream of additional information associated with the HTLC.
2615
        BlindingPoint lnwire.BlindingPointRecord
2616

2617
        // CustomRecords is a set of custom TLV records that are associated with
2618
        // this HTLC. These records are used to store additional information
2619
        // about the HTLC that is not part of the standard HTLC fields. This
2620
        // field is encoded within the ExtraData field.
2621
        CustomRecords lnwire.CustomRecords
2622
}
2623

2624
// serializeExtraData encodes a TLV stream of extra data to be stored with a
2625
// HTLC. It uses the update_add_htlc TLV types, because this is where extra
2626
// data is passed with a HTLC. At present blinding points are the only extra
2627
// data that we will store, and the function is a no-op if a nil blinding
2628
// point is provided.
2629
//
2630
// This function MUST be called to persist all HTLC values when they are
2631
// serialized.
2632
func (h *HTLC) serializeExtraData() error {
28,046✔
2633
        var records []tlv.RecordProducer
28,046✔
2634
        h.BlindingPoint.WhenSome(func(b tlv.RecordT[lnwire.BlindingPointTlvType,
28,046✔
2635
                *btcec.PublicKey]) {
28,053✔
2636

7✔
2637
                records = append(records, &b)
7✔
2638
        })
7✔
2639

2640
        records, err := h.CustomRecords.ExtendRecordProducers(records)
28,046✔
2641
        if err != nil {
28,046✔
2642
                return err
×
2643
        }
×
2644

2645
        return h.ExtraData.PackRecords(records...)
28,046✔
2646
}
2647

2648
// deserializeExtraData extracts TLVs from the extra data persisted for the
2649
// htlc and populates values in the struct accordingly.
2650
//
2651
// This function MUST be called to populate the struct properly when HTLCs
2652
// are deserialized.
2653
func (h *HTLC) deserializeExtraData() error {
63,588✔
2654
        if len(h.ExtraData) == 0 {
125,488✔
2655
                return nil
61,900✔
2656
        }
61,900✔
2657

2658
        blindingPoint := h.BlindingPoint.Zero()
1,691✔
2659
        tlvMap, err := h.ExtraData.ExtractRecords(&blindingPoint)
1,691✔
2660
        if err != nil {
1,691✔
2661
                return err
×
2662
        }
×
2663

2664
        if val, ok := tlvMap[h.BlindingPoint.TlvType()]; ok && val == nil {
1,698✔
2665
                h.BlindingPoint = tlv.SomeRecordT(blindingPoint)
7✔
2666

7✔
2667
                // Remove the entry from the TLV map. Anything left in the map
7✔
2668
                // will be included in the custom records field.
7✔
2669
                delete(tlvMap, h.BlindingPoint.TlvType())
7✔
2670
        }
7✔
2671

2672
        // Set the custom records field to the remaining TLV records.
2673
        customRecords, err := lnwire.NewCustomRecords(tlvMap)
1,691✔
2674
        if err != nil {
1,691✔
2675
                return err
×
2676
        }
×
2677
        h.CustomRecords = customRecords
1,691✔
2678

1,691✔
2679
        return nil
1,691✔
2680
}
2681

2682
// SerializeHtlcs writes out the passed set of HTLC's into the passed writer
2683
// using the current default on-disk serialization format.
2684
//
2685
// This inline serialization has been extended to allow storage of extra data
2686
// associated with a HTLC in the following way:
2687
//   - The known-length onion blob (1366 bytes) is serialized as var bytes in
2688
//     WriteElements (ie, the length 1366 was written, followed by the 1366
2689
//     onion bytes).
2690
//   - To include extra data, we append any extra data present to this one
2691
//     variable length of data. Since we know that the onion is strictly 1366
2692
//     bytes, any length after that should be considered to be extra data.
2693
//
2694
// NOTE: This API is NOT stable, the on-disk format will likely change in the
2695
// future.
2696
func SerializeHtlcs(b io.Writer, htlcs ...HTLC) error {
8,605✔
2697
        numHtlcs := uint16(len(htlcs))
8,605✔
2698
        if err := WriteElement(b, numHtlcs); err != nil {
8,605✔
2699
                return err
×
2700
        }
×
2701

2702
        for _, htlc := range htlcs {
36,651✔
2703
                // Populate TLV stream for any additional fields contained
28,046✔
2704
                // in the TLV.
28,046✔
2705
                if err := htlc.serializeExtraData(); err != nil {
28,046✔
2706
                        return err
×
2707
                }
×
2708

2709
                // The onion blob and hltc data are stored as a single var
2710
                // bytes blob.
2711
                onionAndExtraData := make(
28,046✔
2712
                        []byte, lnwire.OnionPacketSize+len(htlc.ExtraData),
28,046✔
2713
                )
28,046✔
2714
                copy(onionAndExtraData, htlc.OnionBlob[:])
28,046✔
2715
                copy(onionAndExtraData[lnwire.OnionPacketSize:], htlc.ExtraData)
28,046✔
2716

28,046✔
2717
                if err := WriteElements(b,
28,046✔
2718
                        htlc.Signature, htlc.RHash, htlc.Amt, htlc.RefundTimeout,
28,046✔
2719
                        htlc.OutputIndex, htlc.Incoming, onionAndExtraData,
28,046✔
2720
                        htlc.HtlcIndex, htlc.LogIndex,
28,046✔
2721
                ); err != nil {
28,046✔
2722
                        return err
×
2723
                }
×
2724
        }
2725

2726
        return nil
8,605✔
2727
}
2728

2729
// DeserializeHtlcs attempts to read out a slice of HTLC's from the passed
2730
// io.Reader. The bytes within the passed reader MUST have been previously
2731
// written to using the SerializeHtlcs function.
2732
//
2733
// This inline deserialization has been extended to allow storage of extra data
2734
// associated with a HTLC in the following way:
2735
//   - The known-length onion blob (1366 bytes) and any additional data present
2736
//     are read out as a single blob of variable byte data.
2737
//   - They are stored like this to take advantage of the variable space
2738
//     available for extension without migration (see SerializeHtlcs).
2739
//   - The first 1366 bytes are interpreted as the onion blob, and any remaining
2740
//     bytes as extra HTLC data.
2741
//   - This extra HTLC data is expected to be serialized as a TLV stream, and
2742
//     its parsing is left to higher layers.
2743
//
2744
// NOTE: This API is NOT stable, the on-disk format will likely change in the
2745
// future.
2746
func DeserializeHtlcs(r io.Reader) ([]HTLC, error) {
16,582✔
2747
        var numHtlcs uint16
16,582✔
2748
        if err := ReadElement(r, &numHtlcs); err != nil {
16,582✔
2749
                return nil, err
×
2750
        }
×
2751

2752
        var htlcs []HTLC
16,582✔
2753
        if numHtlcs == 0 {
23,755✔
2754
                return htlcs, nil
7,173✔
2755
        }
7,173✔
2756

2757
        htlcs = make([]HTLC, numHtlcs)
9,412✔
2758
        for i := uint16(0); i < numHtlcs; i++ {
73,001✔
2759
                var onionAndExtraData []byte
63,589✔
2760
                if err := ReadElements(r,
63,589✔
2761
                        &htlcs[i].Signature, &htlcs[i].RHash, &htlcs[i].Amt,
63,589✔
2762
                        &htlcs[i].RefundTimeout, &htlcs[i].OutputIndex,
63,589✔
2763
                        &htlcs[i].Incoming, &onionAndExtraData,
63,589✔
2764
                        &htlcs[i].HtlcIndex, &htlcs[i].LogIndex,
63,589✔
2765
                ); err != nil {
63,589✔
2766
                        return htlcs, err
×
2767
                }
×
2768

2769
                // Sanity check that we have at least the onion blob size we
2770
                // expect.
2771
                if len(onionAndExtraData) < lnwire.OnionPacketSize {
63,590✔
2772
                        return nil, ErrOnionBlobLength
1✔
2773
                }
1✔
2774

2775
                // First OnionPacketSize bytes are our fixed length onion
2776
                // packet.
2777
                copy(
63,588✔
2778
                        htlcs[i].OnionBlob[:],
63,588✔
2779
                        onionAndExtraData[0:lnwire.OnionPacketSize],
63,588✔
2780
                )
63,588✔
2781

63,588✔
2782
                // Any additional bytes belong to extra data. ExtraDataLen
63,588✔
2783
                // will be >= 0, because we know that we always have a fixed
63,588✔
2784
                // length onion packet.
63,588✔
2785
                extraDataLen := len(onionAndExtraData) - lnwire.OnionPacketSize
63,588✔
2786
                if extraDataLen > 0 {
65,279✔
2787
                        htlcs[i].ExtraData = make([]byte, extraDataLen)
1,691✔
2788

1,691✔
2789
                        copy(
1,691✔
2790
                                htlcs[i].ExtraData,
1,691✔
2791
                                onionAndExtraData[lnwire.OnionPacketSize:],
1,691✔
2792
                        )
1,691✔
2793
                }
1,691✔
2794

2795
                // Finally, deserialize any TLVs contained in that extra data
2796
                // if they are present.
2797
                if err := htlcs[i].deserializeExtraData(); err != nil {
63,588✔
2798
                        return nil, err
×
2799
                }
×
2800
        }
2801

2802
        return htlcs, nil
9,411✔
2803
}
2804

2805
// Copy returns a full copy of the target HTLC.
2806
func (h *HTLC) Copy() HTLC {
272✔
2807
        clone := HTLC{
272✔
2808
                Incoming:      h.Incoming,
272✔
2809
                Amt:           h.Amt,
272✔
2810
                RefundTimeout: h.RefundTimeout,
272✔
2811
                OutputIndex:   h.OutputIndex,
272✔
2812
        }
272✔
2813
        copy(clone.Signature[:], h.Signature)
272✔
2814
        copy(clone.RHash[:], h.RHash[:])
272✔
2815
        copy(clone.ExtraData, h.ExtraData)
272✔
2816
        clone.BlindingPoint = h.BlindingPoint
272✔
2817
        clone.CustomRecords = h.CustomRecords.Copy()
272✔
2818

272✔
2819
        return clone
272✔
2820
}
272✔
2821

2822
// LogUpdate represents a pending update to the remote commitment chain. The
2823
// log update may be an add, fail, or settle entry. We maintain this data in
2824
// order to be able to properly retransmit our proposed state if necessary.
2825
type LogUpdate struct {
2826
        // LogIndex is the log index of this proposed commitment update entry.
2827
        LogIndex uint64
2828

2829
        // UpdateMsg is the update message that was included within our
2830
        // local update log. The LogIndex value denotes the log index of this
2831
        // update which will be used when restoring our local update log if
2832
        // we're left with a dangling update on restart.
2833
        UpdateMsg lnwire.Message
2834
}
2835

2836
// serializeLogUpdate writes a log update to the provided io.Writer.
2837
func serializeLogUpdate(w io.Writer, l *LogUpdate) error {
1,248✔
2838
        return WriteElements(w, l.LogIndex, l.UpdateMsg)
1,248✔
2839
}
1,248✔
2840

2841
// deserializeLogUpdate reads a log update from the provided io.Reader.
2842
func deserializeLogUpdate(r io.Reader) (*LogUpdate, error) {
86✔
2843
        l := &LogUpdate{}
86✔
2844
        if err := ReadElements(r, &l.LogIndex, &l.UpdateMsg); err != nil {
86✔
2845
                return nil, err
×
2846
        }
×
2847

2848
        return l, nil
86✔
2849
}
2850

2851
// CommitDiff represents the delta needed to apply the state transition between
2852
// two subsequent commitment states. Given state N and state N+1, one is able
2853
// to apply the set of messages contained within the CommitDiff to N to arrive
2854
// at state N+1. Each time a new commitment is extended, we'll write a new
2855
// commitment (along with the full commitment state) to disk so we can
2856
// re-transmit the state in the case of a connection loss or message drop.
2857
type CommitDiff struct {
2858
        // ChannelCommitment is the full commitment state that one would arrive
2859
        // at by applying the set of messages contained in the UpdateDiff to
2860
        // the prior accepted commitment.
2861
        Commitment ChannelCommitment
2862

2863
        // LogUpdates is the set of messages sent prior to the commitment state
2864
        // transition in question. Upon reconnection, if we detect that they
2865
        // don't have the commitment, then we re-send this along with the
2866
        // proper signature.
2867
        LogUpdates []LogUpdate
2868

2869
        // CommitSig is the exact CommitSig message that should be sent after
2870
        // the set of LogUpdates above has been retransmitted. The signatures
2871
        // within this message should properly cover the new commitment state
2872
        // and also the HTLC's within the new commitment state.
2873
        CommitSig *lnwire.CommitSig
2874

2875
        // OpenedCircuitKeys is a set of unique identifiers for any downstream
2876
        // Add packets included in this commitment txn. After a restart, this
2877
        // set of htlcs is acked from the link's incoming mailbox to ensure
2878
        // there isn't an attempt to re-add them to this commitment txn.
2879
        OpenedCircuitKeys []models.CircuitKey
2880

2881
        // ClosedCircuitKeys records the unique identifiers for any settle/fail
2882
        // packets that were resolved by this commitment txn. After a restart,
2883
        // this is used to ensure those circuits are removed from the circuit
2884
        // map, and the downstream packets in the link's mailbox are removed.
2885
        ClosedCircuitKeys []models.CircuitKey
2886

2887
        // AddAcks specifies the locations (commit height, pkg index) of any
2888
        // Adds that were failed/settled in this commit diff. This will ack
2889
        // entries in *this* channel's forwarding packages.
2890
        //
2891
        // NOTE: This value is not serialized, it is used to atomically mark the
2892
        // resolution of adds, such that they will not be reprocessed after a
2893
        // restart.
2894
        AddAcks []AddRef
2895

2896
        // SettleFailAcks specifies the locations (chan id, commit height, pkg
2897
        // index) of any Settles or Fails that were locked into this commit
2898
        // diff, and originate from *another* channel, i.e. the outgoing link.
2899
        //
2900
        // NOTE: This value is not serialized, it is used to atomically acks
2901
        // settles and fails from the forwarding packages of other channels,
2902
        // such that they will not be reforwarded internally after a restart.
2903
        SettleFailAcks []SettleFailRef
2904
}
2905

2906
// serializeLogUpdates serializes provided list of updates to a stream.
2907
func serializeLogUpdates(w io.Writer, logUpdates []LogUpdate) error {
9,140✔
2908
        numUpdates := uint16(len(logUpdates))
9,140✔
2909
        if err := binary.Write(w, byteOrder, numUpdates); err != nil {
9,140✔
2910
                return err
×
2911
        }
×
2912

2913
        for _, diff := range logUpdates {
12,925✔
2914
                err := WriteElements(w, diff.LogIndex, diff.UpdateMsg)
3,785✔
2915
                if err != nil {
3,785✔
2916
                        return err
×
2917
                }
×
2918
        }
2919

2920
        return nil
9,140✔
2921
}
2922

2923
// deserializeLogUpdates deserializes a list of updates from a stream.
2924
func deserializeLogUpdates(r io.Reader) ([]LogUpdate, error) {
5,456✔
2925
        var numUpdates uint16
5,456✔
2926
        if err := binary.Read(r, byteOrder, &numUpdates); err != nil {
5,456✔
2927
                return nil, err
×
2928
        }
×
2929

2930
        logUpdates := make([]LogUpdate, numUpdates)
5,456✔
2931
        for i := 0; i < int(numUpdates); i++ {
8,857✔
2932
                err := ReadElements(r,
3,401✔
2933
                        &logUpdates[i].LogIndex, &logUpdates[i].UpdateMsg,
3,401✔
2934
                )
3,401✔
2935
                if err != nil {
3,401✔
2936
                        return nil, err
×
2937
                }
×
2938
        }
2939
        return logUpdates, nil
5,456✔
2940
}
2941

2942
func serializeCommitDiff(w io.Writer, diff *CommitDiff) error { // nolint: dupl
2,070✔
2943
        if err := serializeChanCommit(w, &diff.Commitment); err != nil {
2,070✔
2944
                return err
×
2945
        }
×
2946

2947
        if err := WriteElements(w, diff.CommitSig); err != nil {
2,070✔
2948
                return err
×
2949
        }
×
2950

2951
        if err := serializeLogUpdates(w, diff.LogUpdates); err != nil {
2,070✔
2952
                return err
×
2953
        }
×
2954

2955
        numOpenRefs := uint16(len(diff.OpenedCircuitKeys))
2,070✔
2956
        if err := binary.Write(w, byteOrder, numOpenRefs); err != nil {
2,070✔
2957
                return err
×
2958
        }
×
2959

2960
        for _, openRef := range diff.OpenedCircuitKeys {
2,534✔
2961
                err := WriteElements(w, openRef.ChanID, openRef.HtlcID)
464✔
2962
                if err != nil {
464✔
2963
                        return err
×
2964
                }
×
2965
        }
2966

2967
        numClosedRefs := uint16(len(diff.ClosedCircuitKeys))
2,070✔
2968
        if err := binary.Write(w, byteOrder, numClosedRefs); err != nil {
2,070✔
2969
                return err
×
2970
        }
×
2971

2972
        for _, closedRef := range diff.ClosedCircuitKeys {
2,112✔
2973
                err := WriteElements(w, closedRef.ChanID, closedRef.HtlcID)
42✔
2974
                if err != nil {
42✔
2975
                        return err
×
2976
                }
×
2977
        }
2978

2979
        // We'll also encode the commit aux data stream here. We do this here
2980
        // rather than above (at the call to serializeChanCommit), to ensure
2981
        // backwards compat for reads to existing non-custom channels.
2982
        auxData := diff.Commitment.extractTlvData()
2,070✔
2983
        if err := auxData.encode(w); err != nil {
2,070✔
2984
                return fmt.Errorf("unable to write aux data: %w", err)
×
2985
        }
×
2986

2987
        return nil
2,070✔
2988
}
2989

2990
func deserializeCommitDiff(r io.Reader) (*CommitDiff, error) {
2,063✔
2991
        var (
2,063✔
2992
                d   CommitDiff
2,063✔
2993
                err error
2,063✔
2994
        )
2,063✔
2995

2,063✔
2996
        d.Commitment, err = deserializeChanCommit(r)
2,063✔
2997
        if err != nil {
2,063✔
2998
                return nil, err
×
2999
        }
×
3000

3001
        var msg lnwire.Message
2,063✔
3002
        if err := ReadElements(r, &msg); err != nil {
2,063✔
3003
                return nil, err
×
3004
        }
×
3005
        commitSig, ok := msg.(*lnwire.CommitSig)
2,063✔
3006
        if !ok {
2,063✔
3007
                return nil, fmt.Errorf("expected lnwire.CommitSig, instead "+
×
3008
                        "read: %T", msg)
×
3009
        }
×
3010
        d.CommitSig = commitSig
2,063✔
3011

2,063✔
3012
        d.LogUpdates, err = deserializeLogUpdates(r)
2,063✔
3013
        if err != nil {
2,063✔
3014
                return nil, err
×
3015
        }
×
3016

3017
        var numOpenRefs uint16
2,063✔
3018
        if err := binary.Read(r, byteOrder, &numOpenRefs); err != nil {
2,063✔
3019
                return nil, err
×
3020
        }
×
3021

3022
        d.OpenedCircuitKeys = make([]models.CircuitKey, numOpenRefs)
2,063✔
3023
        for i := 0; i < int(numOpenRefs); i++ {
2,554✔
3024
                err := ReadElements(r,
491✔
3025
                        &d.OpenedCircuitKeys[i].ChanID,
491✔
3026
                        &d.OpenedCircuitKeys[i].HtlcID)
491✔
3027
                if err != nil {
491✔
3028
                        return nil, err
×
3029
                }
×
3030
        }
3031

3032
        var numClosedRefs uint16
2,063✔
3033
        if err := binary.Read(r, byteOrder, &numClosedRefs); err != nil {
2,063✔
3034
                return nil, err
×
3035
        }
×
3036

3037
        d.ClosedCircuitKeys = make([]models.CircuitKey, numClosedRefs)
2,063✔
3038
        for i := 0; i < int(numClosedRefs); i++ {
2,102✔
3039
                err := ReadElements(r,
39✔
3040
                        &d.ClosedCircuitKeys[i].ChanID,
39✔
3041
                        &d.ClosedCircuitKeys[i].HtlcID)
39✔
3042
                if err != nil {
39✔
3043
                        return nil, err
×
3044
                }
×
3045
        }
3046

3047
        // As a final step, we'll read out any aux commit data that we have at
3048
        // the end of this byte stream. We do this here to ensure backward
3049
        // compatibility, as otherwise we risk erroneously reading into the
3050
        // wrong field.
3051
        var auxData commitTlvData
2,063✔
3052
        if err := auxData.decode(r); err != nil {
2,063✔
3053
                return nil, fmt.Errorf("unable to decode aux data: %w", err)
×
3054
        }
×
3055

3056
        d.Commitment.amendTlvData(auxData)
2,063✔
3057

2,063✔
3058
        return &d, nil
2,063✔
3059
}
3060

3061
// AppendRemoteCommitChain appends a new CommitDiff to the end of the
3062
// commitment chain for the remote party. This method is to be used once we
3063
// have prepared a new commitment state for the remote party, but before we
3064
// transmit it to the remote party. The contents of the argument should be
3065
// sufficient to retransmit the updates and signature needed to reconstruct the
3066
// state in full, in the case that we need to retransmit.
3067
func (c *OpenChannel) AppendRemoteCommitChain(diff *CommitDiff) error {
2,072✔
3068
        c.Lock()
2,072✔
3069
        defer c.Unlock()
2,072✔
3070

2,072✔
3071
        // If this is a restored channel, then we want to avoid mutating the
2,072✔
3072
        // state at all, as it's impossible to do so in a protocol compliant
2,072✔
3073
        // manner.
2,072✔
3074
        if c.hasChanStatus(ChanStatusRestored) {
2,073✔
3075
                return ErrNoRestoredChannelMutation
1✔
3076
        }
1✔
3077

3078
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
4,142✔
3079
                // First, we'll grab the writable bucket where this channel's
2,071✔
3080
                // data resides.
2,071✔
3081
                chanBucket, err := fetchChanBucketRw(
2,071✔
3082
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
2,071✔
3083
                )
2,071✔
3084
                if err != nil {
2,071✔
3085
                        return err
×
3086
                }
×
3087

3088
                // If the channel is marked as borked, then for safety reasons,
3089
                // we shouldn't attempt any further updates.
3090
                isBorked, err := c.isBorked(chanBucket)
2,071✔
3091
                if err != nil {
2,071✔
3092
                        return err
×
3093
                }
×
3094
                if isBorked {
2,072✔
3095
                        return ErrChanBorked
1✔
3096
                }
1✔
3097

3098
                // Any outgoing settles and fails necessarily have a
3099
                // corresponding adds in this channel's forwarding packages.
3100
                // Mark all of these as being fully processed in our forwarding
3101
                // package, which prevents us from reprocessing them after
3102
                // startup.
3103
                err = c.Packager.AckAddHtlcs(tx, diff.AddAcks...)
2,070✔
3104
                if err != nil {
2,070✔
3105
                        return err
×
3106
                }
×
3107

3108
                // Additionally, we ack from any fails or settles that are
3109
                // persisted in another channel's forwarding package. This
3110
                // prevents the same fails and settles from being retransmitted
3111
                // after restarts. The actual fail or settle we need to
3112
                // propagate to the remote party is now in the commit diff.
3113
                err = c.Packager.AckSettleFails(tx, diff.SettleFailAcks...)
2,070✔
3114
                if err != nil {
2,070✔
3115
                        return err
×
3116
                }
×
3117

3118
                // We are sending a commitment signature so lastWasRevokeKey should
3119
                // store false.
3120
                var b bytes.Buffer
2,070✔
3121
                if err := WriteElements(&b, false); err != nil {
2,070✔
3122
                        return err
×
3123
                }
×
3124
                if err := chanBucket.Put(lastWasRevokeKey, b.Bytes()); err != nil {
2,070✔
3125
                        return err
×
3126
                }
×
3127

3128
                // TODO(roasbeef): use seqno to derive key for later LCP
3129

3130
                // With the bucket retrieved, we'll now serialize the commit
3131
                // diff itself, and write it to disk.
3132
                var b2 bytes.Buffer
2,070✔
3133
                if err := serializeCommitDiff(&b2, diff); err != nil {
2,070✔
3134
                        return err
×
3135
                }
×
3136
                return chanBucket.Put(commitDiffKey, b2.Bytes())
2,070✔
3137
        }, func() {})
2,071✔
3138
}
3139

3140
// RemoteCommitChainTip returns the "tip" of the current remote commitment
3141
// chain. This value will be non-nil iff, we've created a new commitment for
3142
// the remote party that they haven't yet ACK'd. In this case, their commitment
3143
// chain will have a length of two: their current unrevoked commitment, and
3144
// this new pending commitment. Once they revoked their prior state, we'll swap
3145
// these pointers, causing the tip and the tail to point to the same entry.
3146
func (c *OpenChannel) RemoteCommitChainTip() (*CommitDiff, error) {
1,248✔
3147
        var cd *CommitDiff
1,248✔
3148
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
2,496✔
3149
                chanBucket, err := fetchChanBucket(
1,248✔
3150
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
1,248✔
3151
                )
1,248✔
3152
                switch err {
1,248✔
3153
                case nil:
872✔
3154
                case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
378✔
3155
                        return ErrNoPendingCommit
378✔
3156
                default:
×
3157
                        return err
×
3158
                }
3159

3160
                tipBytes := chanBucket.Get(commitDiffKey)
872✔
3161
                if tipBytes == nil {
1,663✔
3162
                        return ErrNoPendingCommit
791✔
3163
                }
791✔
3164

3165
                tipReader := bytes.NewReader(tipBytes)
84✔
3166
                dcd, err := deserializeCommitDiff(tipReader)
84✔
3167
                if err != nil {
84✔
3168
                        return err
×
3169
                }
×
3170

3171
                cd = dcd
84✔
3172
                return nil
84✔
3173
        }, func() {
1,248✔
3174
                cd = nil
1,248✔
3175
        })
1,248✔
3176
        if err != nil {
2,415✔
3177
                return nil, err
1,167✔
3178
        }
1,167✔
3179

3180
        return cd, nil
84✔
3181
}
3182

3183
// UnsignedAckedUpdates retrieves the persisted unsigned acked remote log
3184
// updates that still need to be signed for.
3185
func (c *OpenChannel) UnsignedAckedUpdates() ([]LogUpdate, error) {
814✔
3186
        var updates []LogUpdate
814✔
3187
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
1,628✔
3188
                chanBucket, err := fetchChanBucket(
814✔
3189
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
814✔
3190
                )
814✔
3191
                switch err {
814✔
3192
                case nil:
438✔
3193
                case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
378✔
3194
                        return nil
378✔
3195
                default:
×
3196
                        return err
×
3197
                }
3198

3199
                updateBytes := chanBucket.Get(unsignedAckedUpdatesKey)
438✔
3200
                if updateBytes == nil {
803✔
3201
                        return nil
365✔
3202
                }
365✔
3203

3204
                r := bytes.NewReader(updateBytes)
76✔
3205
                updates, err = deserializeLogUpdates(r)
76✔
3206
                return err
76✔
3207
        }, func() {
814✔
3208
                updates = nil
814✔
3209
        })
814✔
3210
        if err != nil {
814✔
3211
                return nil, err
×
3212
        }
×
3213

3214
        return updates, nil
814✔
3215
}
3216

3217
// RemoteUnsignedLocalUpdates retrieves the persisted, unsigned local log
3218
// updates that the remote still needs to sign for.
3219
func (c *OpenChannel) RemoteUnsignedLocalUpdates() ([]LogUpdate, error) {
813✔
3220
        var updates []LogUpdate
813✔
3221
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
1,626✔
3222
                chanBucket, err := fetchChanBucket(
813✔
3223
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
813✔
3224
                )
813✔
3225
                switch err {
813✔
3226
                case nil:
437✔
3227
                        break
437✔
3228
                case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
378✔
3229
                        return nil
378✔
3230
                default:
×
3231
                        return err
×
3232
                }
3233

3234
                updateBytes := chanBucket.Get(remoteUnsignedLocalUpdatesKey)
437✔
3235
                if updateBytes == nil {
833✔
3236
                        return nil
396✔
3237
                }
396✔
3238

3239
                r := bytes.NewReader(updateBytes)
44✔
3240
                updates, err = deserializeLogUpdates(r)
44✔
3241
                return err
44✔
3242
        }, func() {
813✔
3243
                updates = nil
813✔
3244
        })
813✔
3245
        if err != nil {
813✔
3246
                return nil, err
×
3247
        }
×
3248

3249
        return updates, nil
813✔
3250
}
3251

3252
// InsertNextRevocation inserts the _next_ commitment point (revocation) into
3253
// the database, and also modifies the internal RemoteNextRevocation attribute
3254
// to point to the passed key. This method is to be using during final channel
3255
// set up, _after_ the channel has been fully confirmed.
3256
//
3257
// NOTE: If this method isn't called, then the target channel won't be able to
3258
// propose new states for the commitment state of the remote party.
3259
func (c *OpenChannel) InsertNextRevocation(revKey *btcec.PublicKey) error {
631✔
3260
        c.Lock()
631✔
3261
        defer c.Unlock()
631✔
3262

631✔
3263
        c.RemoteNextRevocation = revKey
631✔
3264

631✔
3265
        err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
1,262✔
3266
                chanBucket, err := fetchChanBucketRw(
631✔
3267
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
631✔
3268
                )
631✔
3269
                if err != nil {
631✔
3270
                        return err
×
3271
                }
×
3272

3273
                return putChanRevocationState(chanBucket, c)
631✔
3274
        }, func() {})
631✔
3275
        if err != nil {
631✔
3276
                return err
×
3277
        }
×
3278

3279
        return nil
631✔
3280
}
3281

3282
// AdvanceCommitChainTail records the new state transition within an on-disk
3283
// append-only log which records all state transitions by the remote peer. In
3284
// the case of an uncooperative broadcast of a prior state by the remote peer,
3285
// this log can be consulted in order to reconstruct the state needed to
3286
// rectify the situation. This method will add the current commitment for the
3287
// remote party to the revocation log, and promote the current pending
3288
// commitment to the current remote commitment. The updates parameter is the
3289
// set of local updates that the peer still needs to send us a signature for.
3290
// We store this set of updates in case we go down.
3291
func (c *OpenChannel) AdvanceCommitChainTail(fwdPkg *FwdPkg,
3292
        updates []LogUpdate, ourOutputIndex, theirOutputIndex uint32) error {
1,984✔
3293

1,984✔
3294
        c.Lock()
1,984✔
3295
        defer c.Unlock()
1,984✔
3296

1,984✔
3297
        // If this is a restored channel, then we want to avoid mutating the
1,984✔
3298
        // state at all, as it's impossible to do so in a protocol compliant
1,984✔
3299
        // manner.
1,984✔
3300
        if c.hasChanStatus(ChanStatusRestored) {
1,985✔
3301
                return ErrNoRestoredChannelMutation
1✔
3302
        }
1✔
3303

3304
        var newRemoteCommit *ChannelCommitment
1,983✔
3305

1,983✔
3306
        err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
3,966✔
3307
                chanBucket, err := fetchChanBucketRw(
1,983✔
3308
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
1,983✔
3309
                )
1,983✔
3310
                if err != nil {
1,983✔
3311
                        return err
×
3312
                }
×
3313

3314
                // If the channel is marked as borked, then for safety reasons,
3315
                // we shouldn't attempt any further updates.
3316
                isBorked, err := c.isBorked(chanBucket)
1,983✔
3317
                if err != nil {
1,983✔
3318
                        return err
×
3319
                }
×
3320
                if isBorked {
1,984✔
3321
                        return ErrChanBorked
1✔
3322
                }
1✔
3323

3324
                // Persist the latest preimage state to disk as the remote peer
3325
                // has just added to our local preimage store, and given us a
3326
                // new pending revocation key.
3327
                if err := putChanRevocationState(chanBucket, c); err != nil {
1,982✔
3328
                        return err
×
3329
                }
×
3330

3331
                // With the current preimage producer/store state updated,
3332
                // append a new log entry recording this the delta of this
3333
                // state transition.
3334
                //
3335
                // TODO(roasbeef): could make the deltas relative, would save
3336
                // space, but then tradeoff for more disk-seeks to recover the
3337
                // full state.
3338
                logKey := revocationLogBucket
1,982✔
3339
                logBucket, err := chanBucket.CreateBucketIfNotExists(logKey)
1,982✔
3340
                if err != nil {
1,982✔
3341
                        return err
×
3342
                }
×
3343

3344
                // Before we append this revoked state to the revocation log,
3345
                // we'll swap out what's currently the tail of the commit tip,
3346
                // with the current locked-in commitment for the remote party.
3347
                tipBytes := chanBucket.Get(commitDiffKey)
1,982✔
3348
                tipReader := bytes.NewReader(tipBytes)
1,982✔
3349
                newCommit, err := deserializeCommitDiff(tipReader)
1,982✔
3350
                if err != nil {
1,982✔
3351
                        return err
×
3352
                }
×
3353
                err = putChanCommitment(
1,982✔
3354
                        chanBucket, &newCommit.Commitment, false,
1,982✔
3355
                )
1,982✔
3356
                if err != nil {
1,982✔
3357
                        return err
×
3358
                }
×
3359
                if err := chanBucket.Delete(commitDiffKey); err != nil {
1,982✔
3360
                        return err
×
3361
                }
×
3362

3363
                // With the commitment pointer swapped, we can now add the
3364
                // revoked (prior) state to the revocation log.
3365
                err = putRevocationLog(
1,982✔
3366
                        logBucket, &c.RemoteCommitment, ourOutputIndex,
1,982✔
3367
                        theirOutputIndex, c.Db.parent.noRevLogAmtData,
1,982✔
3368
                )
1,982✔
3369
                if err != nil {
1,982✔
3370
                        return err
×
3371
                }
×
3372

3373
                // Lastly, we write the forwarding package to disk so that we
3374
                // can properly recover from failures and reforward HTLCs that
3375
                // have not received a corresponding settle/fail.
3376
                if err := c.Packager.AddFwdPkg(tx, fwdPkg); err != nil {
1,982✔
3377
                        return err
×
3378
                }
×
3379

3380
                // Persist the unsigned acked updates that are not included
3381
                // in their new commitment.
3382
                updateBytes := chanBucket.Get(unsignedAckedUpdatesKey)
1,982✔
3383
                if updateBytes == nil {
2,194✔
3384
                        // This shouldn't normally happen as we always store
212✔
3385
                        // the number of updates, but could still be
212✔
3386
                        // encountered by nodes that are upgrading.
212✔
3387
                        newRemoteCommit = &newCommit.Commitment
212✔
3388
                        return nil
212✔
3389
                }
212✔
3390

3391
                r := bytes.NewReader(updateBytes)
1,773✔
3392
                unsignedUpdates, err := deserializeLogUpdates(r)
1,773✔
3393
                if err != nil {
1,773✔
3394
                        return err
×
3395
                }
×
3396

3397
                var validUpdates []LogUpdate
1,773✔
3398
                for _, upd := range unsignedUpdates {
3,197✔
3399
                        lIdx := upd.LogIndex
1,424✔
3400

1,424✔
3401
                        // Filter for updates that are not on the remote
1,424✔
3402
                        // commitment.
1,424✔
3403
                        if lIdx >= newCommit.Commitment.RemoteLogIndex {
1,593✔
3404
                                validUpdates = append(validUpdates, upd)
169✔
3405
                        }
169✔
3406
                }
3407

3408
                var b bytes.Buffer
1,773✔
3409
                err = serializeLogUpdates(&b, validUpdates)
1,773✔
3410
                if err != nil {
1,773✔
3411
                        return fmt.Errorf("unable to serialize log updates: %w",
×
3412
                                err)
×
3413
                }
×
3414

3415
                err = chanBucket.Put(unsignedAckedUpdatesKey, b.Bytes())
1,773✔
3416
                if err != nil {
1,773✔
3417
                        return fmt.Errorf("unable to store under "+
×
3418
                                "unsignedAckedUpdatesKey: %w", err)
×
3419
                }
×
3420

3421
                // Persist the local updates the peer hasn't yet signed so they
3422
                // can be restored after restart.
3423
                var b2 bytes.Buffer
1,773✔
3424
                err = serializeLogUpdates(&b2, updates)
1,773✔
3425
                if err != nil {
1,773✔
3426
                        return err
×
3427
                }
×
3428

3429
                err = chanBucket.Put(remoteUnsignedLocalUpdatesKey, b2.Bytes())
1,773✔
3430
                if err != nil {
1,773✔
3431
                        return fmt.Errorf("unable to restore remote unsigned "+
×
3432
                                "local updates: %v", err)
×
3433
                }
×
3434

3435
                newRemoteCommit = &newCommit.Commitment
1,773✔
3436

1,773✔
3437
                return nil
1,773✔
3438
        }, func() {
1,983✔
3439
                newRemoteCommit = nil
1,983✔
3440
        })
1,983✔
3441
        if err != nil {
1,984✔
3442
                return err
1✔
3443
        }
1✔
3444

3445
        // With the db transaction complete, we'll swap over the in-memory
3446
        // pointer of the new remote commitment, which was previously the tip
3447
        // of the commit chain.
3448
        c.RemoteCommitment = *newRemoteCommit
1,982✔
3449

1,982✔
3450
        return nil
1,982✔
3451
}
3452

3453
// FinalHtlcInfo contains information about the final outcome of an htlc.
3454
type FinalHtlcInfo struct {
3455
        // Settled is true is the htlc was settled. If false, the htlc was
3456
        // failed.
3457
        Settled bool
3458

3459
        // Offchain indicates whether the htlc was resolved off-chain or
3460
        // on-chain.
3461
        Offchain bool
3462
}
3463

3464
// putFinalHtlc writes the final htlc outcome to the database. Additionally it
3465
// records whether the htlc was resolved off-chain or on-chain.
3466
func putFinalHtlc(finalHtlcsBucket kvdb.RwBucket, id uint64,
3467
        info FinalHtlcInfo) error {
6✔
3468

6✔
3469
        var key [8]byte
6✔
3470
        byteOrder.PutUint64(key[:], id)
6✔
3471

6✔
3472
        var finalHtlcByte FinalHtlcByte
6✔
3473
        if info.Settled {
12✔
3474
                finalHtlcByte |= FinalHtlcSettledBit
6✔
3475
        }
6✔
3476
        if info.Offchain {
11✔
3477
                finalHtlcByte |= FinalHtlcOffchainBit
5✔
3478
        }
5✔
3479

3480
        return finalHtlcsBucket.Put(key[:], []byte{byte(finalHtlcByte)})
6✔
3481
}
3482

3483
// NextLocalHtlcIndex returns the next unallocated local htlc index. To ensure
3484
// this always returns the next index that has been not been allocated, this
3485
// will first try to examine any pending commitments, before falling back to the
3486
// last locked-in remote commitment.
3487
func (c *OpenChannel) NextLocalHtlcIndex() (uint64, error) {
382✔
3488
        // First, load the most recent commit diff that we initiated for the
382✔
3489
        // remote party. If no pending commit is found, this is not treated as
382✔
3490
        // a critical error, since we can always fall back.
382✔
3491
        pendingRemoteCommit, err := c.RemoteCommitChainTip()
382✔
3492
        if err != nil && err != ErrNoPendingCommit {
382✔
3493
                return 0, err
×
3494
        }
×
3495

3496
        // If a pending commit was found, its local htlc index will be at least
3497
        // as large as the one on our local commitment.
3498
        if pendingRemoteCommit != nil {
398✔
3499
                return pendingRemoteCommit.Commitment.LocalHtlcIndex, nil
16✔
3500
        }
16✔
3501

3502
        // Otherwise, fallback to using the local htlc index of their commitment.
3503
        return c.RemoteCommitment.LocalHtlcIndex, nil
366✔
3504
}
3505

3506
// LoadFwdPkgs scans the forwarding log for any packages that haven't been
3507
// processed, and returns their deserialized log updates in map indexed by the
3508
// remote commitment height at which the updates were locked in.
3509
func (c *OpenChannel) LoadFwdPkgs() ([]*FwdPkg, error) {
452✔
3510
        c.RLock()
452✔
3511
        defer c.RUnlock()
452✔
3512

452✔
3513
        var fwdPkgs []*FwdPkg
452✔
3514
        if err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
887✔
3515
                var err error
435✔
3516
                fwdPkgs, err = c.Packager.LoadFwdPkgs(tx)
435✔
3517
                return err
435✔
3518
        }, func() {
887✔
3519
                fwdPkgs = nil
452✔
3520
        }); err != nil {
469✔
3521
                return nil, err
17✔
3522
        }
17✔
3523

3524
        return fwdPkgs, nil
435✔
3525
}
3526

3527
// AckAddHtlcs updates the AckAddFilter containing any of the provided AddRefs
3528
// indicating that a response to this Add has been committed to the remote party.
3529
// Doing so will prevent these Add HTLCs from being reforwarded internally.
3530
func (c *OpenChannel) AckAddHtlcs(addRefs ...AddRef) error {
1✔
3531
        c.Lock()
1✔
3532
        defer c.Unlock()
1✔
3533

1✔
3534
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
2✔
3535
                return c.Packager.AckAddHtlcs(tx, addRefs...)
1✔
3536
        }, func() {})
2✔
3537
}
3538

3539
// AckSettleFails updates the SettleFailFilter containing any of the provided
3540
// SettleFailRefs, indicating that the response has been delivered to the
3541
// incoming link, corresponding to a particular AddRef. Doing so will prevent
3542
// the responses from being retransmitted internally.
3543
func (c *OpenChannel) AckSettleFails(settleFailRefs ...SettleFailRef) error {
×
3544
        c.Lock()
×
3545
        defer c.Unlock()
×
3546

×
3547
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
×
3548
                return c.Packager.AckSettleFails(tx, settleFailRefs...)
×
3549
        }, func() {})
×
3550
}
3551

3552
// SetFwdFilter atomically sets the forwarding filter for the forwarding package
3553
// identified by `height`.
3554
func (c *OpenChannel) SetFwdFilter(height uint64, fwdFilter *PkgFilter) error {
1,201✔
3555
        c.Lock()
1,201✔
3556
        defer c.Unlock()
1,201✔
3557

1,201✔
3558
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
2,402✔
3559
                return c.Packager.SetFwdFilter(tx, height, fwdFilter)
1,201✔
3560
        }, func() {})
2,402✔
3561
}
3562

3563
// RemoveFwdPkgs atomically removes forwarding packages specified by the remote
3564
// commitment heights. If one of the intermediate RemovePkg calls fails, then the
3565
// later packages won't be removed.
3566
//
3567
// NOTE: This method should only be called on packages marked FwdStateCompleted.
3568
func (c *OpenChannel) RemoveFwdPkgs(heights ...uint64) error {
4✔
3569
        c.Lock()
4✔
3570
        defer c.Unlock()
4✔
3571

4✔
3572
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
8✔
3573
                for _, height := range heights {
8✔
3574
                        err := c.Packager.RemovePkg(tx, height)
4✔
3575
                        if err != nil {
5✔
3576
                                return err
1✔
3577
                        }
1✔
3578
                }
3579

3580
                return nil
4✔
3581
        }, func() {})
4✔
3582
}
3583

3584
// revocationLogTailCommitHeight returns the commit height at the end of the
3585
// revocation log. This entry represents the last previous state for the remote
3586
// node's commitment chain. The ChannelDelta returned by this method will
3587
// always lag one state behind the most current (unrevoked) state of the remote
3588
// node's commitment chain.
3589
// NOTE: used in unit test only.
3590
func (c *OpenChannel) revocationLogTailCommitHeight() (uint64, error) {
2✔
3591
        c.RLock()
2✔
3592
        defer c.RUnlock()
2✔
3593

2✔
3594
        var height uint64
2✔
3595

2✔
3596
        // If we haven't created any state updates yet, then we'll exit early as
2✔
3597
        // there's nothing to be found on disk in the revocation bucket.
2✔
3598
        if c.RemoteCommitment.CommitHeight == 0 {
2✔
3599
                return height, nil
×
3600
        }
×
3601

3602
        if err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
4✔
3603
                chanBucket, err := fetchChanBucket(
2✔
3604
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
2✔
3605
                )
2✔
3606
                if err != nil {
2✔
3607
                        return err
×
3608
                }
×
3609

3610
                logBucket, err := fetchLogBucket(chanBucket)
2✔
3611
                if err != nil {
2✔
3612
                        return err
×
3613
                }
×
3614

3615
                // Once we have the bucket that stores the revocation log from
3616
                // this channel, we'll jump to the _last_ key in bucket. Since
3617
                // the key is the commit height, we'll decode the bytes and
3618
                // return it.
3619
                cursor := logBucket.ReadCursor()
2✔
3620
                rawHeight, _ := cursor.Last()
2✔
3621
                height = byteOrder.Uint64(rawHeight)
2✔
3622

2✔
3623
                return nil
2✔
3624
        }, func() {}); err != nil {
2✔
3625
                return height, err
×
3626
        }
×
3627

3628
        return height, nil
2✔
3629
}
3630

3631
// CommitmentHeight returns the current commitment height. The commitment
3632
// height represents the number of updates to the commitment state to date.
3633
// This value is always monotonically increasing. This method is provided in
3634
// order to allow multiple instances of a particular open channel to obtain a
3635
// consistent view of the number of channel updates to date.
3636
func (c *OpenChannel) CommitmentHeight() (uint64, error) {
1✔
3637
        c.RLock()
1✔
3638
        defer c.RUnlock()
1✔
3639

1✔
3640
        var height uint64
1✔
3641
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
2✔
3642
                // Get the bucket dedicated to storing the metadata for open
1✔
3643
                // channels.
1✔
3644
                chanBucket, err := fetchChanBucket(
1✔
3645
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
1✔
3646
                )
1✔
3647
                if err != nil {
1✔
3648
                        return err
×
3649
                }
×
3650

3651
                commit, err := fetchChanCommitment(chanBucket, true)
1✔
3652
                if err != nil {
1✔
3653
                        return err
×
3654
                }
×
3655

3656
                height = commit.CommitHeight
1✔
3657
                return nil
1✔
3658
        }, func() {
1✔
3659
                height = 0
1✔
3660
        })
1✔
3661
        if err != nil {
1✔
3662
                return 0, err
×
3663
        }
×
3664

3665
        return height, nil
1✔
3666
}
3667

3668
// FindPreviousState scans through the append-only log in an attempt to recover
3669
// the previous channel state indicated by the update number. This method is
3670
// intended to be used for obtaining the relevant data needed to claim all
3671
// funds rightfully spendable in the case of an on-chain broadcast of the
3672
// commitment transaction.
3673
func (c *OpenChannel) FindPreviousState(
3674
        updateNum uint64) (*RevocationLog, *ChannelCommitment, error) {
34✔
3675

34✔
3676
        c.RLock()
34✔
3677
        defer c.RUnlock()
34✔
3678

34✔
3679
        commit := &ChannelCommitment{}
34✔
3680
        rl := &RevocationLog{}
34✔
3681

34✔
3682
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
68✔
3683
                chanBucket, err := fetchChanBucket(
34✔
3684
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
34✔
3685
                )
34✔
3686
                if err != nil {
35✔
3687
                        return err
1✔
3688
                }
1✔
3689

3690
                // Find the revocation log from both the new and the old
3691
                // bucket.
3692
                r, c, err := fetchRevocationLogCompatible(chanBucket, updateNum)
33✔
3693
                if err != nil {
55✔
3694
                        return err
22✔
3695
                }
22✔
3696

3697
                rl = r
14✔
3698
                commit = c
14✔
3699
                return nil
14✔
3700
        }, func() {})
34✔
3701
        if err != nil {
57✔
3702
                return nil, nil, err
23✔
3703
        }
23✔
3704

3705
        // Either the `rl` or the `commit` is nil here. We return them as-is
3706
        // and leave it to the caller to decide its following action.
3707
        return rl, commit, nil
14✔
3708
}
3709

3710
// ClosureType is an enum like structure that details exactly _how_ a channel
3711
// was closed. Three closure types are currently possible: none, cooperative,
3712
// local force close, remote force close, and (remote) breach.
3713
type ClosureType uint8
3714

3715
const (
3716
        // CooperativeClose indicates that a channel has been closed
3717
        // cooperatively.  This means that both channel peers were online and
3718
        // signed a new transaction paying out the settled balance of the
3719
        // contract.
3720
        CooperativeClose ClosureType = 0
3721

3722
        // LocalForceClose indicates that we have unilaterally broadcast our
3723
        // current commitment state on-chain.
3724
        LocalForceClose ClosureType = 1
3725

3726
        // RemoteForceClose indicates that the remote peer has unilaterally
3727
        // broadcast their current commitment state on-chain.
3728
        RemoteForceClose ClosureType = 4
3729

3730
        // BreachClose indicates that the remote peer attempted to broadcast a
3731
        // prior _revoked_ channel state.
3732
        BreachClose ClosureType = 2
3733

3734
        // FundingCanceled indicates that the channel never was fully opened
3735
        // before it was marked as closed in the database. This can happen if
3736
        // we or the remote fail at some point during the opening workflow, or
3737
        // we timeout waiting for the funding transaction to be confirmed.
3738
        FundingCanceled ClosureType = 3
3739

3740
        // Abandoned indicates that the channel state was removed without
3741
        // any further actions. This is intended to clean up unusable
3742
        // channels during development.
3743
        Abandoned ClosureType = 5
3744
)
3745

3746
// ChannelCloseSummary contains the final state of a channel at the point it
3747
// was closed. Once a channel is closed, all the information pertaining to that
3748
// channel within the openChannelBucket is deleted, and a compact summary is
3749
// put in place instead.
3750
type ChannelCloseSummary struct {
3751
        // ChanPoint is the outpoint for this channel's funding transaction,
3752
        // and is used as a unique identifier for the channel.
3753
        ChanPoint wire.OutPoint
3754

3755
        // ShortChanID encodes the exact location in the chain in which the
3756
        // channel was initially confirmed. This includes: the block height,
3757
        // transaction index, and the output within the target transaction.
3758
        ShortChanID lnwire.ShortChannelID
3759

3760
        // ChainHash is the hash of the genesis block that this channel resides
3761
        // within.
3762
        ChainHash chainhash.Hash
3763

3764
        // ClosingTXID is the txid of the transaction which ultimately closed
3765
        // this channel.
3766
        ClosingTXID chainhash.Hash
3767

3768
        // RemotePub is the public key of the remote peer that we formerly had
3769
        // a channel with.
3770
        RemotePub *btcec.PublicKey
3771

3772
        // Capacity was the total capacity of the channel.
3773
        Capacity btcutil.Amount
3774

3775
        // CloseHeight is the height at which the funding transaction was
3776
        // spent.
3777
        CloseHeight uint32
3778

3779
        // SettledBalance is our total balance settled balance at the time of
3780
        // channel closure. This _does not_ include the sum of any outputs that
3781
        // have been time-locked as a result of the unilateral channel closure.
3782
        SettledBalance btcutil.Amount
3783

3784
        // TimeLockedBalance is the sum of all the time-locked outputs at the
3785
        // time of channel closure. If we triggered the force closure of this
3786
        // channel, then this value will be non-zero if our settled output is
3787
        // above the dust limit. If we were on the receiving side of a channel
3788
        // force closure, then this value will be non-zero if we had any
3789
        // outstanding outgoing HTLC's at the time of channel closure.
3790
        TimeLockedBalance btcutil.Amount
3791

3792
        // CloseType details exactly _how_ the channel was closed. Five closure
3793
        // types are possible: cooperative, local force, remote force, breach
3794
        // and funding canceled.
3795
        CloseType ClosureType
3796

3797
        // IsPending indicates whether this channel is in the 'pending close'
3798
        // state, which means the channel closing transaction has been
3799
        // confirmed, but not yet been fully resolved. In the case of a channel
3800
        // that has been cooperatively closed, it will go straight into the
3801
        // fully resolved state as soon as the closing transaction has been
3802
        // confirmed. However, for channels that have been force closed, they'll
3803
        // stay marked as "pending" until _all_ the pending funds have been
3804
        // swept.
3805
        IsPending bool
3806

3807
        // RemoteCurrentRevocation is the current revocation for their
3808
        // commitment transaction. However, since this is the derived public key,
3809
        // we don't yet have the private key so we aren't yet able to verify
3810
        // that it's actually in the hash chain.
3811
        RemoteCurrentRevocation *btcec.PublicKey
3812

3813
        // RemoteNextRevocation is the revocation key to be used for the *next*
3814
        // commitment transaction we create for the local node. Within the
3815
        // specification, this value is referred to as the
3816
        // per-commitment-point.
3817
        RemoteNextRevocation *btcec.PublicKey
3818

3819
        // LocalChanConfig is the channel configuration for the local node.
3820
        LocalChanConfig ChannelConfig
3821

3822
        // LastChanSyncMsg is the ChannelReestablish message for this channel
3823
        // for the state at the point where it was closed.
3824
        LastChanSyncMsg *lnwire.ChannelReestablish
3825
}
3826

3827
// CloseChannel closes a previously active Lightning channel. Closing a channel
3828
// entails deleting all saved state within the database concerning this
3829
// channel. This method also takes a struct that summarizes the state of the
3830
// channel at closing, this compact representation will be the only component
3831
// of a channel left over after a full closing. It takes an optional set of
3832
// channel statuses which will be written to the historical channel bucket.
3833
// These statuses are used to record close initiators.
3834
func (c *OpenChannel) CloseChannel(summary *ChannelCloseSummary,
3835
        statuses ...ChannelStatus) error {
118✔
3836

118✔
3837
        c.Lock()
118✔
3838
        defer c.Unlock()
118✔
3839

118✔
3840
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
236✔
3841
                openChanBucket := tx.ReadWriteBucket(openChannelBucket)
118✔
3842
                if openChanBucket == nil {
118✔
3843
                        return ErrNoChanDBExists
×
3844
                }
×
3845

3846
                nodePub := c.IdentityPub.SerializeCompressed()
118✔
3847
                nodeChanBucket := openChanBucket.NestedReadWriteBucket(nodePub)
118✔
3848
                if nodeChanBucket == nil {
118✔
3849
                        return ErrNoActiveChannels
×
3850
                }
×
3851

3852
                chainBucket := nodeChanBucket.NestedReadWriteBucket(c.ChainHash[:])
118✔
3853
                if chainBucket == nil {
118✔
3854
                        return ErrNoActiveChannels
×
3855
                }
×
3856

3857
                var chanPointBuf bytes.Buffer
118✔
3858
                err := graphdb.WriteOutpoint(&chanPointBuf, &c.FundingOutpoint)
118✔
3859
                if err != nil {
118✔
3860
                        return err
×
3861
                }
×
3862
                chanKey := chanPointBuf.Bytes()
118✔
3863
                chanBucket := chainBucket.NestedReadWriteBucket(
118✔
3864
                        chanKey,
118✔
3865
                )
118✔
3866
                if chanBucket == nil {
118✔
3867
                        return ErrNoActiveChannels
×
3868
                }
×
3869

3870
                // Before we delete the channel state, we'll read out the full
3871
                // details, as we'll also store portions of this information
3872
                // for record keeping.
3873
                chanState, err := fetchOpenChannel(
118✔
3874
                        chanBucket, &c.FundingOutpoint,
118✔
3875
                )
118✔
3876
                if err != nil {
118✔
3877
                        return err
×
3878
                }
×
3879

3880
                // Delete all the forwarding packages stored for this particular
3881
                // channel.
3882
                if err = chanState.Packager.Wipe(tx); err != nil {
118✔
3883
                        return err
×
3884
                }
×
3885

3886
                // Now that the index to this channel has been deleted, purge
3887
                // the remaining channel metadata from the database.
3888
                err = deleteOpenChannel(chanBucket)
118✔
3889
                if err != nil {
118✔
3890
                        return err
×
3891
                }
×
3892

3893
                // We'll also remove the channel from the frozen channel bucket
3894
                // if we need to.
3895
                if c.ChanType.IsFrozen() || c.ChanType.HasLeaseExpiration() {
229✔
3896
                        err := deleteThawHeight(chanBucket)
111✔
3897
                        if err != nil {
111✔
3898
                                return err
×
3899
                        }
×
3900
                }
3901

3902
                // With the base channel data deleted, attempt to delete the
3903
                // information stored within the revocation log.
3904
                if err := deleteLogBucket(chanBucket); err != nil {
118✔
3905
                        return err
×
3906
                }
×
3907

3908
                err = chainBucket.DeleteNestedBucket(chanPointBuf.Bytes())
118✔
3909
                if err != nil {
118✔
3910
                        return err
×
3911
                }
×
3912

3913
                // Fetch the outpoint bucket to see if the outpoint exists or
3914
                // not.
3915
                opBucket := tx.ReadWriteBucket(outpointBucket)
118✔
3916
                if opBucket == nil {
118✔
3917
                        return ErrNoChanDBExists
×
3918
                }
×
3919

3920
                // Add the closed outpoint to our outpoint index. This should
3921
                // replace an open outpoint in the index.
3922
                if opBucket.Get(chanPointBuf.Bytes()) == nil {
118✔
3923
                        return ErrMissingIndexEntry
×
3924
                }
×
3925

3926
                status := uint8(outpointClosed)
118✔
3927

118✔
3928
                // Write the IndexStatus of this outpoint as the first entry in a tlv
118✔
3929
                // stream.
118✔
3930
                statusRecord := tlv.MakePrimitiveRecord(indexStatusType, &status)
118✔
3931
                opStream, err := tlv.NewStream(statusRecord)
118✔
3932
                if err != nil {
118✔
3933
                        return err
×
3934
                }
×
3935

3936
                var b bytes.Buffer
118✔
3937
                if err := opStream.Encode(&b); err != nil {
118✔
3938
                        return err
×
3939
                }
×
3940

3941
                // Finally add the closed outpoint and tlv stream to the index.
3942
                if err := opBucket.Put(chanPointBuf.Bytes(), b.Bytes()); err != nil {
118✔
3943
                        return err
×
3944
                }
×
3945

3946
                // Add channel state to the historical channel bucket.
3947
                historicalBucket, err := tx.CreateTopLevelBucket(
118✔
3948
                        historicalChannelBucket,
118✔
3949
                )
118✔
3950
                if err != nil {
118✔
3951
                        return err
×
3952
                }
×
3953

3954
                historicalChanBucket, err :=
118✔
3955
                        historicalBucket.CreateBucketIfNotExists(chanKey)
118✔
3956
                if err != nil {
118✔
3957
                        return err
×
3958
                }
×
3959

3960
                // Apply any additional statuses to the channel state.
3961
                for _, status := range statuses {
126✔
3962
                        chanState.chanStatus |= status
8✔
3963
                }
8✔
3964

3965
                err = putOpenChannel(historicalChanBucket, chanState)
118✔
3966
                if err != nil {
118✔
3967
                        return err
×
3968
                }
×
3969

3970
                // Finally, create a summary of this channel in the closed
3971
                // channel bucket for this node.
3972
                return putChannelCloseSummary(
118✔
3973
                        tx, chanPointBuf.Bytes(), summary, chanState,
118✔
3974
                )
118✔
3975
        }, func() {})
118✔
3976
}
3977

3978
// ChannelSnapshot is a frozen snapshot of the current channel state. A
3979
// snapshot is detached from the original channel that generated it, providing
3980
// read-only access to the current or prior state of an active channel.
3981
//
3982
// TODO(roasbeef): remove all together? pretty much just commitment
3983
type ChannelSnapshot struct {
3984
        // RemoteIdentity is the identity public key of the remote node that we
3985
        // are maintaining the open channel with.
3986
        RemoteIdentity btcec.PublicKey
3987

3988
        // ChanPoint is the outpoint that created the channel. This output is
3989
        // found within the funding transaction and uniquely identified the
3990
        // channel on the resident chain.
3991
        ChannelPoint wire.OutPoint
3992

3993
        // ChainHash is the genesis hash of the chain that the channel resides
3994
        // within.
3995
        ChainHash chainhash.Hash
3996

3997
        // Capacity is the total capacity of the channel.
3998
        Capacity btcutil.Amount
3999

4000
        // TotalMSatSent is the total number of milli-satoshis we've sent
4001
        // within this channel.
4002
        TotalMSatSent lnwire.MilliSatoshi
4003

4004
        // TotalMSatReceived is the total number of milli-satoshis we've
4005
        // received within this channel.
4006
        TotalMSatReceived lnwire.MilliSatoshi
4007

4008
        // ChannelCommitment is the current up-to-date commitment for the
4009
        // target channel.
4010
        ChannelCommitment
4011
}
4012

4013
// Snapshot returns a read-only snapshot of the current channel state. This
4014
// snapshot includes information concerning the current settled balance within
4015
// the channel, metadata detailing total flows, and any outstanding HTLCs.
4016
func (c *OpenChannel) Snapshot() *ChannelSnapshot {
75✔
4017
        c.RLock()
75✔
4018
        defer c.RUnlock()
75✔
4019

75✔
4020
        localCommit := c.LocalCommitment
75✔
4021
        snapshot := &ChannelSnapshot{
75✔
4022
                RemoteIdentity:    *c.IdentityPub,
75✔
4023
                ChannelPoint:      c.FundingOutpoint,
75✔
4024
                Capacity:          c.Capacity,
75✔
4025
                TotalMSatSent:     c.TotalMSatSent,
75✔
4026
                TotalMSatReceived: c.TotalMSatReceived,
75✔
4027
                ChainHash:         c.ChainHash,
75✔
4028
                ChannelCommitment: ChannelCommitment{
75✔
4029
                        LocalBalance:  localCommit.LocalBalance,
75✔
4030
                        RemoteBalance: localCommit.RemoteBalance,
75✔
4031
                        CommitHeight:  localCommit.CommitHeight,
75✔
4032
                        CommitFee:     localCommit.CommitFee,
75✔
4033
                },
75✔
4034
        }
75✔
4035

75✔
4036
        localCommit.CustomBlob.WhenSome(func(blob tlv.Blob) {
75✔
4037
                blobCopy := make([]byte, len(blob))
×
4038
                copy(blobCopy, blob)
×
4039

×
4040
                snapshot.ChannelCommitment.CustomBlob = fn.Some(blobCopy)
×
4041
        })
×
4042

4043
        // Copy over the current set of HTLCs to ensure the caller can't mutate
4044
        // our internal state.
4045
        snapshot.Htlcs = make([]HTLC, len(localCommit.Htlcs))
75✔
4046
        for i, h := range localCommit.Htlcs {
347✔
4047
                snapshot.Htlcs[i] = h.Copy()
272✔
4048
        }
272✔
4049

4050
        return snapshot
75✔
4051
}
4052

4053
// LatestCommitments returns the two latest commitments for both the local and
4054
// remote party. These commitments are read from disk to ensure that only the
4055
// latest fully committed state is returned. The first commitment returned is
4056
// the local commitment, and the second returned is the remote commitment.
4057
func (c *OpenChannel) LatestCommitments() (*ChannelCommitment, *ChannelCommitment, error) {
18✔
4058
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
36✔
4059
                chanBucket, err := fetchChanBucket(
18✔
4060
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
18✔
4061
                )
18✔
4062
                if err != nil {
18✔
4063
                        return err
×
4064
                }
×
4065

4066
                return fetchChanCommitments(chanBucket, c)
18✔
4067
        }, func() {})
18✔
4068
        if err != nil {
18✔
4069
                return nil, nil, err
×
4070
        }
×
4071

4072
        return &c.LocalCommitment, &c.RemoteCommitment, nil
18✔
4073
}
4074

4075
// RemoteRevocationStore returns the most up to date commitment version of the
4076
// revocation storage tree for the remote party. This method can be used when
4077
// acting on a possible contract breach to ensure, that the caller has the most
4078
// up to date information required to deliver justice.
4079
func (c *OpenChannel) RemoteRevocationStore() (shachain.Store, error) {
18✔
4080
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
36✔
4081
                chanBucket, err := fetchChanBucket(
18✔
4082
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
18✔
4083
                )
18✔
4084
                if err != nil {
18✔
4085
                        return err
×
4086
                }
×
4087

4088
                return fetchChanRevocationState(chanBucket, c)
18✔
4089
        }, func() {})
18✔
4090
        if err != nil {
18✔
4091
                return nil, err
×
4092
        }
×
4093

4094
        return c.RevocationStore, nil
18✔
4095
}
4096

4097
// AbsoluteThawHeight determines a frozen channel's absolute thaw height. If the
4098
// channel is not frozen, then 0 is returned.
4099
func (c *OpenChannel) AbsoluteThawHeight() (uint32, error) {
3✔
4100
        // Only frozen channels have a thaw height.
3✔
4101
        if !c.ChanType.IsFrozen() && !c.ChanType.HasLeaseExpiration() {
6✔
4102
                return 0, nil
3✔
4103
        }
3✔
4104

4105
        // If the channel has the frozen bit set and it's thaw height is below
4106
        // the absolute threshold, then it's interpreted as a relative height to
4107
        // the chain's current height.
4108
        if c.ChanType.IsFrozen() && c.ThawHeight < AbsoluteThawHeightThreshold {
6✔
4109
                // We'll only known of the channel's short ID once it's
3✔
4110
                // confirmed.
3✔
4111
                if c.IsPending {
3✔
4112
                        return 0, errors.New("cannot use relative thaw " +
×
4113
                                "height for unconfirmed channel")
×
4114
                }
×
4115

4116
                // For non-zero-conf channels, this is the base height to use.
4117
                blockHeightBase := c.ShortChannelID.BlockHeight
3✔
4118

3✔
4119
                // If this is a zero-conf channel, the ShortChannelID will be
3✔
4120
                // an alias.
3✔
4121
                if c.IsZeroConf() {
3✔
4122
                        if !c.ZeroConfConfirmed() {
×
4123
                                return 0, errors.New("cannot use relative " +
×
4124
                                        "height for unconfirmed zero-conf " +
×
4125
                                        "channel")
×
4126
                        }
×
4127

4128
                        // Use the confirmed SCID's BlockHeight.
4129
                        blockHeightBase = c.confirmedScid.BlockHeight
×
4130
                }
4131

4132
                return blockHeightBase + c.ThawHeight, nil
3✔
4133
        }
4134

4135
        return c.ThawHeight, nil
×
4136
}
4137

4138
// DeriveHeightHint derives the block height for the channel opening.
4139
func (c *OpenChannel) DeriveHeightHint() uint32 {
29✔
4140
        // As a height hint, we'll try to use the opening height, but if the
29✔
4141
        // channel isn't yet open, then we'll use the height it was broadcast
29✔
4142
        // at. This may be an unconfirmed zero-conf channel.
29✔
4143
        heightHint := c.ShortChanID().BlockHeight
29✔
4144
        if heightHint == 0 {
32✔
4145
                heightHint = c.BroadcastHeight()
3✔
4146
        }
3✔
4147

4148
        // Since no zero-conf state is stored in a channel backup, the below
4149
        // logic will not be triggered for restored, zero-conf channels. Set
4150
        // the height hint for zero-conf channels.
4151
        if c.IsZeroConf() {
32✔
4152
                if c.ZeroConfConfirmed() {
6✔
4153
                        // If the zero-conf channel is confirmed, we'll use the
3✔
4154
                        // confirmed SCID's block height.
3✔
4155
                        heightHint = c.ZeroConfRealScid().BlockHeight
3✔
4156
                } else {
6✔
4157
                        // The zero-conf channel is unconfirmed. We'll need to
3✔
4158
                        // use the FundingBroadcastHeight.
3✔
4159
                        heightHint = c.BroadcastHeight()
3✔
4160
                }
3✔
4161
        }
4162

4163
        return heightHint
29✔
4164
}
4165

4166
func putChannelCloseSummary(tx kvdb.RwTx, chanID []byte,
4167
        summary *ChannelCloseSummary, lastChanState *OpenChannel) error {
118✔
4168

118✔
4169
        closedChanBucket, err := tx.CreateTopLevelBucket(closedChannelBucket)
118✔
4170
        if err != nil {
118✔
4171
                return err
×
4172
        }
×
4173

4174
        summary.RemoteCurrentRevocation = lastChanState.RemoteCurrentRevocation
118✔
4175
        summary.RemoteNextRevocation = lastChanState.RemoteNextRevocation
118✔
4176
        summary.LocalChanConfig = lastChanState.LocalChanCfg
118✔
4177

118✔
4178
        var b bytes.Buffer
118✔
4179
        if err := serializeChannelCloseSummary(&b, summary); err != nil {
118✔
4180
                return err
×
4181
        }
×
4182

4183
        return closedChanBucket.Put(chanID, b.Bytes())
118✔
4184
}
4185

4186
func serializeChannelCloseSummary(w io.Writer, cs *ChannelCloseSummary) error {
125✔
4187
        err := WriteElements(w,
125✔
4188
                cs.ChanPoint, cs.ShortChanID, cs.ChainHash, cs.ClosingTXID,
125✔
4189
                cs.CloseHeight, cs.RemotePub, cs.Capacity, cs.SettledBalance,
125✔
4190
                cs.TimeLockedBalance, cs.CloseType, cs.IsPending,
125✔
4191
        )
125✔
4192
        if err != nil {
125✔
4193
                return err
×
4194
        }
×
4195

4196
        // If this is a close channel summary created before the addition of
4197
        // the new fields, then we can exit here.
4198
        if cs.RemoteCurrentRevocation == nil {
125✔
4199
                return WriteElements(w, false)
×
4200
        }
×
4201

4202
        // If fields are present, write boolean to indicate this, and continue.
4203
        if err := WriteElements(w, true); err != nil {
125✔
4204
                return err
×
4205
        }
×
4206

4207
        if err := WriteElements(w, cs.RemoteCurrentRevocation); err != nil {
125✔
4208
                return err
×
4209
        }
×
4210

4211
        if err := writeChanConfig(w, &cs.LocalChanConfig); err != nil {
125✔
4212
                return err
×
4213
        }
×
4214

4215
        // The RemoteNextRevocation field is optional, as it's possible for a
4216
        // channel to be closed before we learn of the next unrevoked
4217
        // revocation point for the remote party. Write a boolean indicating
4218
        // whether this field is present or not.
4219
        if err := WriteElements(w, cs.RemoteNextRevocation != nil); err != nil {
125✔
4220
                return err
×
4221
        }
×
4222

4223
        // Write the field, if present.
4224
        if cs.RemoteNextRevocation != nil {
248✔
4225
                if err = WriteElements(w, cs.RemoteNextRevocation); err != nil {
123✔
4226
                        return err
×
4227
                }
×
4228
        }
4229

4230
        // Write whether the channel sync message is present.
4231
        if err := WriteElements(w, cs.LastChanSyncMsg != nil); err != nil {
125✔
4232
                return err
×
4233
        }
×
4234

4235
        // Write the channel sync message, if present.
4236
        if cs.LastChanSyncMsg != nil {
128✔
4237
                if err := WriteElements(w, cs.LastChanSyncMsg); err != nil {
3✔
4238
                        return err
×
4239
                }
×
4240
        }
4241

4242
        return nil
125✔
4243
}
4244

4245
func deserializeCloseChannelSummary(r io.Reader) (*ChannelCloseSummary, error) {
133✔
4246
        c := &ChannelCloseSummary{}
133✔
4247

133✔
4248
        err := ReadElements(r,
133✔
4249
                &c.ChanPoint, &c.ShortChanID, &c.ChainHash, &c.ClosingTXID,
133✔
4250
                &c.CloseHeight, &c.RemotePub, &c.Capacity, &c.SettledBalance,
133✔
4251
                &c.TimeLockedBalance, &c.CloseType, &c.IsPending,
133✔
4252
        )
133✔
4253
        if err != nil {
133✔
4254
                return nil, err
×
4255
        }
×
4256

4257
        // We'll now check to see if the channel close summary was encoded with
4258
        // any of the additional optional fields.
4259
        var hasNewFields bool
133✔
4260
        err = ReadElements(r, &hasNewFields)
133✔
4261
        if err != nil {
133✔
4262
                return nil, err
×
4263
        }
×
4264

4265
        // If fields are not present, we can return.
4266
        if !hasNewFields {
141✔
4267
                return c, nil
8✔
4268
        }
8✔
4269

4270
        // Otherwise read the new fields.
4271
        if err := ReadElements(r, &c.RemoteCurrentRevocation); err != nil {
125✔
4272
                return nil, err
×
4273
        }
×
4274

4275
        if err := readChanConfig(r, &c.LocalChanConfig); err != nil {
125✔
4276
                return nil, err
×
4277
        }
×
4278

4279
        // Finally, we'll attempt to read the next unrevoked commitment point
4280
        // for the remote party. If we closed the channel before receiving a
4281
        // channel_ready message then this might not be present. A boolean
4282
        // indicating whether the field is present will come first.
4283
        var hasRemoteNextRevocation bool
125✔
4284
        err = ReadElements(r, &hasRemoteNextRevocation)
125✔
4285
        if err != nil {
125✔
4286
                return nil, err
×
4287
        }
×
4288

4289
        // If this field was written, read it.
4290
        if hasRemoteNextRevocation {
250✔
4291
                err = ReadElements(r, &c.RemoteNextRevocation)
125✔
4292
                if err != nil {
125✔
4293
                        return nil, err
×
4294
                }
×
4295
        }
4296

4297
        // Check if we have a channel sync message to read.
4298
        var hasChanSyncMsg bool
125✔
4299
        err = ReadElements(r, &hasChanSyncMsg)
125✔
4300
        if err == io.EOF {
125✔
4301
                return c, nil
×
4302
        } else if err != nil {
125✔
4303
                return nil, err
×
4304
        }
×
4305

4306
        // If a chan sync message is present, read it.
4307
        if hasChanSyncMsg {
128✔
4308
                // We must pass in reference to a lnwire.Message for the codec
3✔
4309
                // to support it.
3✔
4310
                var msg lnwire.Message
3✔
4311
                if err := ReadElements(r, &msg); err != nil {
3✔
4312
                        return nil, err
×
4313
                }
×
4314

4315
                chanSync, ok := msg.(*lnwire.ChannelReestablish)
3✔
4316
                if !ok {
3✔
4317
                        return nil, errors.New("unable cast db Message to " +
×
4318
                                "ChannelReestablish")
×
4319
                }
×
4320
                c.LastChanSyncMsg = chanSync
3✔
4321
        }
4322

4323
        return c, nil
125✔
4324
}
4325

4326
func writeChanConfig(b io.Writer, c *ChannelConfig) error {
6,683✔
4327
        return WriteElements(b,
6,683✔
4328
                c.DustLimit, c.MaxPendingAmount, c.ChanReserve, c.MinHTLC,
6,683✔
4329
                c.MaxAcceptedHtlcs, c.CsvDelay, c.MultiSigKey,
6,683✔
4330
                c.RevocationBasePoint, c.PaymentBasePoint, c.DelayBasePoint,
6,683✔
4331
                c.HtlcBasePoint,
6,683✔
4332
        )
6,683✔
4333
}
6,683✔
4334

4335
// fundingTxPresent returns true if expect the funding transcation to be found
4336
// on disk or already populated within the passed open channel struct.
4337
func fundingTxPresent(channel *OpenChannel) bool {
10,518✔
4338
        chanType := channel.ChanType
10,518✔
4339

10,518✔
4340
        return chanType.IsSingleFunder() && chanType.HasFundingTx() &&
10,518✔
4341
                channel.IsInitiator &&
10,518✔
4342
                !channel.hasChanStatus(ChanStatusRestored)
10,518✔
4343
}
10,518✔
4344

4345
func putChanInfo(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
3,282✔
4346
        var w bytes.Buffer
3,282✔
4347
        if err := WriteElements(&w,
3,282✔
4348
                channel.ChanType, channel.ChainHash, channel.FundingOutpoint,
3,282✔
4349
                channel.ShortChannelID, channel.IsPending, channel.IsInitiator,
3,282✔
4350
                channel.chanStatus, channel.FundingBroadcastHeight,
3,282✔
4351
                channel.NumConfsRequired, channel.ChannelFlags,
3,282✔
4352
                channel.IdentityPub, channel.Capacity, channel.TotalMSatSent,
3,282✔
4353
                channel.TotalMSatReceived,
3,282✔
4354
        ); err != nil {
3,282✔
4355
                return err
×
4356
        }
×
4357

4358
        // For single funder channels that we initiated, and we have the
4359
        // funding transaction, then write the funding txn.
4360
        if fundingTxPresent(channel) {
5,185✔
4361
                if err := WriteElement(&w, channel.FundingTxn); err != nil {
1,903✔
4362
                        return err
×
4363
                }
×
4364
        }
4365

4366
        if err := writeChanConfig(&w, &channel.LocalChanCfg); err != nil {
3,282✔
4367
                return err
×
4368
        }
×
4369
        if err := writeChanConfig(&w, &channel.RemoteChanCfg); err != nil {
3,282✔
4370
                return err
×
4371
        }
×
4372

4373
        auxData := channel.extractTlvData()
3,282✔
4374
        if err := auxData.encode(&w); err != nil {
3,282✔
4375
                return fmt.Errorf("unable to encode aux data: %w", err)
×
4376
        }
×
4377

4378
        if err := chanBucket.Put(chanInfoKey, w.Bytes()); err != nil {
3,282✔
4379
                return err
×
4380
        }
×
4381

4382
        // Finally, add optional shutdown scripts for the local and remote peer if
4383
        // they are present.
4384
        if err := putOptionalUpfrontShutdownScript(
3,282✔
4385
                chanBucket, localUpfrontShutdownKey, channel.LocalShutdownScript,
3,282✔
4386
        ); err != nil {
3,282✔
4387
                return err
×
4388
        }
×
4389

4390
        return putOptionalUpfrontShutdownScript(
3,282✔
4391
                chanBucket, remoteUpfrontShutdownKey, channel.RemoteShutdownScript,
3,282✔
4392
        )
3,282✔
4393
}
4394

4395
// putOptionalUpfrontShutdownScript adds a shutdown script under the key
4396
// provided if it has a non-zero length.
4397
func putOptionalUpfrontShutdownScript(chanBucket kvdb.RwBucket, key []byte,
4398
        script []byte) error {
6,561✔
4399
        // If the script is empty, we do not need to add anything.
6,561✔
4400
        if len(script) == 0 {
13,112✔
4401
                return nil
6,551✔
4402
        }
6,551✔
4403

4404
        var w bytes.Buffer
13✔
4405
        if err := WriteElement(&w, script); err != nil {
13✔
4406
                return err
×
4407
        }
×
4408

4409
        return chanBucket.Put(key, w.Bytes())
13✔
4410
}
4411

4412
// getOptionalUpfrontShutdownScript reads the shutdown script stored under the
4413
// key provided if it is present. Upfront shutdown scripts are optional, so the
4414
// function returns with no error if the key is not present.
4415
func getOptionalUpfrontShutdownScript(chanBucket kvdb.RBucket, key []byte,
4416
        script *lnwire.DeliveryAddress) error {
14,475✔
4417

14,475✔
4418
        // Return early if the bucket does not exit, a shutdown script was not set.
14,475✔
4419
        bs := chanBucket.Get(key)
14,475✔
4420
        if bs == nil {
28,946✔
4421
                return nil
14,471✔
4422
        }
14,471✔
4423

4424
        var tempScript []byte
7✔
4425
        r := bytes.NewReader(bs)
7✔
4426
        if err := ReadElement(r, &tempScript); err != nil {
7✔
4427
                return err
×
4428
        }
×
4429
        *script = tempScript
7✔
4430

7✔
4431
        return nil
7✔
4432
}
4433

4434
func serializeChanCommit(w io.Writer, c *ChannelCommitment) error {
8,587✔
4435
        if err := WriteElements(w,
8,587✔
4436
                c.CommitHeight, c.LocalLogIndex, c.LocalHtlcIndex,
8,587✔
4437
                c.RemoteLogIndex, c.RemoteHtlcIndex, c.LocalBalance,
8,587✔
4438
                c.RemoteBalance, c.CommitFee, c.FeePerKw, c.CommitTx,
8,587✔
4439
                c.CommitSig,
8,587✔
4440
        ); err != nil {
8,587✔
4441
                return err
×
4442
        }
×
4443

4444
        return SerializeHtlcs(w, c.Htlcs...)
8,587✔
4445
}
4446

4447
func putChanCommitment(chanBucket kvdb.RwBucket, c *ChannelCommitment,
4448
        local bool) error {
6,517✔
4449

6,517✔
4450
        var commitKey []byte
6,517✔
4451
        if local {
9,798✔
4452
                commitKey = append(chanCommitmentKey, byte(0x00))
3,281✔
4453
        } else {
6,520✔
4454
                commitKey = append(chanCommitmentKey, byte(0x01))
3,239✔
4455
        }
3,239✔
4456

4457
        var b bytes.Buffer
6,517✔
4458
        if err := serializeChanCommit(&b, c); err != nil {
6,517✔
4459
                return err
×
4460
        }
×
4461

4462
        // Before we write to disk, we'll also write our aux data as well.
4463
        auxData := c.extractTlvData()
6,517✔
4464
        if err := auxData.encode(&b); err != nil {
6,517✔
4465
                return fmt.Errorf("unable to write aux data: %w", err)
×
4466
        }
×
4467

4468
        return chanBucket.Put(commitKey, b.Bytes())
6,517✔
4469
}
4470

4471
func putChanCommitments(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
1,261✔
4472
        // If this is a restored channel, then we don't have any commitments to
1,261✔
4473
        // write.
1,261✔
4474
        if channel.hasChanStatus(ChanStatusRestored) {
1,265✔
4475
                return nil
4✔
4476
        }
4✔
4477

4478
        err := putChanCommitment(
1,260✔
4479
                chanBucket, &channel.LocalCommitment, true,
1,260✔
4480
        )
1,260✔
4481
        if err != nil {
1,260✔
4482
                return err
×
4483
        }
×
4484

4485
        return putChanCommitment(
1,260✔
4486
                chanBucket, &channel.RemoteCommitment, false,
1,260✔
4487
        )
1,260✔
4488
}
4489

4490
func putChanRevocationState(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
3,868✔
4491
        var b bytes.Buffer
3,868✔
4492
        err := WriteElements(
3,868✔
4493
                &b, channel.RemoteCurrentRevocation, channel.RevocationProducer,
3,868✔
4494
                channel.RevocationStore,
3,868✔
4495
        )
3,868✔
4496
        if err != nil {
3,868✔
4497
                return err
×
4498
        }
×
4499

4500
        // If the next revocation is present, which is only the case after the
4501
        // ChannelReady message has been sent, then we'll write it to disk.
4502
        if channel.RemoteNextRevocation != nil {
6,949✔
4503
                err = WriteElements(&b, channel.RemoteNextRevocation)
3,081✔
4504
                if err != nil {
3,081✔
4505
                        return err
×
4506
                }
×
4507
        }
4508

4509
        return chanBucket.Put(revocationStateKey, b.Bytes())
3,868✔
4510
}
4511

4512
func readChanConfig(b io.Reader, c *ChannelConfig) error {
14,597✔
4513
        return ReadElements(b,
14,597✔
4514
                &c.DustLimit, &c.MaxPendingAmount, &c.ChanReserve,
14,597✔
4515
                &c.MinHTLC, &c.MaxAcceptedHtlcs, &c.CsvDelay,
14,597✔
4516
                &c.MultiSigKey, &c.RevocationBasePoint,
14,597✔
4517
                &c.PaymentBasePoint, &c.DelayBasePoint,
14,597✔
4518
                &c.HtlcBasePoint,
14,597✔
4519
        )
14,597✔
4520
}
14,597✔
4521

4522
func fetchChanInfo(chanBucket kvdb.RBucket, channel *OpenChannel) error {
7,239✔
4523
        infoBytes := chanBucket.Get(chanInfoKey)
7,239✔
4524
        if infoBytes == nil {
7,239✔
4525
                return ErrNoChanInfoFound
×
4526
        }
×
4527
        r := bytes.NewReader(infoBytes)
7,239✔
4528

7,239✔
4529
        if err := ReadElements(r,
7,239✔
4530
                &channel.ChanType, &channel.ChainHash, &channel.FundingOutpoint,
7,239✔
4531
                &channel.ShortChannelID, &channel.IsPending, &channel.IsInitiator,
7,239✔
4532
                &channel.chanStatus, &channel.FundingBroadcastHeight,
7,239✔
4533
                &channel.NumConfsRequired, &channel.ChannelFlags,
7,239✔
4534
                &channel.IdentityPub, &channel.Capacity, &channel.TotalMSatSent,
7,239✔
4535
                &channel.TotalMSatReceived,
7,239✔
4536
        ); err != nil {
7,239✔
4537
                return err
×
4538
        }
×
4539

4540
        // For single funder channels that we initiated and have the funding
4541
        // transaction to, read the funding txn.
4542
        if fundingTxPresent(channel) {
11,095✔
4543
                if err := ReadElement(r, &channel.FundingTxn); err != nil {
3,856✔
4544
                        return err
×
4545
                }
×
4546
        }
4547

4548
        if err := readChanConfig(r, &channel.LocalChanCfg); err != nil {
7,239✔
4549
                return err
×
4550
        }
×
4551
        if err := readChanConfig(r, &channel.RemoteChanCfg); err != nil {
7,239✔
4552
                return err
×
4553
        }
×
4554

4555
        // Retrieve the boolean stored under lastWasRevokeKey.
4556
        lastWasRevokeBytes := chanBucket.Get(lastWasRevokeKey)
7,239✔
4557
        if lastWasRevokeBytes == nil {
8,604✔
4558
                // If nothing has been stored under this key, we store false in the
1,365✔
4559
                // OpenChannel struct.
1,365✔
4560
                channel.LastWasRevoke = false
1,365✔
4561
        } else {
7,242✔
4562
                // Otherwise, read the value into the LastWasRevoke field.
5,877✔
4563
                revokeReader := bytes.NewReader(lastWasRevokeBytes)
5,877✔
4564
                err := ReadElements(revokeReader, &channel.LastWasRevoke)
5,877✔
4565
                if err != nil {
5,877✔
4566
                        return err
×
4567
                }
×
4568
        }
4569

4570
        var auxData openChannelTlvData
7,239✔
4571
        if err := auxData.decode(r); err != nil {
7,239✔
4572
                return fmt.Errorf("unable to decode aux data: %w", err)
×
4573
        }
×
4574

4575
        // Assign all the relevant fields from the aux data into the actual
4576
        // open channel.
4577
        channel.amendTlvData(auxData)
7,239✔
4578

7,239✔
4579
        channel.Packager = NewChannelPackager(channel.ShortChannelID)
7,239✔
4580

7,239✔
4581
        // Finally, read the optional shutdown scripts.
7,239✔
4582
        if err := getOptionalUpfrontShutdownScript(
7,239✔
4583
                chanBucket, localUpfrontShutdownKey, &channel.LocalShutdownScript,
7,239✔
4584
        ); err != nil {
7,239✔
4585
                return err
×
4586
        }
×
4587

4588
        return getOptionalUpfrontShutdownScript(
7,239✔
4589
                chanBucket, remoteUpfrontShutdownKey, &channel.RemoteShutdownScript,
7,239✔
4590
        )
7,239✔
4591
}
4592

4593
func deserializeChanCommit(r io.Reader) (ChannelCommitment, error) {
16,563✔
4594
        var c ChannelCommitment
16,563✔
4595

16,563✔
4596
        err := ReadElements(r,
16,563✔
4597
                &c.CommitHeight, &c.LocalLogIndex, &c.LocalHtlcIndex, &c.RemoteLogIndex,
16,563✔
4598
                &c.RemoteHtlcIndex, &c.LocalBalance, &c.RemoteBalance,
16,563✔
4599
                &c.CommitFee, &c.FeePerKw, &c.CommitTx, &c.CommitSig,
16,563✔
4600
        )
16,563✔
4601
        if err != nil {
16,563✔
4602
                return c, err
×
4603
        }
×
4604

4605
        c.Htlcs, err = DeserializeHtlcs(r)
16,563✔
4606
        if err != nil {
16,563✔
4607
                return c, err
×
4608
        }
×
4609

4610
        return c, nil
16,563✔
4611
}
4612

4613
func fetchChanCommitment(chanBucket kvdb.RBucket,
4614
        local bool) (ChannelCommitment, error) {
14,502✔
4615

14,502✔
4616
        var commitKey []byte
14,502✔
4617
        if local {
21,755✔
4618
                commitKey = append(chanCommitmentKey, byte(0x00))
7,253✔
4619
        } else {
14,505✔
4620
                commitKey = append(chanCommitmentKey, byte(0x01))
7,252✔
4621
        }
7,252✔
4622

4623
        commitBytes := chanBucket.Get(commitKey)
14,502✔
4624
        if commitBytes == nil {
14,502✔
4625
                return ChannelCommitment{}, ErrNoCommitmentsFound
×
4626
        }
×
4627

4628
        r := bytes.NewReader(commitBytes)
14,502✔
4629
        chanCommit, err := deserializeChanCommit(r)
14,502✔
4630
        if err != nil {
14,502✔
4631
                return ChannelCommitment{}, fmt.Errorf("unable to decode "+
×
4632
                        "chan commit: %w", err)
×
4633
        }
×
4634

4635
        // We'll also check to see if we have any aux data stored as the end of
4636
        // the stream.
4637
        var auxData commitTlvData
14,502✔
4638
        if err := auxData.decode(r); err != nil {
14,502✔
4639
                return ChannelCommitment{}, fmt.Errorf("unable to decode "+
×
4640
                        "chan aux data: %w", err)
×
4641
        }
×
4642

4643
        chanCommit.amendTlvData(auxData)
14,502✔
4644

14,502✔
4645
        return chanCommit, nil
14,502✔
4646
}
4647

4648
func fetchChanCommitments(chanBucket kvdb.RBucket, channel *OpenChannel) error {
7,254✔
4649
        var err error
7,254✔
4650

7,254✔
4651
        // If this is a restored channel, then we don't have any commitments to
7,254✔
4652
        // read.
7,254✔
4653
        if channel.hasChanStatus(ChanStatusRestored) {
7,259✔
4654
                return nil
5✔
4655
        }
5✔
4656

4657
        channel.LocalCommitment, err = fetchChanCommitment(chanBucket, true)
7,252✔
4658
        if err != nil {
7,252✔
4659
                return err
×
4660
        }
×
4661
        channel.RemoteCommitment, err = fetchChanCommitment(chanBucket, false)
7,252✔
4662
        if err != nil {
7,252✔
4663
                return err
×
4664
        }
×
4665

4666
        return nil
7,252✔
4667
}
4668

4669
func fetchChanRevocationState(chanBucket kvdb.RBucket, channel *OpenChannel) error {
7,254✔
4670
        revBytes := chanBucket.Get(revocationStateKey)
7,254✔
4671
        if revBytes == nil {
7,254✔
4672
                return ErrNoRevocationsFound
×
4673
        }
×
4674
        r := bytes.NewReader(revBytes)
7,254✔
4675

7,254✔
4676
        err := ReadElements(
7,254✔
4677
                r, &channel.RemoteCurrentRevocation, &channel.RevocationProducer,
7,254✔
4678
                &channel.RevocationStore,
7,254✔
4679
        )
7,254✔
4680
        if err != nil {
7,254✔
4681
                return err
×
4682
        }
×
4683

4684
        // If there aren't any bytes left in the buffer, then we don't yet have
4685
        // the next remote revocation, so we can exit early here.
4686
        if r.Len() == 0 {
7,489✔
4687
                return nil
235✔
4688
        }
235✔
4689

4690
        // Otherwise we'll read the next revocation for the remote party which
4691
        // is always the last item within the buffer.
4692
        return ReadElements(r, &channel.RemoteNextRevocation)
7,022✔
4693
}
4694

4695
func deleteOpenChannel(chanBucket kvdb.RwBucket) error {
118✔
4696
        if err := chanBucket.Delete(chanInfoKey); err != nil {
118✔
4697
                return err
×
4698
        }
×
4699

4700
        err := chanBucket.Delete(append(chanCommitmentKey, byte(0x00)))
118✔
4701
        if err != nil {
118✔
4702
                return err
×
4703
        }
×
4704
        err = chanBucket.Delete(append(chanCommitmentKey, byte(0x01)))
118✔
4705
        if err != nil {
118✔
4706
                return err
×
4707
        }
×
4708

4709
        if err := chanBucket.Delete(revocationStateKey); err != nil {
118✔
4710
                return err
×
4711
        }
×
4712

4713
        if diff := chanBucket.Get(commitDiffKey); diff != nil {
121✔
4714
                return chanBucket.Delete(commitDiffKey)
3✔
4715
        }
3✔
4716

4717
        return nil
118✔
4718
}
4719

4720
// makeLogKey converts a uint64 into an 8 byte array.
4721
func makeLogKey(updateNum uint64) [8]byte {
10,151✔
4722
        var key [8]byte
10,151✔
4723
        byteOrder.PutUint64(key[:], updateNum)
10,151✔
4724
        return key
10,151✔
4725
}
10,151✔
4726

4727
func fetchThawHeight(chanBucket kvdb.RBucket) (uint32, error) {
348✔
4728
        var height uint32
348✔
4729

348✔
4730
        heightBytes := chanBucket.Get(frozenChanKey)
348✔
4731
        heightReader := bytes.NewReader(heightBytes)
348✔
4732

348✔
4733
        if err := ReadElements(heightReader, &height); err != nil {
348✔
4734
                return 0, err
×
4735
        }
×
4736

4737
        return height, nil
348✔
4738
}
4739

4740
func storeThawHeight(chanBucket kvdb.RwBucket, height uint32) error {
439✔
4741
        var heightBuf bytes.Buffer
439✔
4742
        if err := WriteElements(&heightBuf, height); err != nil {
439✔
4743
                return err
×
4744
        }
×
4745

4746
        return chanBucket.Put(frozenChanKey, heightBuf.Bytes())
439✔
4747
}
4748

4749
func deleteThawHeight(chanBucket kvdb.RwBucket) error {
111✔
4750
        return chanBucket.Delete(frozenChanKey)
111✔
4751
}
111✔
4752

4753
// keyLocRecord is a wrapper struct around keychain.KeyLocator to implement the
4754
// tlv.RecordProducer interface.
4755
type keyLocRecord struct {
4756
        keychain.KeyLocator
4757
}
4758

4759
// Record creates a Record out of a KeyLocator using the passed Type and the
4760
// EKeyLocator and DKeyLocator functions. The size will always be 8 as
4761
// KeyFamily is uint32 and the Index is uint32.
4762
//
4763
// NOTE: This is part of the tlv.RecordProducer interface.
4764
func (k *keyLocRecord) Record() tlv.Record {
10,518✔
4765
        // Note that we set the type here as zero, as when used with a
10,518✔
4766
        // tlv.RecordT, the type param will be used as the type.
10,518✔
4767
        return tlv.MakeStaticRecord(
10,518✔
4768
                0, &k.KeyLocator, 8, EKeyLocator, DKeyLocator,
10,518✔
4769
        )
10,518✔
4770
}
10,518✔
4771

4772
// EKeyLocator is an encoder for keychain.KeyLocator.
4773
func EKeyLocator(w io.Writer, val interface{}, buf *[8]byte) error {
3,283✔
4774
        if v, ok := val.(*keychain.KeyLocator); ok {
6,566✔
4775
                err := tlv.EUint32T(w, uint32(v.Family), buf)
3,283✔
4776
                if err != nil {
3,283✔
4777
                        return err
×
4778
                }
×
4779

4780
                return tlv.EUint32T(w, v.Index, buf)
3,283✔
4781
        }
4782
        return tlv.NewTypeForEncodingErr(val, "keychain.KeyLocator")
×
4783
}
4784

4785
// DKeyLocator is a decoder for keychain.KeyLocator.
4786
func DKeyLocator(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
7,240✔
4787
        if v, ok := val.(*keychain.KeyLocator); ok {
14,480✔
4788
                var family uint32
7,240✔
4789
                err := tlv.DUint32(r, &family, buf, 4)
7,240✔
4790
                if err != nil {
7,240✔
4791
                        return err
×
4792
                }
×
4793
                v.Family = keychain.KeyFamily(family)
7,240✔
4794

7,240✔
4795
                return tlv.DUint32(r, &v.Index, buf, 4)
7,240✔
4796
        }
4797
        return tlv.NewTypeForDecodingErr(val, "keychain.KeyLocator", l, 8)
×
4798
}
4799

4800
// ShutdownInfo contains various info about the shutdown initiation of a
4801
// channel.
4802
type ShutdownInfo struct {
4803
        // DeliveryScript is the address that we have included in any previous
4804
        // Shutdown message for a particular channel and so should include in
4805
        // any future re-sends of the Shutdown message.
4806
        DeliveryScript tlv.RecordT[tlv.TlvType0, lnwire.DeliveryAddress]
4807

4808
        // LocalInitiator is true if we sent a Shutdown message before ever
4809
        // receiving a Shutdown message from the remote peer.
4810
        LocalInitiator tlv.RecordT[tlv.TlvType1, bool]
4811
}
4812

4813
// NewShutdownInfo constructs a new ShutdownInfo object.
4814
func NewShutdownInfo(deliveryScript lnwire.DeliveryAddress,
4815
        locallyInitiated bool) *ShutdownInfo {
16✔
4816

16✔
4817
        return &ShutdownInfo{
16✔
4818
                DeliveryScript: tlv.NewRecordT[tlv.TlvType0](deliveryScript),
16✔
4819
                LocalInitiator: tlv.NewPrimitiveRecord[tlv.TlvType1](
16✔
4820
                        locallyInitiated,
16✔
4821
                ),
16✔
4822
        }
16✔
4823
}
16✔
4824

4825
// Closer identifies the ChannelParty that initiated the coop-closure process.
4826
func (s ShutdownInfo) Closer() lntypes.ChannelParty {
3✔
4827
        if s.LocalInitiator.Val {
6✔
4828
                return lntypes.Local
3✔
4829
        }
3✔
4830

4831
        return lntypes.Remote
3✔
4832
}
4833

4834
// encode serialises the ShutdownInfo to the given io.Writer.
4835
func (s *ShutdownInfo) encode(w io.Writer) error {
14✔
4836
        records := []tlv.Record{
14✔
4837
                s.DeliveryScript.Record(),
14✔
4838
                s.LocalInitiator.Record(),
14✔
4839
        }
14✔
4840

14✔
4841
        stream, err := tlv.NewStream(records...)
14✔
4842
        if err != nil {
14✔
4843
                return err
×
4844
        }
×
4845

4846
        return stream.Encode(w)
14✔
4847
}
4848

4849
// decodeShutdownInfo constructs a ShutdownInfo struct by decoding the given
4850
// byte slice.
4851
func decodeShutdownInfo(b []byte) (*ShutdownInfo, error) {
5✔
4852
        tlvStream := lnwire.ExtraOpaqueData(b)
5✔
4853

5✔
4854
        var info ShutdownInfo
5✔
4855
        records := []tlv.RecordProducer{
5✔
4856
                &info.DeliveryScript,
5✔
4857
                &info.LocalInitiator,
5✔
4858
        }
5✔
4859

5✔
4860
        _, err := tlvStream.ExtractRecords(records...)
5✔
4861

5✔
4862
        return &info, err
5✔
4863
}
5✔
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