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

lightningnetwork / lnd / 11216766535

07 Oct 2024 01:37PM UTC coverage: 57.817% (-1.0%) from 58.817%
11216766535

Pull #9148

github

ProofOfKeags
lnwire: remove kickoff feerate from propose/commit
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

571 of 879 new or added lines in 16 files covered. (64.96%)

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 hits per line

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

73.48
/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/channeldb/models"
23
        "github.com/lightningnetwork/lnd/fn"
24
        "github.com/lightningnetwork/lnd/htlcswitch/hop"
25
        "github.com/lightningnetwork/lnd/input"
26
        "github.com/lightningnetwork/lnd/keychain"
27
        "github.com/lightningnetwork/lnd/kvdb"
28
        "github.com/lightningnetwork/lnd/lntypes"
29
        "github.com/lightningnetwork/lnd/lnwire"
30
        "github.com/lightningnetwork/lnd/shachain"
31
        "github.com/lightningnetwork/lnd/tlv"
32
)
33

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

291
        return tlvStream.Encode(w)
4,624✔
292
}
293

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

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

314
        tlvs, err := tlvStream.DecodeWithParsedTypes(r)
11,349✔
315
        if err != nil {
11,349✔
316
                return err
×
317
        }
×
318

319
        if _, ok := tlvs[memo.TlvType()]; ok {
11,676✔
320
                c.memo = tlv.SomeRecordT(memo)
327✔
321
        }
327✔
322
        if _, ok := tlvs[tapscriptRoot.TlvType()]; ok {
11,784✔
323
                c.tapscriptRoot = tlv.SomeRecordT(tapscriptRoot)
435✔
324
        }
435✔
325
        if _, ok := tlvs[c.customBlob.TlvType()]; ok {
11,676✔
326
                c.customBlob = tlv.SomeRecordT(blob)
327✔
327
        }
327✔
328

329
        return nil
11,349✔
330
}
331

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

612
        return tlvStream.Encode(w)
12,644✔
613
}
614

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

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

626
        tlvs, err := tlvStream.DecodeWithParsedTypes(r)
26,166✔
627
        if err != nil {
26,166✔
628
                return err
×
629
        }
×
630

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

635
        return nil
26,166✔
636
}
637

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

12,644✔
731
        c.CustomBlob.WhenSome(func(blob tlv.Blob) {
13,489✔
732
                auxData.customBlob = tlv.SomeRecordT(
845✔
733
                        tlv.NewPrimitiveRecord[tlv.TlvType1](blob),
845✔
734
                )
845✔
735
        })
845✔
736

737
        return auxData
12,644✔
738
}
739

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1✔
841
        return statusStr
1✔
842
}
843

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1046
        sync.RWMutex
1047
}
1048

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

×
UNCOV
1054
        commit := c.LocalCommitment
×
UNCOV
1055
        local := fmt.Sprintf(indexStr, commit.CommitHeight,
×
UNCOV
1056
                commit.LocalHtlcIndex, commit.LocalLogIndex,
×
UNCOV
1057
                commit.RemoteHtlcIndex, commit.RemoteLogIndex,
×
UNCOV
1058
        )
×
UNCOV
1059

×
UNCOV
1060
        commit = c.RemoteCommitment
×
UNCOV
1061
        remote := fmt.Sprintf(indexStr, commit.CommitHeight,
×
UNCOV
1062
                commit.LocalHtlcIndex, commit.LocalLogIndex,
×
UNCOV
1063
                commit.RemoteHtlcIndex, commit.RemoteLogIndex,
×
UNCOV
1064
        )
×
UNCOV
1065

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

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

26,157✔
1078
        if c.IsInitiator {
41,707✔
1079
                return lntypes.Local
15,550✔
1080
        }
15,550✔
1081

1082
        return lntypes.Remote
10,607✔
1083
}
1084

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

14,472✔
1090
        return c.ShortChannelID
14,472✔
1091
}
14,472✔
1092

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

9✔
1099
        return c.confirmedScid
9✔
1100
}
9✔
1101

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

5✔
1108
        return c.confirmedScid != hop.Source
5✔
1109
}
5✔
1110

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

643✔
1116
        return c.ChanType.HasZeroConf()
643✔
1117
}
643✔
1118

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

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

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

482✔
1134
        return c.ChanType.HasScidAliasFeature()
482✔
1135
}
482✔
1136

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

211✔
1142
        return c.chanStatus
211✔
1143
}
211✔
1144

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

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

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

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

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

373✔
1170
        return c.hasChanStatus(status)
373✔
1171
}
373✔
1172

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

1180
        return c.chanStatus&status == status
31,903✔
1181
}
1182

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

103✔
1188
        return c.FundingBroadcastHeight
103✔
1189
}
103✔
1190

1191
// SetBroadcastHeight sets the FundingBroadcastHeight.
UNCOV
1192
func (c *OpenChannel) SetBroadcastHeight(height uint32) {
×
UNCOV
1193
        c.Lock()
×
UNCOV
1194
        defer c.Unlock()
×
UNCOV
1195

×
UNCOV
1196
        c.FundingBroadcastHeight = height
×
UNCOV
1197
}
×
1198

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

11,349✔
1210
        auxData.memo.WhenSomeV(func(memo []byte) {
11,676✔
1211
                c.Memo = memo
327✔
1212
        })
327✔
1213
        auxData.tapscriptRoot.WhenSomeV(func(h [32]byte) {
11,784✔
1214
                c.TapscriptRoot = fn.Some[chainhash.Hash](h)
435✔
1215
        })
435✔
1216
        auxData.customBlob.WhenSomeV(func(blob tlv.Blob) {
11,676✔
1217
                c.CustomBlob = fn.Some(blob)
327✔
1218
        })
327✔
1219
}
1220

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

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

1254
        return auxData
4,624✔
1255
}
1256

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

5✔
1263
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
10✔
1264
                chanBucket, err := fetchChanBucket(
5✔
1265
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
5✔
1266
                )
5✔
1267
                if err != nil {
5✔
UNCOV
1268
                        return err
×
UNCOV
1269
                }
×
1270

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

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

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

1290
                return nil
5✔
1291
        }, func() {})
5✔
1292
        if err != nil {
5✔
UNCOV
1293
                return err
×
UNCOV
1294
        }
×
1295

1296
        return nil
5✔
1297
}
1298

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

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

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

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

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

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

1341
        return chanBucket, nil
1,830✔
1342
}
1343

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

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

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

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

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

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

1388
        return chanBucket, nil
11,076✔
1389
}
1390

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

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

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

1408
        return chanBucket, nil
3✔
1409
}
1410

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

1424
        var chanPointBuf bytes.Buffer
873✔
1425
        if err := writeOutpoint(&chanPointBuf, &c.FundingOutpoint); err != nil {
873✔
1426
                return err
×
1427
        }
×
1428

1429
        // Now, check if the outpoint exists in our index.
1430
        if opBucket.Get(chanPointBuf.Bytes()) != nil {
873✔
UNCOV
1431
                return ErrChanAlreadyExists
×
UNCOV
1432
        }
×
1433

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

1439
        status := uint8(outpointOpen)
873✔
1440

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

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

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

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

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

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

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

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

1499
        return putOpenChannel(chanBucket, c)
873✔
1500
}
1501

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

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

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

1521
                channel.IsPending = false
163✔
1522
                channel.ShortChannelID = openLoc
163✔
1523

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

1529
        c.IsPending = false
163✔
1530
        c.ShortChannelID = openLoc
163✔
1531
        c.Packager = NewChannelPackager(openLoc)
163✔
1532

163✔
1533
        return nil
163✔
1534
}
1535

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

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

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

1557
                channel.confirmedScid = realScid
7✔
1558

7✔
1559
                return putOpenChannel(chanBucket, channel)
7✔
1560
        }, func() {}); err != nil {
7✔
1561
                return err
×
1562
        }
×
1563

1564
        c.confirmedScid = realScid
7✔
1565

7✔
1566
        return nil
7✔
1567
}
1568

1569
// MarkScidAliasNegotiated adds ScidAliasFeatureBit to ChanType in-memory and
1570
// in the database.
UNCOV
1571
func (c *OpenChannel) MarkScidAliasNegotiated() error {
×
UNCOV
1572
        c.Lock()
×
UNCOV
1573
        defer c.Unlock()
×
UNCOV
1574

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

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

UNCOV
1590
                channel.ChanType |= ScidAliasFeatureBit
×
UNCOV
1591
                return putOpenChannel(chanBucket, channel)
×
UNCOV
1592
        }, func() {}); err != nil {
×
1593
                return err
×
1594
        }
×
1595

UNCOV
1596
        c.ChanType |= ScidAliasFeatureBit
×
UNCOV
1597

×
UNCOV
1598
        return nil
×
1599
}
1600

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

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

1613
        putCommitPoint := func(chanBucket kvdb.RwBucket) error {
8✔
1614
                return chanBucket.Put(dataLossCommitPointKey, b.Bytes())
4✔
1615
        }
4✔
1616

1617
        return c.putChanStatus(ChanStatusLocalDataLoss, putCommitPoint)
4✔
1618
}
1619

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

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

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

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

1654
        return commitPoint, nil
4✔
1655
}
1656

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

2✔
1664
        return c.putChanStatus(ChanStatusBorked)
2✔
1665
}
2✔
1666

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

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

UNCOV
1680
        return input.ComputeCommitmentPoint(revocation[:]), nil
×
1681
}
1682

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

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

1701
        revRootHash := chainhash.HashH(rootHashBuf.Bytes())
971✔
1702

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

1712
        taprootRevRoot := taprootRevHmac.Sum(nil)
971✔
1713

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

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

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

1736
        shaChainRand := musig2.WithCustomRand(bytes.NewBuffer(nextPreimage[:]))
215✔
1737
        pubKeyOpt := musig2.WithPublicKey(pubKey)
215✔
1738

215✔
1739
        return musig2.GenNonces(pubKeyOpt, shaChainRand)
215✔
1740
}
1741

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

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

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

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

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

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

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

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

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

1834
                nextTaprootNonce = lnwire.SomeMusig2Nonce(nextNonce.PubNonce)
21✔
1835
        }
1836

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

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

11✔
1859
        return c.storeShutdownInfo(info)
11✔
1860
}
11✔
1861

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

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

1879
                return chanBucket.Put(shutdownInfoKey, b.Bytes())
11✔
1880
        }, func() {})
11✔
1881
}
1882

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

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

×
UNCOV
1901
                        return ErrNoShutdownInfo
×
1902
                default:
×
1903
                        return err
×
1904
                }
1905

1906
                shutdownInfoBytes := chanBucket.Get(shutdownInfoKey)
4✔
1907
                if shutdownInfoBytes == nil {
6✔
1908
                        return ErrNoShutdownInfo
2✔
1909
                }
2✔
1910

1911
                shutdownInfo, err = decodeShutdownInfo(shutdownInfoBytes)
2✔
1912

2✔
1913
                return err
2✔
1914
        }, func() {
4✔
1915
                shutdownInfo = nil
4✔
1916
        })
4✔
1917
        if err != nil {
6✔
1918
                return fn.None[ShutdownInfo](), err
2✔
1919
        }
2✔
1920

1921
        return fn.Some[ShutdownInfo](*shutdownInfo), nil
2✔
1922
}
1923

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

1935
        return channel.chanStatus != ChanStatusDefault, nil
10,219✔
1936
}
1937

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

8✔
1947
        return c.markBroadcasted(
8✔
1948
                ChanStatusCommitBroadcasted, forceCloseTxKey, closeTx,
8✔
1949
                closer,
8✔
1950
        )
8✔
1951
}
8✔
1952

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

38✔
1963
        return c.markBroadcasted(
38✔
1964
                ChanStatusCoopBroadcasted, coopCloseTxKey, closeTx,
38✔
1965
                closer,
38✔
1966
        )
38✔
1967
}
38✔
1968

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

46✔
1976
        c.Lock()
46✔
1977
        defer c.Unlock()
46✔
1978

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

1988
                putClosingTx = func(chanBucket kvdb.RwBucket) error {
42✔
1989
                        return chanBucket.Put(key, b.Bytes())
21✔
1990
                }
21✔
1991
        }
1992

1993
        // Add the initiator status to the status provided. These statuses are
1994
        // set in addition to the broadcast status so that we do not need to
1995
        // migrate the original logic which does not store initiator.
1996
        if closer.IsLocal() {
86✔
1997
                status |= ChanStatusLocalCloseInitiator
40✔
1998
        } else {
46✔
1999
                status |= ChanStatusRemoteCloseInitiator
6✔
2000
        }
6✔
2001

2002
        return c.putChanStatus(status, putClosingTx)
46✔
2003
}
2004

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

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

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

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

2034
                bs := chanBucket.Get(key)
16✔
2035
                if bs == nil {
18✔
2036
                        return ErrNoCloseTx
2✔
2037
                }
2✔
2038
                r := bytes.NewReader(bs)
14✔
2039
                return ReadElement(r, &closeTx)
14✔
2040
        }, func() {
16✔
2041
                closeTx = nil
16✔
2042
        })
16✔
2043
        if err != nil {
18✔
2044
                return nil, err
2✔
2045
        }
2✔
2046

2047
        return closeTx, nil
14✔
2048
}
2049

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

55✔
2056
        if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
109✔
2057
                chanBucket, err := fetchChanBucketRw(
54✔
2058
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
54✔
2059
                )
54✔
2060
                if err != nil {
54✔
2061
                        return err
×
2062
                }
×
2063

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

2069
                // Add this status to the existing bitvector found in the DB.
2070
                status = channel.chanStatus | status
54✔
2071
                channel.chanStatus = status
54✔
2072

54✔
2073
                if err := putOpenChannel(chanBucket, channel); err != nil {
54✔
2074
                        return err
×
2075
                }
×
2076

2077
                for _, f := range fs {
103✔
2078
                        // Skip execution of nil closures.
49✔
2079
                        if f == nil {
73✔
2080
                                continue
24✔
2081
                        }
2082

2083
                        if err := f(chanBucket); err != nil {
25✔
2084
                                return err
×
2085
                        }
×
2086
                }
2087

2088
                return nil
54✔
2089
        }, func() {}); err != nil {
56✔
2090
                return err
1✔
2091
        }
1✔
2092

2093
        // Update the in-memory representation to keep it in sync with the DB.
2094
        c.chanStatus = status
54✔
2095

54✔
2096
        return nil
54✔
2097
}
2098

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

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

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

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

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

4✔
2125
        return nil
4✔
2126
}
2127

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

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

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

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

2161
        return nil
1,215✔
2162
}
2163

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

11,344✔
2169
        channel := &OpenChannel{
11,344✔
2170
                FundingOutpoint: *chanPoint,
11,344✔
2171
        }
11,344✔
2172

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

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

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

2195
                channel.ThawHeight = thawHeight
334✔
2196
        }
2197

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

2205
        channel.Packager = NewChannelPackager(channel.ShortChannelID)
11,344✔
2206

11,344✔
2207
        return channel, nil
11,344✔
2208
}
2209

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

872✔
2225
        c.FundingBroadcastHeight = pendingHeight
872✔
2226

872✔
2227
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
1,744✔
2228
                return syncNewChannel(tx, c, []net.Addr{addr})
872✔
2229
        }, func() {})
1,744✔
2230
}
2231

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

2240
        nodeInfoBucket, err := tx.CreateTopLevelBucket(nodeInfoBucket)
873✔
2241
        if err != nil {
873✔
2242
                return err
×
2243
        }
×
2244

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

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

730✔
2260
        // TODO(roasbeef): do away with link node all together?
730✔
2261

730✔
2262
        return putLinkNode(nodeInfoBucket, linkNode)
730✔
2263
}
2264

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

3,411✔
2280
        c.Lock()
3,411✔
2281
        defer c.Unlock()
3,411✔
2282

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

2290
        var finalHtlcs = make(map[uint64]bool)
3,410✔
2291

3,410✔
2292
        err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
6,820✔
2293
                chanBucket, err := fetchChanBucketRw(
3,410✔
2294
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
3,410✔
2295
                )
3,410✔
2296
                if err != nil {
3,410✔
2297
                        return err
×
2298
                }
×
2299

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

2310
                if err = putChanInfo(chanBucket, c); err != nil {
3,409✔
2311
                        return fmt.Errorf("unable to store chan info: %w", err)
×
2312
                }
×
2313

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

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

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

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

2345
                if err := chanBucket.Put(lastWasRevokeKey, b2.Bytes()); err != nil {
3,409✔
2346
                        return err
×
2347
                }
×
2348

2349
                // Persist the remote unsigned local updates that are not included
2350
                // in our new commitment.
2351
                updateBytes := chanBucket.Get(remoteUnsignedLocalUpdatesKey)
3,409✔
2352
                if updateBytes == nil {
3,928✔
2353
                        return nil
519✔
2354
                }
519✔
2355

2356
                r := bytes.NewReader(updateBytes)
2,890✔
2357
                updates, err := deserializeLogUpdates(r)
2,890✔
2358
                if err != nil {
2,890✔
2359
                        return err
×
2360
                }
×
2361

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

2373
                        finalHtlcsBucket = bucket
1✔
2374
                }
2375

2376
                var unsignedUpdates []LogUpdate
2,890✔
2377
                for _, upd := range updates {
3,754✔
2378
                        // Gather updates that are not on our local commitment.
864✔
2379
                        if upd.LogIndex >= newCommitment.LocalLogIndex {
864✔
2380
                                unsignedUpdates = append(unsignedUpdates, upd)
×
2381

×
2382
                                continue
×
2383
                        }
2384

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

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

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

2408
                return nil
2,890✔
2409
        }, func() {
3,410✔
2410
                finalHtlcs = make(map[uint64]bool)
3,410✔
2411
        })
3,410✔
2412
        if err != nil {
3,411✔
2413
                return nil, err
1✔
2414
        }
1✔
2415

2416
        c.LocalCommitment = *newCommitment
3,409✔
2417

3,409✔
2418
        return finalHtlcs, nil
3,409✔
2419
}
2420

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

864✔
2426
        var (
864✔
2427
                settled bool
864✔
2428
                id      uint64
864✔
2429
        )
864✔
2430

864✔
2431
        switch msg := upd.UpdateMsg.(type) {
864✔
2432
        case *lnwire.UpdateFulfillHTLC:
722✔
2433
                settled = true
722✔
2434
                id = msg.ID
722✔
2435

2436
        case *lnwire.UpdateFailHTLC:
131✔
2437
                settled = false
131✔
2438
                id = msg.ID
131✔
2439

2440
        case *lnwire.UpdateFailMalformedHTLC:
3✔
2441
                settled = false
3✔
2442
                id = msg.ID
3✔
2443

2444
        default:
8✔
2445
                return nil
8✔
2446
        }
2447

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

2462
        finalHtlcs[id] = settled
856✔
2463

856✔
2464
        return nil
856✔
2465
}
2466

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

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

451,460✔
2482
                onionHash := sha256.Sum256(htlc.OnionBlob[:])
451,460✔
2483
                remoteHtlcs[onionHash] = struct{}{}
451,460✔
2484
        }
451,460✔
2485

2486
        // Now that we know which HTLC's they have, we'll only mark the HTLC's
2487
        // as active if *we* know them as well.
2488
        activeHtlcs := make([]HTLC, 0, len(remoteHtlcs))
3,382✔
2489
        for _, htlc := range c.LocalCommitment.Htlcs {
455,164✔
2490
                log.Tracef("LocalCommitment has htlc: id=%v, update=%v "+
451,782✔
2491
                        "incoming=%v", htlc.HtlcIndex, htlc.LogIndex,
451,782✔
2492
                        htlc.Incoming)
451,782✔
2493

451,782✔
2494
                onionHash := sha256.Sum256(htlc.OnionBlob[:])
451,782✔
2495
                if _, ok := remoteHtlcs[onionHash]; !ok {
452,066✔
2496
                        log.Tracef("Skipped htlc due to onion mismatched: "+
284✔
2497
                                "id=%v, update=%v incoming=%v",
284✔
2498
                                htlc.HtlcIndex, htlc.LogIndex, htlc.Incoming)
284✔
2499

284✔
2500
                        continue
284✔
2501
                }
2502

2503
                activeHtlcs = append(activeHtlcs, htlc)
451,498✔
2504
        }
2505

2506
        return activeHtlcs
3,382✔
2507
}
2508

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

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

2525
        // RHash is the payment hash of the HTLC.
2526
        RHash [32]byte
2527

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

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

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

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

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

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

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

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

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

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

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

4✔
2604
                records = append(records, &b)
4✔
2605
        })
4✔
2606

2607
        records, err := h.CustomRecords.ExtendRecordProducers(records)
1,230,653✔
2608
        if err != nil {
1,230,653✔
2609
                return err
×
2610
        }
×
2611

2612
        return h.ExtraData.PackRecords(records...)
1,230,653✔
2613
}
2614

2615
// deserializeExtraData extracts TLVs from the extra data persisted for the
2616
// htlc and populates values in the struct accordingly.
2617
//
2618
// This function MUST be called to populate the struct properly when HTLCs
2619
// are deserialized.
2620
func (h *HTLC) deserializeExtraData() error {
2,863,213✔
2621
        if len(h.ExtraData) == 0 {
5,722,313✔
2622
                return nil
2,859,100✔
2623
        }
2,859,100✔
2624

2625
        blindingPoint := h.BlindingPoint.Zero()
4,113✔
2626
        tlvMap, err := h.ExtraData.ExtractRecords(&blindingPoint)
4,113✔
2627
        if err != nil {
4,113✔
2628
                return err
×
2629
        }
×
2630

2631
        if val, ok := tlvMap[h.BlindingPoint.TlvType()]; ok && val == nil {
4,117✔
2632
                h.BlindingPoint = tlv.SomeRecordT(blindingPoint)
4✔
2633

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

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

4,113✔
2646
        return nil
4,113✔
2647
}
2648

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

2669
        for _, htlc := range htlcs {
1,243,318✔
2670
                // Populate TLV stream for any additional fields contained
1,230,653✔
2671
                // in the TLV.
1,230,653✔
2672
                if err := htlc.serializeExtraData(); err != nil {
1,230,653✔
2673
                        return err
×
2674
                }
×
2675

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

1,230,653✔
2684
                if err := WriteElements(b,
1,230,653✔
2685
                        htlc.Signature, htlc.RHash, htlc.Amt, htlc.RefundTimeout,
1,230,653✔
2686
                        htlc.OutputIndex, htlc.Incoming, onionAndExtraData,
1,230,653✔
2687
                        htlc.HtlcIndex, htlc.LogIndex,
1,230,653✔
2688
                ); err != nil {
1,230,653✔
2689
                        return err
×
2690
                }
×
2691
        }
2692

2693
        return nil
12,665✔
2694
}
2695

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

2719
        var htlcs []HTLC
26,186✔
2720
        if numHtlcs == 0 {
33,447✔
2721
                return htlcs, nil
7,261✔
2722
        }
7,261✔
2723

2724
        htlcs = make([]HTLC, numHtlcs)
18,925✔
2725
        for i := uint16(0); i < numHtlcs; i++ {
2,882,139✔
2726
                var onionAndExtraData []byte
2,863,214✔
2727
                if err := ReadElements(r,
2,863,214✔
2728
                        &htlcs[i].Signature, &htlcs[i].RHash, &htlcs[i].Amt,
2,863,214✔
2729
                        &htlcs[i].RefundTimeout, &htlcs[i].OutputIndex,
2,863,214✔
2730
                        &htlcs[i].Incoming, &onionAndExtraData,
2,863,214✔
2731
                        &htlcs[i].HtlcIndex, &htlcs[i].LogIndex,
2,863,214✔
2732
                ); err != nil {
2,863,214✔
2733
                        return htlcs, err
×
2734
                }
×
2735

2736
                // Sanity check that we have at least the onion blob size we
2737
                // expect.
2738
                if len(onionAndExtraData) < lnwire.OnionPacketSize {
2,863,215✔
2739
                        return nil, ErrOnionBlobLength
1✔
2740
                }
1✔
2741

2742
                // First OnionPacketSize bytes are our fixed length onion
2743
                // packet.
2744
                copy(
2,863,213✔
2745
                        htlcs[i].OnionBlob[:],
2,863,213✔
2746
                        onionAndExtraData[0:lnwire.OnionPacketSize],
2,863,213✔
2747
                )
2,863,213✔
2748

2,863,213✔
2749
                // Any additional bytes belong to extra data. ExtraDataLen
2,863,213✔
2750
                // will be >= 0, because we know that we always have a fixed
2,863,213✔
2751
                // length onion packet.
2,863,213✔
2752
                extraDataLen := len(onionAndExtraData) - lnwire.OnionPacketSize
2,863,213✔
2753
                if extraDataLen > 0 {
2,867,326✔
2754
                        htlcs[i].ExtraData = make([]byte, extraDataLen)
4,113✔
2755

4,113✔
2756
                        copy(
4,113✔
2757
                                htlcs[i].ExtraData,
4,113✔
2758
                                onionAndExtraData[lnwire.OnionPacketSize:],
4,113✔
2759
                        )
4,113✔
2760
                }
4,113✔
2761

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

2769
        return htlcs, nil
18,924✔
2770
}
2771

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

4,717✔
2786
        return clone
4,717✔
2787
}
4,717✔
2788

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

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

2803
// serializeLogUpdate writes a log update to the provided io.Writer.
2804
func serializeLogUpdate(w io.Writer, l *LogUpdate) error {
2,720✔
2805
        return WriteElements(w, l.LogIndex, l.UpdateMsg)
2,720✔
2806
}
2,720✔
2807

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

2815
        return l, nil
3,254✔
2816
}
2817

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

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

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

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

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

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

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

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

2880
        for _, diff := range logUpdates {
25,201✔
2881
                err := WriteElements(w, diff.LogIndex, diff.UpdateMsg)
9,153✔
2882
                if err != nil {
9,153✔
2883
                        return err
×
2884
                }
×
2885
        }
2886

2887
        return nil
16,048✔
2888
}
2889

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

2897
        logUpdates := make([]LogUpdate, numUpdates)
9,596✔
2898
        for i := 0; i < int(numUpdates); i++ {
17,343✔
2899
                err := ReadElements(r,
7,747✔
2900
                        &logUpdates[i].LogIndex, &logUpdates[i].UpdateMsg,
7,747✔
2901
                )
7,747✔
2902
                if err != nil {
7,747✔
2903
                        return nil, err
×
2904
                }
×
2905
        }
2906
        return logUpdates, nil
9,596✔
2907
}
2908

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

2914
        if err := WriteElements(w, diff.CommitSig); err != nil {
3,447✔
2915
                return err
×
2916
        }
×
2917

2918
        if err := serializeLogUpdates(w, diff.LogUpdates); err != nil {
3,447✔
2919
                return err
×
2920
        }
×
2921

2922
        numOpenRefs := uint16(len(diff.OpenedCircuitKeys))
3,447✔
2923
        if err := binary.Write(w, byteOrder, numOpenRefs); err != nil {
3,447✔
2924
                return err
×
2925
        }
×
2926

2927
        for _, openRef := range diff.OpenedCircuitKeys {
4,949✔
2928
                err := WriteElements(w, openRef.ChanID, openRef.HtlcID)
1,502✔
2929
                if err != nil {
1,502✔
2930
                        return err
×
2931
                }
×
2932
        }
2933

2934
        numClosedRefs := uint16(len(diff.ClosedCircuitKeys))
3,447✔
2935
        if err := binary.Write(w, byteOrder, numClosedRefs); err != nil {
3,447✔
2936
                return err
×
2937
        }
×
2938

2939
        for _, closedRef := range diff.ClosedCircuitKeys {
3,486✔
2940
                err := WriteElements(w, closedRef.ChanID, closedRef.HtlcID)
39✔
2941
                if err != nil {
39✔
2942
                        return err
×
2943
                }
×
2944
        }
2945

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

2954
        return nil
3,447✔
2955
}
2956

2957
func deserializeCommitDiff(r io.Reader) (*CommitDiff, error) {
3,441✔
2958
        var (
3,441✔
2959
                d   CommitDiff
3,441✔
2960
                err error
3,441✔
2961
        )
3,441✔
2962

3,441✔
2963
        d.Commitment, err = deserializeChanCommit(r)
3,441✔
2964
        if err != nil {
3,441✔
2965
                return nil, err
×
2966
        }
×
2967

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

3,441✔
2979
        d.LogUpdates, err = deserializeLogUpdates(r)
3,441✔
2980
        if err != nil {
3,441✔
2981
                return nil, err
×
2982
        }
×
2983

2984
        var numOpenRefs uint16
3,441✔
2985
        if err := binary.Read(r, byteOrder, &numOpenRefs); err != nil {
3,441✔
2986
                return nil, err
×
2987
        }
×
2988

2989
        d.OpenedCircuitKeys = make([]models.CircuitKey, numOpenRefs)
3,441✔
2990
        for i := 0; i < int(numOpenRefs); i++ {
4,970✔
2991
                err := ReadElements(r,
1,529✔
2992
                        &d.OpenedCircuitKeys[i].ChanID,
1,529✔
2993
                        &d.OpenedCircuitKeys[i].HtlcID)
1,529✔
2994
                if err != nil {
1,529✔
2995
                        return nil, err
×
2996
                }
×
2997
        }
2998

2999
        var numClosedRefs uint16
3,441✔
3000
        if err := binary.Read(r, byteOrder, &numClosedRefs); err != nil {
3,441✔
3001
                return nil, err
×
3002
        }
×
3003

3004
        d.ClosedCircuitKeys = make([]models.CircuitKey, numClosedRefs)
3,441✔
3005
        for i := 0; i < int(numClosedRefs); i++ {
3,478✔
3006
                err := ReadElements(r,
37✔
3007
                        &d.ClosedCircuitKeys[i].ChanID,
37✔
3008
                        &d.ClosedCircuitKeys[i].HtlcID)
37✔
3009
                if err != nil {
37✔
3010
                        return nil, err
×
3011
                }
×
3012
        }
3013

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

3023
        d.Commitment.amendTlvData(auxData)
3,441✔
3024

3,441✔
3025
        return &d, nil
3,441✔
3026
}
3027

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

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

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

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

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

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

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

3095
                // TODO(roasbeef): use seqno to derive key for later LCP
3096

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

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

3127
                tipBytes := chanBucket.Get(commitDiffKey)
869✔
3128
                if tipBytes == nil {
1,657✔
3129
                        return ErrNoPendingCommit
788✔
3130
                }
788✔
3131

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

3138
                cd = dcd
81✔
3139
                return nil
81✔
3140
        }, func() {
1,235✔
3141
                cd = nil
1,235✔
3142
        })
1,235✔
3143
        if err != nil {
2,389✔
3144
                return nil, err
1,154✔
3145
        }
1,154✔
3146

3147
        return cd, err
81✔
3148
}
3149

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

3166
                updateBytes := chanBucket.Get(unsignedAckedUpdatesKey)
435✔
3167
                if updateBytes == nil {
797✔
3168
                        return nil
362✔
3169
                }
362✔
3170

3171
                r := bytes.NewReader(updateBytes)
73✔
3172
                updates, err = deserializeLogUpdates(r)
73✔
3173
                return err
73✔
3174
        }, func() {
801✔
3175
                updates = nil
801✔
3176
        })
801✔
3177
        if err != nil {
801✔
3178
                return nil, err
×
3179
        }
×
3180

3181
        return updates, nil
801✔
3182
}
3183

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

3201
                updateBytes := chanBucket.Get(remoteUnsignedLocalUpdatesKey)
434✔
3202
                if updateBytes == nil {
827✔
3203
                        return nil
393✔
3204
                }
393✔
3205

3206
                r := bytes.NewReader(updateBytes)
41✔
3207
                updates, err = deserializeLogUpdates(r)
41✔
3208
                return err
41✔
3209
        }, func() {
800✔
3210
                updates = nil
800✔
3211
        })
800✔
3212
        if err != nil {
800✔
3213
                return nil, err
×
3214
        }
×
3215

3216
        return updates, nil
800✔
3217
}
3218

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

618✔
3230
        c.RemoteNextRevocation = revKey
618✔
3231

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

3240
                return putChanRevocationState(chanBucket, c)
618✔
3241
        }, func() {})
618✔
3242
        if err != nil {
618✔
3243
                return err
×
3244
        }
×
3245

3246
        return nil
618✔
3247
}
3248

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

3,362✔
3261
        c.Lock()
3,362✔
3262
        defer c.Unlock()
3,362✔
3263

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

3271
        var newRemoteCommit *ChannelCommitment
3,361✔
3272

3,361✔
3273
        err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
6,722✔
3274
                chanBucket, err := fetchChanBucketRw(
3,361✔
3275
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
3,361✔
3276
                )
3,361✔
3277
                if err != nil {
3,361✔
3278
                        return err
×
3279
                }
×
3280

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

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

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

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

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

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

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

3358
                r := bytes.NewReader(updateBytes)
3,151✔
3359
                unsignedUpdates, err := deserializeLogUpdates(r)
3,151✔
3360
                if err != nil {
3,151✔
3361
                        return err
×
3362
                }
×
3363

3364
                var validUpdates []LogUpdate
3,151✔
3365
                for _, upd := range unsignedUpdates {
7,005✔
3366
                        lIdx := upd.LogIndex
3,854✔
3367

3,854✔
3368
                        // Filter for updates that are not on the remote
3,854✔
3369
                        // commitment.
3,854✔
3370
                        if lIdx >= newCommit.Commitment.RemoteLogIndex {
4,978✔
3371
                                validUpdates = append(validUpdates, upd)
1,124✔
3372
                        }
1,124✔
3373
                }
3374

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

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

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

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

3402
                newRemoteCommit = &newCommit.Commitment
3,151✔
3403

3,151✔
3404
                return nil
3,151✔
3405
        }, func() {
3,361✔
3406
                newRemoteCommit = nil
3,361✔
3407
        })
3,361✔
3408
        if err != nil {
3,362✔
3409
                return err
1✔
3410
        }
1✔
3411

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

3,360✔
3417
        return nil
3,360✔
3418
}
3419

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

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

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

3✔
3436
        var key [8]byte
3✔
3437
        byteOrder.PutUint64(key[:], id)
3✔
3438

3✔
3439
        var finalHtlcByte FinalHtlcByte
3✔
3440
        if info.Settled {
6✔
3441
                finalHtlcByte |= FinalHtlcSettledBit
3✔
3442
        }
3✔
3443
        if info.Offchain {
5✔
3444
                finalHtlcByte |= FinalHtlcOffchainBit
2✔
3445
        }
2✔
3446

3447
        return finalHtlcsBucket.Put(key[:], []byte{byte(finalHtlcByte)})
3✔
3448
}
3449

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

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

3469
        // Otherwise, fallback to using the local htlc index of their commitment.
3470
        return c.RemoteCommitment.LocalHtlcIndex, nil
363✔
3471
}
3472

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

501✔
3480
        var fwdPkgs []*FwdPkg
501✔
3481
        if err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
943✔
3482
                var err error
442✔
3483
                fwdPkgs, err = c.Packager.LoadFwdPkgs(tx)
442✔
3484
                return err
442✔
3485
        }, func() {
943✔
3486
                fwdPkgs = nil
501✔
3487
        }); err != nil {
560✔
3488
                return nil, err
59✔
3489
        }
59✔
3490

3491
        return fwdPkgs, nil
442✔
3492
}
3493

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

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

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

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

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

2,577✔
3525
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
5,154✔
3526
                return c.Packager.SetFwdFilter(tx, height, fwdFilter)
2,577✔
3527
        }, func() {})
5,154✔
3528
}
3529

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

13✔
3539
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
26✔
3540
                for _, height := range heights {
896✔
3541
                        err := c.Packager.RemovePkg(tx, height)
883✔
3542
                        if err != nil {
883✔
3543
                                return err
×
3544
                        }
×
3545
                }
3546

3547
                return nil
13✔
3548
        }, func() {})
13✔
3549
}
3550

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

2✔
3561
        var height uint64
2✔
3562

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

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

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

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

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

3595
        return height, nil
2✔
3596
}
3597

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

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

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

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

3632
        return height, nil
1✔
3633
}
3634

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

31✔
3643
        c.RLock()
31✔
3644
        defer c.RUnlock()
31✔
3645

31✔
3646
        commit := &ChannelCommitment{}
31✔
3647
        rl := &RevocationLog{}
31✔
3648

31✔
3649
        err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
62✔
3650
                chanBucket, err := fetchChanBucket(
31✔
3651
                        tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
31✔
3652
                )
31✔
3653
                if err != nil {
32✔
3654
                        return err
1✔
3655
                }
1✔
3656

3657
                // Find the revocation log from both the new and the old
3658
                // bucket.
3659
                r, c, err := fetchRevocationLogCompatible(chanBucket, updateNum)
30✔
3660
                if err != nil {
49✔
3661
                        return err
19✔
3662
                }
19✔
3663

3664
                rl = r
11✔
3665
                commit = c
11✔
3666
                return nil
11✔
3667
        }, func() {})
31✔
3668
        if err != nil {
51✔
3669
                return nil, nil, err
20✔
3670
        }
20✔
3671

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

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

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

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

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

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

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

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

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

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

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

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

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

3739
        // Capacity was the total capacity of the channel.
3740
        Capacity btcutil.Amount
3741

3742
        // CloseHeight is the height at which the funding transaction was
3743
        // spent.
3744
        CloseHeight uint32
3745

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

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

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

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

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

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

3786
        // LocalChanConfig is the channel configuration for the local node.
3787
        LocalChanConfig ChannelConfig
3788

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

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

114✔
3804
        c.Lock()
114✔
3805
        defer c.Unlock()
114✔
3806

114✔
3807
        return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
228✔
3808
                openChanBucket := tx.ReadWriteBucket(openChannelBucket)
114✔
3809
                if openChanBucket == nil {
114✔
3810
                        return ErrNoChanDBExists
×
3811
                }
×
3812

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

3819
                chainBucket := nodeChanBucket.NestedReadWriteBucket(c.ChainHash[:])
114✔
3820
                if chainBucket == nil {
114✔
3821
                        return ErrNoActiveChannels
×
3822
                }
×
3823

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

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

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

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

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

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

3875
                err = chainBucket.DeleteNestedBucket(chanPointBuf.Bytes())
114✔
3876
                if err != nil {
114✔
3877
                        return err
×
3878
                }
×
3879

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

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

3893
                status := uint8(outpointClosed)
114✔
3894

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

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

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

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

3921
                historicalChanBucket, err :=
114✔
3922
                        historicalBucket.CreateBucketIfNotExists(chanKey)
114✔
3923
                if err != nil {
114✔
3924
                        return err
×
3925
                }
×
3926

3927
                // Apply any additional statuses to the channel state.
3928
                for _, status := range statuses {
119✔
3929
                        chanState.chanStatus |= status
5✔
3930
                }
5✔
3931

3932
                err = putOpenChannel(historicalChanBucket, chanState)
114✔
3933
                if err != nil {
114✔
3934
                        return err
×
3935
                }
×
3936

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

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

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

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

3964
        // Capacity is the total capacity of the channel.
3965
        Capacity btcutil.Amount
3966

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

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

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

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

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

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

×
4007
                snapshot.ChannelCommitment.CustomBlob = fn.Some(blobCopy)
×
4008
        })
×
4009

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

4017
        return snapshot
88✔
4018
}
4019

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

4033
                return fetchChanCommitments(chanBucket, c)
15✔
4034
        }, func() {})
15✔
4035
        if err != nil {
15✔
4036
                return nil, nil, err
×
4037
        }
×
4038

4039
        return &c.LocalCommitment, &c.RemoteCommitment, nil
15✔
4040
}
4041

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

4055
                return fetchChanRevocationState(chanBucket, c)
15✔
4056
        }, func() {})
15✔
4057
        if err != nil {
15✔
4058
                return nil, err
×
4059
        }
×
4060

4061
        return c.RevocationStore, nil
15✔
4062
}
4063

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

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

4083
                // For non-zero-conf channels, this is the base height to use.
UNCOV
4084
                blockHeightBase := c.ShortChannelID.BlockHeight
×
UNCOV
4085

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

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

UNCOV
4099
                return blockHeightBase + c.ThawHeight, nil
×
4100
        }
4101

UNCOV
4102
        return c.ThawHeight, nil
×
4103
}
4104

4105
func putChannelCloseSummary(tx kvdb.RwTx, chanID []byte,
4106
        summary *ChannelCloseSummary, lastChanState *OpenChannel) error {
114✔
4107

114✔
4108
        closedChanBucket, err := tx.CreateTopLevelBucket(closedChannelBucket)
114✔
4109
        if err != nil {
114✔
4110
                return err
×
4111
        }
×
4112

4113
        summary.RemoteCurrentRevocation = lastChanState.RemoteCurrentRevocation
114✔
4114
        summary.RemoteNextRevocation = lastChanState.RemoteNextRevocation
114✔
4115
        summary.LocalChanConfig = lastChanState.LocalChanCfg
114✔
4116

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

4122
        return closedChanBucket.Put(chanID, b.Bytes())
114✔
4123
}
4124

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

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

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

4146
        if err := WriteElements(w, cs.RemoteCurrentRevocation); err != nil {
121✔
4147
                return err
×
4148
        }
×
4149

4150
        if err := writeChanConfig(w, &cs.LocalChanConfig); err != nil {
121✔
4151
                return err
×
4152
        }
×
4153

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

4162
        // Write the field, if present.
4163
        if cs.RemoteNextRevocation != nil {
240✔
4164
                if err = WriteElements(w, cs.RemoteNextRevocation); err != nil {
119✔
4165
                        return err
×
4166
                }
×
4167
        }
4168

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

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

4181
        return nil
121✔
4182
}
4183

4184
func deserializeCloseChannelSummary(r io.Reader) (*ChannelCloseSummary, error) {
130✔
4185
        c := &ChannelCloseSummary{}
130✔
4186

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

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

4204
        // If fields are not present, we can return.
4205
        if !hasNewFields {
138✔
4206
                return c, nil
8✔
4207
        }
8✔
4208

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

4214
        if err := readChanConfig(r, &c.LocalChanConfig); err != nil {
122✔
4215
                return nil, err
×
4216
        }
×
4217

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

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

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

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

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

4262
        return c, nil
122✔
4263
}
4264

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

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

15,973✔
4279
        return chanType.IsSingleFunder() && chanType.HasFundingTx() &&
15,973✔
4280
                channel.IsInitiator &&
15,973✔
4281
                !channel.hasChanStatus(ChanStatusRestored)
15,973✔
4282
}
15,973✔
4283

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

4297
        // For single funder channels that we initiated, and we have the
4298
        // funding transaction, then write the funding txn.
4299
        if fundingTxPresent(channel) {
7,189✔
4300
                if err := WriteElement(&w, channel.FundingTxn); err != nil {
2,565✔
4301
                        return err
×
4302
                }
×
4303
        }
4304

4305
        if err := writeChanConfig(&w, &channel.LocalChanCfg); err != nil {
4,624✔
4306
                return err
×
4307
        }
×
4308
        if err := writeChanConfig(&w, &channel.RemoteChanCfg); err != nil {
4,624✔
4309
                return err
×
4310
        }
×
4311

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

4317
        if err := chanBucket.Put(chanInfoKey, w.Bytes()); err != nil {
4,624✔
4318
                return err
×
4319
        }
×
4320

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

4329
        return putOptionalUpfrontShutdownScript(
4,624✔
4330
                chanBucket, remoteUpfrontShutdownKey, channel.RemoteShutdownScript,
4,624✔
4331
        )
4,624✔
4332
}
4333

4334
// putOptionalUpfrontShutdownScript adds a shutdown script under the key
4335
// provided if it has a non-zero length.
4336
func putOptionalUpfrontShutdownScript(chanBucket kvdb.RwBucket, key []byte,
4337
        script []byte) error {
9,248✔
4338
        // If the script is empty, we do not need to add anything.
9,248✔
4339
        if len(script) == 0 {
18,486✔
4340
                return nil
9,238✔
4341
        }
9,238✔
4342

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

4348
        return chanBucket.Put(key, w.Bytes())
10✔
4349
}
4350

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

22,698✔
4357
        // Return early if the bucket does not exit, a shutdown script was not set.
22,698✔
4358
        bs := chanBucket.Get(key)
22,698✔
4359
        if bs == nil {
45,392✔
4360
                return nil
22,694✔
4361
        }
22,694✔
4362

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

4✔
4370
        return nil
4✔
4371
}
4372

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

4383
        return SerializeHtlcs(w, c.Htlcs...)
12,647✔
4384
}
4385

4386
func putChanCommitment(chanBucket kvdb.RwBucket, c *ChannelCommitment,
4387
        local bool) error {
9,197✔
4388

9,197✔
4389
        var commitKey []byte
9,197✔
4390
        if local {
13,820✔
4391
                commitKey = append(chanCommitmentKey, byte(0x00))
4,623✔
4392
        } else {
9,197✔
4393
                commitKey = append(chanCommitmentKey, byte(0x01))
4,574✔
4394
        }
4,574✔
4395

4396
        var b bytes.Buffer
9,197✔
4397
        if err := serializeChanCommit(&b, c); err != nil {
9,197✔
4398
                return err
×
4399
        }
×
4400

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

4407
        return chanBucket.Put(commitKey, b.Bytes())
9,197✔
4408
}
4409

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

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

4424
        return putChanCommitment(
1,214✔
4425
                chanBucket, &channel.RemoteCommitment, false,
1,214✔
4426
        )
1,214✔
4427
}
4428

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

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

4448
        return chanBucket.Put(revocationStateKey, b.Bytes())
5,193✔
4449
}
4450

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

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

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

4479
        // For single funder channels that we initiated and have the funding
4480
        // transaction to, read the funding txn.
4481
        if fundingTxPresent(channel) {
17,264✔
4482
                if err := ReadElement(r, &channel.FundingTxn); err != nil {
5,915✔
4483
                        return err
×
4484
                }
×
4485
        }
4486

4487
        if err := readChanConfig(r, &channel.LocalChanCfg); err != nil {
11,349✔
4488
                return err
×
4489
        }
×
4490
        if err := readChanConfig(r, &channel.RemoteChanCfg); err != nil {
11,349✔
4491
                return err
×
4492
        }
×
4493

4494
        // Retrieve the boolean stored under lastWasRevokeKey.
4495
        lastWasRevokeBytes := chanBucket.Get(lastWasRevokeKey)
11,349✔
4496
        if lastWasRevokeBytes == nil {
12,675✔
4497
                // If nothing has been stored under this key, we store false in the
1,326✔
4498
                // OpenChannel struct.
1,326✔
4499
                channel.LastWasRevoke = false
1,326✔
4500
        } else {
11,349✔
4501
                // Otherwise, read the value into the LastWasRevoke field.
10,023✔
4502
                revokeReader := bytes.NewReader(lastWasRevokeBytes)
10,023✔
4503
                err := ReadElements(revokeReader, &channel.LastWasRevoke)
10,023✔
4504
                if err != nil {
10,023✔
4505
                        return err
×
4506
                }
×
4507
        }
4508

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

4514
        // Assign all the relevant fields from the aux data into the actual
4515
        // open channel.
4516
        channel.amendTlvData(auxData)
11,349✔
4517

11,349✔
4518
        channel.Packager = NewChannelPackager(channel.ShortChannelID)
11,349✔
4519

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

4527
        return getOptionalUpfrontShutdownScript(
11,349✔
4528
                chanBucket, remoteUpfrontShutdownKey, &channel.RemoteShutdownScript,
11,349✔
4529
        )
11,349✔
4530
}
4531

4532
func deserializeChanCommit(r io.Reader) (ChannelCommitment, error) {
26,167✔
4533
        var c ChannelCommitment
26,167✔
4534

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

4544
        c.Htlcs, err = DeserializeHtlcs(r)
26,167✔
4545
        if err != nil {
26,167✔
4546
                return c, err
×
4547
        }
×
4548

4549
        return c, nil
26,167✔
4550
}
4551

4552
func fetchChanCommitment(chanBucket kvdb.RBucket,
4553
        local bool) (ChannelCommitment, error) {
22,725✔
4554

22,725✔
4555
        var commitKey []byte
22,725✔
4556
        if local {
34,088✔
4557
                commitKey = append(chanCommitmentKey, byte(0x00))
11,363✔
4558
        } else {
22,725✔
4559
                commitKey = append(chanCommitmentKey, byte(0x01))
11,362✔
4560
        }
11,362✔
4561

4562
        commitBytes := chanBucket.Get(commitKey)
22,725✔
4563
        if commitBytes == nil {
22,725✔
4564
                return ChannelCommitment{}, ErrNoCommitmentsFound
×
4565
        }
×
4566

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

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

4582
        chanCommit.amendTlvData(auxData)
22,725✔
4583

22,725✔
4584
        return chanCommit, nil
22,725✔
4585
}
4586

4587
func fetchChanCommitments(chanBucket kvdb.RBucket, channel *OpenChannel) error {
11,364✔
4588
        var err error
11,364✔
4589

11,364✔
4590
        // If this is a restored channel, then we don't have any commitments to
11,364✔
4591
        // read.
11,364✔
4592
        if channel.hasChanStatus(ChanStatusRestored) {
11,366✔
4593
                return nil
2✔
4594
        }
2✔
4595

4596
        channel.LocalCommitment, err = fetchChanCommitment(chanBucket, true)
11,362✔
4597
        if err != nil {
11,362✔
4598
                return err
×
4599
        }
×
4600
        channel.RemoteCommitment, err = fetchChanCommitment(chanBucket, false)
11,362✔
4601
        if err != nil {
11,362✔
4602
                return err
×
4603
        }
×
4604

4605
        return nil
11,362✔
4606
}
4607

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

11,364✔
4615
        err := ReadElements(
11,364✔
4616
                r, &channel.RemoteCurrentRevocation, &channel.RevocationProducer,
11,364✔
4617
                &channel.RevocationStore,
11,364✔
4618
        )
11,364✔
4619
        if err != nil {
11,364✔
4620
                return err
×
4621
        }
×
4622

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

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

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

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

4648
        if err := chanBucket.Delete(revocationStateKey); err != nil {
114✔
4649
                return err
×
4650
        }
×
4651

4652
        if diff := chanBucket.Get(commitDiffKey); diff != nil {
114✔
UNCOV
4653
                return chanBucket.Delete(commitDiffKey)
×
UNCOV
4654
        }
×
4655

4656
        return nil
114✔
4657
}
4658

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

4666
func fetchThawHeight(chanBucket kvdb.RBucket) (uint32, error) {
334✔
4667
        var height uint32
334✔
4668

334✔
4669
        heightBytes := chanBucket.Get(frozenChanKey)
334✔
4670
        heightReader := bytes.NewReader(heightBytes)
334✔
4671

334✔
4672
        if err := ReadElements(heightReader, &height); err != nil {
334✔
4673
                return 0, err
×
4674
        }
×
4675

4676
        return height, nil
334✔
4677
}
4678

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

4685
        return chanBucket.Put(frozenChanKey, heightBuf.Bytes())
428✔
4686
}
4687

4688
func deleteThawHeight(chanBucket kvdb.RwBucket) error {
107✔
4689
        return chanBucket.Delete(frozenChanKey)
107✔
4690
}
107✔
4691

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

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

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

4719
                return tlv.EUint32T(w, v.Index, buf)
4,625✔
4720
        }
4721
        return tlv.NewTypeForEncodingErr(val, "keychain.KeyLocator")
×
4722
}
4723

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

11,350✔
4734
                return tlv.DUint32(r, &v.Index, buf, 4)
11,350✔
4735
        }
4736
        return tlv.NewTypeForDecodingErr(val, "keychain.KeyLocator", l, 8)
×
4737
}
4738

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

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

4752
// NewShutdownInfo constructs a new ShutdownInfo object.
4753
func NewShutdownInfo(deliveryScript lnwire.DeliveryAddress,
4754
        locallyInitiated bool) *ShutdownInfo {
13✔
4755

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

4764
// Closer identifies the ChannelParty that initiated the coop-closure process.
UNCOV
4765
func (s ShutdownInfo) Closer() lntypes.ChannelParty {
×
UNCOV
4766
        if s.LocalInitiator.Val {
×
UNCOV
4767
                return lntypes.Local
×
UNCOV
4768
        }
×
4769

UNCOV
4770
        return lntypes.Remote
×
4771
}
4772

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

11✔
4780
        stream, err := tlv.NewStream(records...)
11✔
4781
        if err != nil {
11✔
4782
                return err
×
4783
        }
×
4784

4785
        return stream.Encode(w)
11✔
4786
}
4787

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

2✔
4793
        var info ShutdownInfo
2✔
4794
        records := []tlv.RecordProducer{
2✔
4795
                &info.DeliveryScript,
2✔
4796
                &info.LocalInitiator,
2✔
4797
        }
2✔
4798

2✔
4799
        _, err := tlvStream.ExtractRecords(records...)
2✔
4800

2✔
4801
        return &info, err
2✔
4802
}
2✔
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