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

lightningnetwork / lnd / 13157733617

05 Feb 2025 12:49PM UTC coverage: 57.712% (-1.1%) from 58.82%
13157733617

Pull #9447

github

yyforyongyu
sweep: rename methods for clarity

We now rename "third party" to "unknown" as the inputs can be spent via
an older sweeping tx, a third party (anchor), or a remote party (pin).
In fee bumper we don't have the info to distinguish the above cases, and
leave them to be further handled by the sweeper as it has more context.
Pull Request #9447: sweep: start tracking input spending status in the fee bumper

83 of 87 new or added lines in 2 files covered. (95.4%)

19472 existing lines in 252 files now uncovered.

103634 of 179570 relevant lines covered (57.71%)

24840.31 hits per line

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

68.26
/funding/manager.go
1
package funding
2

3
import (
4
        "bytes"
5
        "encoding/binary"
6
        "fmt"
7
        "io"
8
        "sync"
9
        "sync/atomic"
10
        "time"
11

12
        "github.com/btcsuite/btcd/blockchain"
13
        "github.com/btcsuite/btcd/btcec/v2"
14
        "github.com/btcsuite/btcd/btcec/v2/ecdsa"
15
        "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
16
        "github.com/btcsuite/btcd/btcutil"
17
        "github.com/btcsuite/btcd/chaincfg/chainhash"
18
        "github.com/btcsuite/btcd/txscript"
19
        "github.com/btcsuite/btcd/wire"
20
        "github.com/davecgh/go-spew/spew"
21
        "github.com/go-errors/errors"
22
        "github.com/lightningnetwork/lnd/chainntnfs"
23
        "github.com/lightningnetwork/lnd/chanacceptor"
24
        "github.com/lightningnetwork/lnd/channeldb"
25
        "github.com/lightningnetwork/lnd/discovery"
26
        "github.com/lightningnetwork/lnd/fn/v2"
27
        "github.com/lightningnetwork/lnd/graph"
28
        "github.com/lightningnetwork/lnd/graph/db/models"
29
        "github.com/lightningnetwork/lnd/input"
30
        "github.com/lightningnetwork/lnd/keychain"
31
        "github.com/lightningnetwork/lnd/labels"
32
        "github.com/lightningnetwork/lnd/lnpeer"
33
        "github.com/lightningnetwork/lnd/lnrpc"
34
        "github.com/lightningnetwork/lnd/lnutils"
35
        "github.com/lightningnetwork/lnd/lnwallet"
36
        "github.com/lightningnetwork/lnd/lnwallet/chainfee"
37
        "github.com/lightningnetwork/lnd/lnwallet/chanfunding"
38
        "github.com/lightningnetwork/lnd/lnwire"
39
        "golang.org/x/crypto/salsa20"
40
)
41

42
var (
43
        // byteOrder defines the endian-ness we use for encoding to and from
44
        // buffers.
45
        byteOrder = binary.BigEndian
46

47
        // checkPeerChannelReadyInterval is used when we are waiting for the
48
        // peer to send us ChannelReady. We will check every 1 second to see
49
        // if the message is received.
50
        //
51
        // NOTE: for itest, this value is changed to 10ms.
52
        checkPeerChannelReadyInterval = 1 * time.Second
53

54
        // errNoLocalNonce is returned when a local nonce is not found in the
55
        // expected TLV.
56
        errNoLocalNonce = fmt.Errorf("local nonce not found")
57

58
        // errNoPartialSig is returned when a partial sig is not found in the
59
        // expected TLV.
60
        errNoPartialSig = fmt.Errorf("partial sig not found")
61
)
62

63
// WriteOutpoint writes an outpoint to an io.Writer. This is not the same as
64
// the channeldb variant as this uses WriteVarBytes for the Hash.
65
func WriteOutpoint(w io.Writer, o *wire.OutPoint) error {
368✔
66
        scratch := make([]byte, 4)
368✔
67

368✔
68
        if err := wire.WriteVarBytes(w, 0, o.Hash[:]); err != nil {
368✔
69
                return err
×
70
        }
×
71

72
        byteOrder.PutUint32(scratch, o.Index)
368✔
73
        _, err := w.Write(scratch)
368✔
74
        return err
368✔
75
}
76

77
const (
78
        // MinBtcRemoteDelay is the minimum CSV delay we will require the remote
79
        // to use for its commitment transaction.
80
        MinBtcRemoteDelay uint16 = 144
81

82
        // MaxBtcRemoteDelay is the maximum CSV delay we will require the remote
83
        // to use for its commitment transaction.
84
        MaxBtcRemoteDelay uint16 = 2016
85

86
        // MinChanFundingSize is the smallest channel that we'll allow to be
87
        // created over the RPC interface.
88
        MinChanFundingSize = btcutil.Amount(20000)
89

90
        // MaxBtcFundingAmount is a soft-limit of the maximum channel size
91
        // currently accepted on the Bitcoin chain within the Lightning
92
        // Protocol. This limit is defined in BOLT-0002, and serves as an
93
        // initial precautionary limit while implementations are battle tested
94
        // in the real world.
95
        MaxBtcFundingAmount = btcutil.Amount(1<<24) - 1
96

97
        // MaxBtcFundingAmountWumbo is a soft-limit on the maximum size of wumbo
98
        // channels. This limit is 10 BTC and is the only thing standing between
99
        // you and limitless channel size (apart from 21 million cap).
100
        MaxBtcFundingAmountWumbo = btcutil.Amount(1000000000)
101

102
        msgBufferSize = 50
103

104
        // MaxWaitNumBlocksFundingConf is the maximum number of blocks to wait
105
        // for the funding transaction to be confirmed before forgetting
106
        // channels that aren't initiated by us. 2016 blocks is ~2 weeks.
107
        MaxWaitNumBlocksFundingConf = 2016
108

109
        // pendingChansLimit is the maximum number of pending channels that we
110
        // can have. After this point, pending channel opens will start to be
111
        // rejected.
112
        pendingChansLimit = 1_000
113
)
114

115
var (
116
        // ErrFundingManagerShuttingDown is an error returned when attempting to
117
        // process a funding request/message but the funding manager has already
118
        // been signaled to shut down.
119
        ErrFundingManagerShuttingDown = errors.New("funding manager shutting " +
120
                "down")
121

122
        // ErrConfirmationTimeout is an error returned when we as a responder
123
        // are waiting for a funding transaction to confirm, but too many
124
        // blocks pass without confirmation.
125
        ErrConfirmationTimeout = errors.New("timeout waiting for funding " +
126
                "confirmation")
127

128
        // errUpfrontShutdownScriptNotSupported is returned if an upfront
129
        // shutdown script is set for a peer that does not support the feature
130
        // bit.
131
        errUpfrontShutdownScriptNotSupported = errors.New("peer does not " +
132
                "support option upfront shutdown script")
133

134
        zeroID [32]byte
135
)
136

137
// reservationWithCtx encapsulates a pending channel reservation. This wrapper
138
// struct is used internally within the funding manager to track and progress
139
// the funding workflow initiated by incoming/outgoing methods from the target
140
// peer. Additionally, this struct houses a response and error channel which is
141
// used to respond to the caller in the case a channel workflow is initiated
142
// via a local signal such as RPC.
143
//
144
// TODO(roasbeef): actually use the context package
145
//   - deadlines, etc.
146
type reservationWithCtx struct {
147
        reservation *lnwallet.ChannelReservation
148
        peer        lnpeer.Peer
149

150
        chanAmt btcutil.Amount
151

152
        // forwardingPolicy is the policy provided by the initFundingMsg.
153
        forwardingPolicy models.ForwardingPolicy
154

155
        // Constraints we require for the remote.
156
        remoteCsvDelay    uint16
157
        remoteMinHtlc     lnwire.MilliSatoshi
158
        remoteMaxValue    lnwire.MilliSatoshi
159
        remoteMaxHtlcs    uint16
160
        remoteChanReserve btcutil.Amount
161

162
        // maxLocalCsv is the maximum csv we will accept from the remote.
163
        maxLocalCsv uint16
164

165
        // channelType is the explicit channel type proposed by the initiator of
166
        // the channel.
167
        channelType *lnwire.ChannelType
168

169
        updateMtx   sync.RWMutex
170
        lastUpdated time.Time
171

172
        updates chan *lnrpc.OpenStatusUpdate
173
        err     chan error
174
}
175

176
// isLocked checks the reservation's timestamp to determine whether it is
177
// locked.
178
func (r *reservationWithCtx) isLocked() bool {
3✔
179
        r.updateMtx.RLock()
3✔
180
        defer r.updateMtx.RUnlock()
3✔
181

3✔
182
        // The time zero value represents a locked reservation.
3✔
183
        return r.lastUpdated.IsZero()
3✔
184
}
3✔
185

186
// updateTimestamp updates the reservation's timestamp with the current time.
187
func (r *reservationWithCtx) updateTimestamp() {
134✔
188
        r.updateMtx.Lock()
134✔
189
        defer r.updateMtx.Unlock()
134✔
190

134✔
191
        r.lastUpdated = time.Now()
134✔
192
}
134✔
193

194
// InitFundingMsg is sent by an outside subsystem to the funding manager in
195
// order to kick off a funding workflow with a specified target peer. The
196
// original request which defines the parameters of the funding workflow are
197
// embedded within this message giving the funding manager full context w.r.t
198
// the workflow.
199
type InitFundingMsg struct {
200
        // Peer is the peer that we want to open a channel to.
201
        Peer lnpeer.Peer
202

203
        // TargetPubkey is the public key of the peer.
204
        TargetPubkey *btcec.PublicKey
205

206
        // ChainHash is the target genesis hash for this channel.
207
        ChainHash chainhash.Hash
208

209
        // SubtractFees set to true means that fees will be subtracted
210
        // from the LocalFundingAmt.
211
        SubtractFees bool
212

213
        // LocalFundingAmt is the size of the channel.
214
        LocalFundingAmt btcutil.Amount
215

216
        // BaseFee is the base fee charged for routing payments regardless of
217
        // the number of milli-satoshis sent.
218
        BaseFee *uint64
219

220
        // FeeRate is the fee rate in ppm (parts per million) that will be
221
        // charged proportionally based on the value of each forwarded HTLC, the
222
        // lowest possible rate is 0 with a granularity of 0.000001
223
        // (millionths).
224
        FeeRate *uint64
225

226
        // PushAmt is the amount pushed to the counterparty.
227
        PushAmt lnwire.MilliSatoshi
228

229
        // FundingFeePerKw is the fee for the funding transaction.
230
        FundingFeePerKw chainfee.SatPerKWeight
231

232
        // Private determines whether or not this channel will be private.
233
        Private bool
234

235
        // MinHtlcIn is the minimum incoming HTLC that we accept.
236
        MinHtlcIn lnwire.MilliSatoshi
237

238
        // RemoteCsvDelay is the CSV delay we require for the remote peer.
239
        RemoteCsvDelay uint16
240

241
        // RemoteChanReserve is the channel reserve we required for the remote
242
        // peer.
243
        RemoteChanReserve btcutil.Amount
244

245
        // MinConfs indicates the minimum number of confirmations that each
246
        // output selected to fund the channel should satisfy.
247
        MinConfs int32
248

249
        // ShutdownScript is an optional upfront shutdown script for the
250
        // channel. This value is optional, so may be nil.
251
        ShutdownScript lnwire.DeliveryAddress
252

253
        // MaxValueInFlight is the maximum amount of coins in MilliSatoshi
254
        // that can be pending within the channel. It only applies to the
255
        // remote party.
256
        MaxValueInFlight lnwire.MilliSatoshi
257

258
        // MaxHtlcs is the maximum number of HTLCs that the remote peer
259
        // can offer us.
260
        MaxHtlcs uint16
261

262
        // MaxLocalCsv is the maximum local csv delay we will accept from our
263
        // peer.
264
        MaxLocalCsv uint16
265

266
        // FundUpToMaxAmt is the maximum amount to try to commit to. If set, the
267
        // MinFundAmt field denotes the acceptable minimum amount to commit to,
268
        // while trying to commit as many coins as possible up to this value.
269
        FundUpToMaxAmt btcutil.Amount
270

271
        // MinFundAmt must be set iff FundUpToMaxAmt is set. It denotes the
272
        // minimum amount to commit to.
273
        MinFundAmt btcutil.Amount
274

275
        // Outpoints is a list of client-selected outpoints that should be used
276
        // for funding a channel. If LocalFundingAmt is specified then this
277
        // amount is allocated from the sum of outpoints towards funding. If
278
        // the FundUpToMaxAmt is specified the entirety of selected funds is
279
        // allocated towards channel funding.
280
        Outpoints []wire.OutPoint
281

282
        // ChanFunder is an optional channel funder that allows the caller to
283
        // control exactly how the channel funding is carried out. If not
284
        // specified, then the default chanfunding.WalletAssembler will be
285
        // used.
286
        ChanFunder chanfunding.Assembler
287

288
        // PendingChanID is not all zeroes (the default value), then this will
289
        // be the pending channel ID used for the funding flow within the wire
290
        // protocol.
291
        PendingChanID PendingChanID
292

293
        // ChannelType allows the caller to use an explicit channel type for the
294
        // funding negotiation. This type will only be observed if BOTH sides
295
        // support explicit channel type negotiation.
296
        ChannelType *lnwire.ChannelType
297

298
        // Memo is any arbitrary information we wish to store locally about the
299
        // channel that will be useful to our future selves.
300
        Memo []byte
301

302
        // Updates is a channel which updates to the opening status of the
303
        // channel are sent on.
304
        Updates chan *lnrpc.OpenStatusUpdate
305

306
        // Err is a channel which errors encountered during the funding flow are
307
        // sent on.
308
        Err chan error
309
}
310

311
// fundingMsg is sent by the ProcessFundingMsg function and packages a
312
// funding-specific lnwire.Message along with the lnpeer.Peer that sent it.
313
type fundingMsg struct {
314
        msg  lnwire.Message
315
        peer lnpeer.Peer
316
}
317

318
// pendingChannels is a map instantiated per-peer which tracks all active
319
// pending single funded channels indexed by their pending channel identifier,
320
// which is a set of 32-bytes generated via a CSPRNG.
321
type pendingChannels map[PendingChanID]*reservationWithCtx
322

323
// serializedPubKey is used within the FundingManager's activeReservations list
324
// to identify the nodes with which the FundingManager is actively working to
325
// initiate new channels.
326
type serializedPubKey [33]byte
327

328
// newSerializedKey creates a new serialized public key from an instance of a
329
// live pubkey object.
330
func newSerializedKey(pubKey *btcec.PublicKey) serializedPubKey {
380✔
331
        var s serializedPubKey
380✔
332
        copy(s[:], pubKey.SerializeCompressed())
380✔
333
        return s
380✔
334
}
380✔
335

336
// DevConfig specifies configs used for integration test only.
337
type DevConfig struct {
338
        // ProcessChannelReadyWait is the duration to sleep before processing
339
        // remote node's channel ready message once the channel as been marked
340
        // as `channelReadySent`.
341
        ProcessChannelReadyWait time.Duration
342
}
343

344
// Config defines the configuration for the FundingManager. All elements
345
// within the configuration MUST be non-nil for the FundingManager to carry out
346
// its duties.
347
type Config struct {
348
        // Dev specifies config values used in integration test. For
349
        // production, this config will always be an empty struct.
350
        Dev *DevConfig
351

352
        // NoWumboChans indicates if we're to reject all incoming wumbo channel
353
        // requests, and also reject all outgoing wumbo channel requests.
354
        NoWumboChans bool
355

356
        // IDKey is the PublicKey that is used to identify this node within the
357
        // Lightning Network.
358
        IDKey *btcec.PublicKey
359

360
        // IDKeyLoc is the locator for the key that is used to identify this
361
        // node within the LightningNetwork.
362
        IDKeyLoc keychain.KeyLocator
363

364
        // Wallet handles the parts of the funding process that involves moving
365
        // funds from on-chain transaction outputs into Lightning channels.
366
        Wallet *lnwallet.LightningWallet
367

368
        // PublishTransaction facilitates the process of broadcasting a
369
        // transaction to the network.
370
        PublishTransaction func(*wire.MsgTx, string) error
371

372
        // UpdateLabel updates the label that a transaction has in our wallet,
373
        // overwriting any existing labels.
374
        UpdateLabel func(chainhash.Hash, string) error
375

376
        // FeeEstimator calculates appropriate fee rates based on historical
377
        // transaction information.
378
        FeeEstimator chainfee.Estimator
379

380
        // Notifier is used by the FundingManager to determine when the
381
        // channel's funding transaction has been confirmed on the blockchain
382
        // so that the channel creation process can be completed.
383
        Notifier chainntnfs.ChainNotifier
384

385
        // ChannelDB is the database that keeps track of all channel state.
386
        ChannelDB *channeldb.ChannelStateDB
387

388
        // SignMessage signs an arbitrary message with a given public key. The
389
        // actual digest signed is the double sha-256 of the message. In the
390
        // case that the private key corresponding to the passed public key
391
        // cannot be located, then an error is returned.
392
        //
393
        // TODO(roasbeef): should instead pass on this responsibility to a
394
        // distinct sub-system?
395
        SignMessage func(keyLoc keychain.KeyLocator,
396
                msg []byte, doubleHash bool) (*ecdsa.Signature, error)
397

398
        // CurrentNodeAnnouncement should return the latest, fully signed node
399
        // announcement from the backing Lightning Network node with a fresh
400
        // timestamp.
401
        CurrentNodeAnnouncement func() (lnwire.NodeAnnouncement, error)
402

403
        // SendAnnouncement is used by the FundingManager to send announcement
404
        // messages to the Gossiper to possibly broadcast to the greater
405
        // network. A set of optional message fields can be provided to populate
406
        // any information within the graph that is not included in the gossip
407
        // message.
408
        SendAnnouncement func(msg lnwire.Message,
409
                optionalFields ...discovery.OptionalMsgField) chan error
410

411
        // NotifyWhenOnline allows the FundingManager to register with a
412
        // subsystem that will notify it when the peer comes online. This is
413
        // used when sending the channelReady message, since it MUST be
414
        // delivered after the funding transaction is confirmed.
415
        //
416
        // NOTE: The peerChan channel must be buffered.
417
        NotifyWhenOnline func(peer [33]byte, peerChan chan<- lnpeer.Peer)
418

419
        // FindChannel queries the database for the channel with the given
420
        // channel ID. Providing the node's public key is an optimization that
421
        // prevents deserializing and scanning through all possible channels.
422
        FindChannel func(node *btcec.PublicKey,
423
                chanID lnwire.ChannelID) (*channeldb.OpenChannel, error)
424

425
        // TempChanIDSeed is a cryptographically random string of bytes that's
426
        // used as a seed to generate pending channel ID's.
427
        TempChanIDSeed [32]byte
428

429
        // DefaultRoutingPolicy is the default routing policy used when
430
        // initially announcing channels.
431
        DefaultRoutingPolicy models.ForwardingPolicy
432

433
        // DefaultMinHtlcIn is the default minimum incoming htlc value that is
434
        // set as a channel parameter.
435
        DefaultMinHtlcIn lnwire.MilliSatoshi
436

437
        // NumRequiredConfs is a function closure that helps the funding
438
        // manager decide how many confirmations it should require for a
439
        // channel extended to it. The function is able to take into account
440
        // the amount of the channel, and any funds we'll be pushed in the
441
        // process to determine how many confirmations we'll require.
442
        NumRequiredConfs func(btcutil.Amount, lnwire.MilliSatoshi) uint16
443

444
        // RequiredRemoteDelay is a function that maps the total amount in a
445
        // proposed channel to the CSV delay that we'll require for the remote
446
        // party. Naturally a larger channel should require a higher CSV delay
447
        // in order to give us more time to claim funds in the case of a
448
        // contract breach.
449
        RequiredRemoteDelay func(btcutil.Amount) uint16
450

451
        // RequiredRemoteChanReserve is a function closure that, given the
452
        // channel capacity and dust limit, will return an appropriate amount
453
        // for the remote peer's required channel reserve that is to be adhered
454
        // to at all times.
455
        RequiredRemoteChanReserve func(capacity,
456
                dustLimit btcutil.Amount) btcutil.Amount
457

458
        // RequiredRemoteMaxValue is a function closure that, given the channel
459
        // capacity, returns the amount of MilliSatoshis that our remote peer
460
        // can have in total outstanding HTLCs with us.
461
        RequiredRemoteMaxValue func(btcutil.Amount) lnwire.MilliSatoshi
462

463
        // RequiredRemoteMaxHTLCs is a function closure that, given the channel
464
        // capacity, returns the number of maximum HTLCs the remote peer can
465
        // offer us.
466
        RequiredRemoteMaxHTLCs func(btcutil.Amount) uint16
467

468
        // WatchNewChannel is to be called once a new channel enters the final
469
        // funding stage: waiting for on-chain confirmation. This method sends
470
        // the channel to the ChainArbitrator so it can watch for any on-chain
471
        // events related to the channel. We also provide the public key of the
472
        // node we're establishing a channel with for reconnection purposes.
473
        WatchNewChannel func(*channeldb.OpenChannel, *btcec.PublicKey) error
474

475
        // ReportShortChanID allows the funding manager to report the confirmed
476
        // short channel ID of a formerly pending zero-conf channel to outside
477
        // sub-systems.
478
        ReportShortChanID func(wire.OutPoint) error
479

480
        // ZombieSweeperInterval is the periodic time interval in which the
481
        // zombie sweeper is run.
482
        ZombieSweeperInterval time.Duration
483

484
        // ReservationTimeout is the length of idle time that must pass before
485
        // a reservation is considered a zombie.
486
        ReservationTimeout time.Duration
487

488
        // MinChanSize is the smallest channel size that we'll accept as an
489
        // inbound channel. We have such a parameter, as otherwise, nodes could
490
        // flood us with very small channels that would never really be usable
491
        // due to fees.
492
        MinChanSize btcutil.Amount
493

494
        // MaxChanSize is the largest channel size that we'll accept as an
495
        // inbound channel. We have such a parameter, so that you may decide how
496
        // WUMBO you would like your channel.
497
        MaxChanSize btcutil.Amount
498

499
        // MaxPendingChannels is the maximum number of pending channels we
500
        // allow for each peer.
501
        MaxPendingChannels int
502

503
        // RejectPush is set true if the fundingmanager should reject any
504
        // incoming channels having a non-zero push amount.
505
        RejectPush bool
506

507
        // MaxLocalCSVDelay is the maximum csv delay we will allow for our
508
        // commit output. Channels that exceed this value will be failed.
509
        MaxLocalCSVDelay uint16
510

511
        // NotifyOpenChannelEvent informs the ChannelNotifier when channels
512
        // transition from pending open to open.
513
        NotifyOpenChannelEvent func(wire.OutPoint)
514

515
        // OpenChannelPredicate is a predicate on the lnwire.OpenChannel message
516
        // and on the requesting node's public key that returns a bool which
517
        // tells the funding manager whether or not to accept the channel.
518
        OpenChannelPredicate chanacceptor.ChannelAcceptor
519

520
        // NotifyPendingOpenChannelEvent informs the ChannelNotifier when
521
        // channels enter a pending state.
522
        NotifyPendingOpenChannelEvent func(wire.OutPoint,
523
                *channeldb.OpenChannel)
524

525
        // EnableUpfrontShutdown specifies whether the upfront shutdown script
526
        // is enabled.
527
        EnableUpfrontShutdown bool
528

529
        // MaxAnchorsCommitFeeRate is the max commitment fee rate we'll use as
530
        // the initiator for channels of the anchor type.
531
        MaxAnchorsCommitFeeRate chainfee.SatPerKWeight
532

533
        // DeleteAliasEdge allows the Manager to delete an alias channel edge
534
        // from the graph. It also returns our local to-be-deleted policy.
535
        DeleteAliasEdge func(scid lnwire.ShortChannelID) (
536
                *models.ChannelEdgePolicy, error)
537

538
        // AliasManager is an implementation of the aliasHandler interface that
539
        // abstracts away the handling of many alias functions.
540
        AliasManager aliasHandler
541

542
        // IsSweeperOutpoint queries the sweeper store for successfully
543
        // published sweeps. This is useful to decide for the internal wallet
544
        // backed funding flow to not use utxos still being swept by the sweeper
545
        // subsystem.
546
        IsSweeperOutpoint func(wire.OutPoint) bool
547

548
        // AuxLeafStore is an optional store that can be used to store auxiliary
549
        // leaves for certain custom channel types.
550
        AuxLeafStore fn.Option[lnwallet.AuxLeafStore]
551

552
        // AuxFundingController is an optional controller that can be used to
553
        // modify the way we handle certain custom channel types. It's also
554
        // able to automatically handle new custom protocol messages related to
555
        // the funding process.
556
        AuxFundingController fn.Option[AuxFundingController]
557

558
        // AuxSigner is an optional signer that can be used to sign auxiliary
559
        // leaves for certain custom channel types.
560
        AuxSigner fn.Option[lnwallet.AuxSigner]
561

562
        // AuxResolver is an optional interface that can be used to modify the
563
        // way contracts are resolved.
564
        AuxResolver fn.Option[lnwallet.AuxContractResolver]
565
}
566

567
// Manager acts as an orchestrator/bridge between the wallet's
568
// 'ChannelReservation' workflow, and the wire protocol's funding initiation
569
// messages. Any requests to initiate the funding workflow for a channel,
570
// either kicked-off locally or remotely are handled by the funding manager.
571
// Once a channel's funding workflow has been completed, any local callers, the
572
// local peer, and possibly the remote peer are notified of the completion of
573
// the channel workflow. Additionally, any temporary or permanent access
574
// controls between the wallet and remote peers are enforced via the funding
575
// manager.
576
type Manager struct {
577
        started sync.Once
578
        stopped sync.Once
579

580
        // cfg is a copy of the configuration struct that the FundingManager
581
        // was initialized with.
582
        cfg *Config
583

584
        // chanIDKey is a cryptographically random key that's used to generate
585
        // temporary channel ID's.
586
        chanIDKey [32]byte
587

588
        // chanIDNonce is a nonce that's incremented for each new funding
589
        // reservation created.
590
        chanIDNonce atomic.Uint64
591

592
        // nonceMtx is a mutex that guards the pendingMusigNonces.
593
        nonceMtx sync.RWMutex
594

595
        // pendingMusigNonces is used to store the musig2 nonce we generate to
596
        // send funding locked until we receive a funding locked message from
597
        // the remote party. We'll use this to keep track of the nonce we
598
        // generated, so we send the local+remote nonces to the peer state
599
        // machine.
600
        //
601
        // NOTE: This map is protected by the nonceMtx above.
602
        //
603
        // TODO(roasbeef): replace w/ generic concurrent map
604
        pendingMusigNonces map[lnwire.ChannelID]*musig2.Nonces
605

606
        // activeReservations is a map which houses the state of all pending
607
        // funding workflows.
608
        activeReservations map[serializedPubKey]pendingChannels
609

610
        // signedReservations is a utility map that maps the permanent channel
611
        // ID of a funding reservation to its temporary channel ID. This is
612
        // required as mid funding flow, we switch to referencing the channel
613
        // by its full channel ID once the commitment transactions have been
614
        // signed by both parties.
615
        signedReservations map[lnwire.ChannelID]PendingChanID
616

617
        // resMtx guards both of the maps above to ensure that all access is
618
        // goroutine safe.
619
        resMtx sync.RWMutex
620

621
        // fundingMsgs is a channel that relays fundingMsg structs from
622
        // external sub-systems using the ProcessFundingMsg call.
623
        fundingMsgs chan *fundingMsg
624

625
        // fundingRequests is a channel used to receive channel initiation
626
        // requests from a local subsystem within the daemon.
627
        fundingRequests chan *InitFundingMsg
628

629
        localDiscoverySignals *lnutils.SyncMap[lnwire.ChannelID, chan struct{}]
630

631
        handleChannelReadyBarriers *lnutils.SyncMap[lnwire.ChannelID, struct{}]
632

633
        quit chan struct{}
634
        wg   sync.WaitGroup
635
}
636

637
// channelOpeningState represents the different states a channel can be in
638
// between the funding transaction has been confirmed and the channel is
639
// announced to the network and ready to be used.
640
type channelOpeningState uint8
641

642
const (
643
        // markedOpen is the opening state of a channel if the funding
644
        // transaction is confirmed on-chain, but channelReady is not yet
645
        // successfully sent to the other peer.
646
        markedOpen channelOpeningState = iota
647

648
        // channelReadySent is the opening state of a channel if the
649
        // channelReady message has successfully been sent to the other peer,
650
        // but we still haven't announced the channel to the network.
651
        channelReadySent
652

653
        // addedToGraph is the opening state of a channel if the channel has
654
        // been successfully added to the graph immediately after the
655
        // channelReady message has been sent, but we still haven't announced
656
        // the channel to the network.
657
        addedToGraph
658
)
659

UNCOV
660
func (c channelOpeningState) String() string {
×
UNCOV
661
        switch c {
×
UNCOV
662
        case markedOpen:
×
UNCOV
663
                return "markedOpen"
×
UNCOV
664
        case channelReadySent:
×
UNCOV
665
                return "channelReadySent"
×
UNCOV
666
        case addedToGraph:
×
UNCOV
667
                return "addedToGraph"
×
668
        default:
×
669
                return "unknown"
×
670
        }
671
}
672

673
// NewFundingManager creates and initializes a new instance of the
674
// fundingManager.
675
func NewFundingManager(cfg Config) (*Manager, error) {
107✔
676
        return &Manager{
107✔
677
                cfg:       &cfg,
107✔
678
                chanIDKey: cfg.TempChanIDSeed,
107✔
679
                activeReservations: make(
107✔
680
                        map[serializedPubKey]pendingChannels,
107✔
681
                ),
107✔
682
                signedReservations: make(
107✔
683
                        map[lnwire.ChannelID][32]byte,
107✔
684
                ),
107✔
685
                fundingMsgs: make(
107✔
686
                        chan *fundingMsg, msgBufferSize,
107✔
687
                ),
107✔
688
                fundingRequests: make(
107✔
689
                        chan *InitFundingMsg, msgBufferSize,
107✔
690
                ),
107✔
691
                localDiscoverySignals: &lnutils.SyncMap[
107✔
692
                        lnwire.ChannelID, chan struct{},
107✔
693
                ]{},
107✔
694
                handleChannelReadyBarriers: &lnutils.SyncMap[
107✔
695
                        lnwire.ChannelID, struct{},
107✔
696
                ]{},
107✔
697
                pendingMusigNonces: make(
107✔
698
                        map[lnwire.ChannelID]*musig2.Nonces,
107✔
699
                ),
107✔
700
                quit: make(chan struct{}),
107✔
701
        }, nil
107✔
702
}
107✔
703

704
// Start launches all helper goroutines required for handling requests sent
705
// to the funding manager.
706
func (f *Manager) Start() error {
107✔
707
        var err error
107✔
708
        f.started.Do(func() {
214✔
709
                log.Info("Funding manager starting")
107✔
710
                err = f.start()
107✔
711
        })
107✔
712
        return err
107✔
713
}
714

715
func (f *Manager) start() error {
107✔
716
        // Upon restart, the Funding Manager will check the database to load any
107✔
717
        // channels that were  waiting for their funding transactions to be
107✔
718
        // confirmed on the blockchain at the time when the daemon last went
107✔
719
        // down.
107✔
720
        // TODO(roasbeef): store height that funding finished?
107✔
721
        //  * would then replace call below
107✔
722
        allChannels, err := f.cfg.ChannelDB.FetchAllChannels()
107✔
723
        if err != nil {
107✔
724
                return err
×
725
        }
×
726

727
        for _, channel := range allChannels {
116✔
728
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
9✔
729

9✔
730
                // For any channels that were in a pending state when the
9✔
731
                // daemon was last connected, the Funding Manager will
9✔
732
                // re-initialize the channel barriers, and republish the
9✔
733
                // funding transaction if we're the initiator.
9✔
734
                if channel.IsPending {
10✔
735
                        log.Tracef("Loading pending ChannelPoint(%v), "+
1✔
736
                                "creating chan barrier",
1✔
737
                                channel.FundingOutpoint)
1✔
738

1✔
739
                        f.localDiscoverySignals.Store(
1✔
740
                                chanID, make(chan struct{}),
1✔
741
                        )
1✔
742

1✔
743
                        // Rebroadcast the funding transaction for any pending
1✔
744
                        // channel that we initiated. No error will be returned
1✔
745
                        // if the transaction already has been broadcast.
1✔
746
                        chanType := channel.ChanType
1✔
747
                        if chanType.IsSingleFunder() &&
1✔
748
                                chanType.HasFundingTx() &&
1✔
749
                                channel.IsInitiator {
2✔
750

1✔
751
                                f.rebroadcastFundingTx(channel)
1✔
752
                        }
1✔
753
                } else if channel.ChanType.IsSingleFunder() &&
8✔
754
                        channel.ChanType.HasFundingTx() &&
8✔
755
                        channel.IsZeroConf() && channel.IsInitiator &&
8✔
756
                        !channel.ZeroConfConfirmed() {
10✔
757

2✔
758
                        // Rebroadcast the funding transaction for unconfirmed
2✔
759
                        // zero-conf channels if we have the funding tx and are
2✔
760
                        // also the initiator.
2✔
761
                        f.rebroadcastFundingTx(channel)
2✔
762
                }
2✔
763

764
                // We will restart the funding state machine for all channels,
765
                // which will wait for the channel's funding transaction to be
766
                // confirmed on the blockchain, and transmit the messages
767
                // necessary for the channel to be operational.
768
                f.wg.Add(1)
9✔
769
                go f.advanceFundingState(channel, chanID, nil)
9✔
770
        }
771

772
        f.wg.Add(1) // TODO(roasbeef): tune
107✔
773
        go f.reservationCoordinator()
107✔
774

107✔
775
        return nil
107✔
776
}
777

778
// Stop signals all helper goroutines to execute a graceful shutdown. This
779
// method will block until all goroutines have exited.
780
func (f *Manager) Stop() error {
104✔
781
        f.stopped.Do(func() {
207✔
782
                log.Info("Funding manager shutting down...")
103✔
783
                defer log.Debug("Funding manager shutdown complete")
103✔
784

103✔
785
                close(f.quit)
103✔
786
                f.wg.Wait()
103✔
787
        })
103✔
788

789
        return nil
104✔
790
}
791

792
// rebroadcastFundingTx publishes the funding tx on startup for each
793
// unconfirmed channel.
794
func (f *Manager) rebroadcastFundingTx(c *channeldb.OpenChannel) {
3✔
795
        var fundingTxBuf bytes.Buffer
3✔
796
        err := c.FundingTxn.Serialize(&fundingTxBuf)
3✔
797
        if err != nil {
3✔
798
                log.Errorf("Unable to serialize funding transaction %v: %v",
×
799
                        c.FundingTxn.TxHash(), err)
×
800

×
801
                // Clear the buffer of any bytes that were written before the
×
802
                // serialization error to prevent logging an incomplete
×
803
                // transaction.
×
804
                fundingTxBuf.Reset()
×
805
        } else {
3✔
806
                log.Debugf("Rebroadcasting funding tx for ChannelPoint(%v): "+
3✔
807
                        "%x", c.FundingOutpoint, fundingTxBuf.Bytes())
3✔
808
        }
3✔
809

810
        // Set a nil short channel ID at this stage because we do not know it
811
        // until our funding tx confirms.
812
        label := labels.MakeLabel(labels.LabelTypeChannelOpen, nil)
3✔
813

3✔
814
        err = f.cfg.PublishTransaction(c.FundingTxn, label)
3✔
815
        if err != nil {
3✔
816
                log.Errorf("Unable to rebroadcast funding tx %x for "+
×
817
                        "ChannelPoint(%v): %v", fundingTxBuf.Bytes(),
×
818
                        c.FundingOutpoint, err)
×
819
        }
×
820
}
821

822
// PendingChanID is a type that represents a pending channel ID. This might be
823
// selected by the caller, but if not, will be automatically selected.
824
type PendingChanID = [32]byte
825

826
// nextPendingChanID returns the next free pending channel ID to be used to
827
// identify a particular future channel funding workflow.
828
func (f *Manager) nextPendingChanID() PendingChanID {
56✔
829
        // Obtain a fresh nonce. We do this by encoding the incremented nonce.
56✔
830
        nextNonce := f.chanIDNonce.Add(1)
56✔
831

56✔
832
        var nonceBytes [8]byte
56✔
833
        binary.LittleEndian.PutUint64(nonceBytes[:], nextNonce)
56✔
834

56✔
835
        // We'll generate the next pending channelID by "encrypting" 32-bytes
56✔
836
        // of zeroes which'll extract 32 random bytes from our stream cipher.
56✔
837
        var (
56✔
838
                nextChanID PendingChanID
56✔
839
                zeroes     [32]byte
56✔
840
        )
56✔
841
        salsa20.XORKeyStream(
56✔
842
                nextChanID[:], zeroes[:], nonceBytes[:], &f.chanIDKey,
56✔
843
        )
56✔
844

56✔
845
        return nextChanID
56✔
846
}
56✔
847

848
// CancelPeerReservations cancels all active reservations associated with the
849
// passed node. This will ensure any outputs which have been pre committed,
850
// (and thus locked from coin selection), are properly freed.
UNCOV
851
func (f *Manager) CancelPeerReservations(nodePub [33]byte) {
×
UNCOV
852
        log.Debugf("Cancelling all reservations for peer %x", nodePub[:])
×
UNCOV
853

×
UNCOV
854
        f.resMtx.Lock()
×
UNCOV
855
        defer f.resMtx.Unlock()
×
UNCOV
856

×
UNCOV
857
        // We'll attempt to look up this node in the set of active
×
UNCOV
858
        // reservations.  If they don't have any, then there's no further work
×
UNCOV
859
        // to be done.
×
UNCOV
860
        nodeReservations, ok := f.activeReservations[nodePub]
×
UNCOV
861
        if !ok {
×
UNCOV
862
                log.Debugf("No active reservations for node: %x", nodePub[:])
×
UNCOV
863
                return
×
UNCOV
864
        }
×
865

866
        // If they do have any active reservations, then we'll cancel all of
867
        // them (which releases any locked UTXO's), and also delete it from the
868
        // reservation map.
869
        for pendingID, resCtx := range nodeReservations {
×
870
                if err := resCtx.reservation.Cancel(); err != nil {
×
871
                        log.Errorf("unable to cancel reservation for "+
×
872
                                "node=%x: %v", nodePub[:], err)
×
873
                }
×
874

875
                resCtx.err <- fmt.Errorf("peer disconnected")
×
876
                delete(nodeReservations, pendingID)
×
877
        }
878

879
        // Finally, we'll delete the node itself from the set of reservations.
880
        delete(f.activeReservations, nodePub)
×
881
}
882

883
// chanIdentifier wraps pending channel ID and channel ID into one struct so
884
// it's easier to identify a specific channel.
885
//
886
// TODO(yy): move to a different package to hide the private fields so direct
887
// access is disabled.
888
type chanIdentifier struct {
889
        // tempChanID is the pending channel ID created by the funder when
890
        // initializing the funding flow. For fundee, it's received from the
891
        // `open_channel` message.
892
        tempChanID lnwire.ChannelID
893

894
        // chanID is the channel ID created by the funder once the
895
        // `accept_channel` message is received. For fundee, it's received from
896
        // the `funding_created` message.
897
        chanID lnwire.ChannelID
898

899
        // chanIDSet is a boolean indicates whether the active channel ID is
900
        // set for this identifier. For zero conf channels, the `chanID` can be
901
        // all-zero, which is the same as the empty value of `ChannelID`. To
902
        // avoid the confusion, we use this boolean to explicitly signal
903
        // whether the `chanID` is set or not.
904
        chanIDSet bool
905
}
906

907
// newChanIdentifier creates a new chanIdentifier.
908
func newChanIdentifier(tempChanID lnwire.ChannelID) *chanIdentifier {
145✔
909
        return &chanIdentifier{
145✔
910
                tempChanID: tempChanID,
145✔
911
        }
145✔
912
}
145✔
913

914
// setChanID updates the `chanIdentifier` with the active channel ID.
915
func (c *chanIdentifier) setChanID(chanID lnwire.ChannelID) {
88✔
916
        c.chanID = chanID
88✔
917
        c.chanIDSet = true
88✔
918
}
88✔
919

920
// hasChanID returns true if the active channel ID has been set.
921
func (c *chanIdentifier) hasChanID() bool {
22✔
922
        return c.chanIDSet
22✔
923
}
22✔
924

925
// failFundingFlow will fail the active funding flow with the target peer,
926
// identified by its unique temporary channel ID. This method will send an
927
// error to the remote peer, and also remove the reservation from our set of
928
// pending reservations.
929
//
930
// TODO(roasbeef): if peer disconnects, and haven't yet broadcast funding
931
// transaction, then all reservations should be cleared.
932
func (f *Manager) failFundingFlow(peer lnpeer.Peer, cid *chanIdentifier,
933
        fundingErr error) {
22✔
934

22✔
935
        log.Debugf("Failing funding flow for pending_id=%v: %v",
22✔
936
                cid.tempChanID, fundingErr)
22✔
937

22✔
938
        // First, notify Brontide to remove the pending channel.
22✔
939
        //
22✔
940
        // NOTE: depending on where we fail the flow, we may not have the
22✔
941
        // active channel ID yet.
22✔
942
        if cid.hasChanID() {
27✔
943
                err := peer.RemovePendingChannel(cid.chanID)
5✔
944
                if err != nil {
5✔
945
                        log.Errorf("Unable to remove channel %v with peer %x: "+
×
946
                                "%v", cid,
×
947
                                peer.IdentityKey().SerializeCompressed(), err)
×
948
                }
×
949
        }
950

951
        ctx, err := f.cancelReservationCtx(
22✔
952
                peer.IdentityKey(), cid.tempChanID, false,
22✔
953
        )
22✔
954
        if err != nil {
32✔
955
                log.Errorf("unable to cancel reservation: %v", err)
10✔
956
        }
10✔
957

958
        // In case the case where the reservation existed, send the funding
959
        // error on the error channel.
960
        if ctx != nil {
34✔
961
                ctx.err <- fundingErr
12✔
962
        }
12✔
963

964
        // We only send the exact error if it is part of out whitelisted set of
965
        // errors (lnwire.FundingError or lnwallet.ReservationError).
966
        var msg lnwire.ErrorData
22✔
967
        switch e := fundingErr.(type) {
22✔
968
        // Let the actual error message be sent to the remote for the
969
        // whitelisted types.
970
        case lnwallet.ReservationError:
6✔
971
                msg = lnwire.ErrorData(e.Error())
6✔
972
        case lnwire.FundingError:
4✔
973
                msg = lnwire.ErrorData(e.Error())
4✔
UNCOV
974
        case chanacceptor.ChanAcceptError:
×
UNCOV
975
                msg = lnwire.ErrorData(e.Error())
×
976

977
        // For all other error types we just send a generic error.
978
        default:
12✔
979
                msg = lnwire.ErrorData("funding failed due to internal error")
12✔
980
        }
981

982
        errMsg := &lnwire.Error{
22✔
983
                ChanID: cid.tempChanID,
22✔
984
                Data:   msg,
22✔
985
        }
22✔
986

22✔
987
        log.Debugf("Sending funding error to peer (%x): %v",
22✔
988
                peer.IdentityKey().SerializeCompressed(), spew.Sdump(errMsg))
22✔
989
        if err := peer.SendMessage(false, errMsg); err != nil {
23✔
990
                log.Errorf("unable to send error message to peer %v", err)
1✔
991
        }
1✔
992
}
993

994
// sendWarning sends a new warning message to the target peer, targeting the
995
// specified cid with the passed funding error.
996
func (f *Manager) sendWarning(peer lnpeer.Peer, cid *chanIdentifier,
997
        fundingErr error) {
×
998

×
999
        msg := fundingErr.Error()
×
1000

×
1001
        errMsg := &lnwire.Warning{
×
1002
                ChanID: cid.tempChanID,
×
1003
                Data:   lnwire.WarningData(msg),
×
1004
        }
×
1005

×
1006
        log.Debugf("Sending funding warning to peer (%x): %v",
×
1007
                peer.IdentityKey().SerializeCompressed(),
×
1008
                spew.Sdump(errMsg),
×
1009
        )
×
1010

×
1011
        if err := peer.SendMessage(false, errMsg); err != nil {
×
1012
                log.Errorf("unable to send error message to peer %v", err)
×
1013
        }
×
1014
}
1015

1016
// reservationCoordinator is the primary goroutine tasked with progressing the
1017
// funding workflow between the wallet, and any outside peers or local callers.
1018
//
1019
// NOTE: This MUST be run as a goroutine.
1020
func (f *Manager) reservationCoordinator() {
107✔
1021
        defer f.wg.Done()
107✔
1022

107✔
1023
        zombieSweepTicker := time.NewTicker(f.cfg.ZombieSweeperInterval)
107✔
1024
        defer zombieSweepTicker.Stop()
107✔
1025

107✔
1026
        for {
480✔
1027
                select {
373✔
1028
                case fmsg := <-f.fundingMsgs:
210✔
1029
                        switch msg := fmsg.msg.(type) {
210✔
1030
                        case *lnwire.OpenChannel:
54✔
1031
                                f.fundeeProcessOpenChannel(fmsg.peer, msg)
54✔
1032

1033
                        case *lnwire.AcceptChannel:
32✔
1034
                                f.funderProcessAcceptChannel(fmsg.peer, msg)
32✔
1035

1036
                        case *lnwire.FundingCreated:
27✔
1037
                                f.fundeeProcessFundingCreated(fmsg.peer, msg)
27✔
1038

1039
                        case *lnwire.FundingSigned:
27✔
1040
                                f.funderProcessFundingSigned(fmsg.peer, msg)
27✔
1041

1042
                        case *lnwire.ChannelReady:
28✔
1043
                                f.wg.Add(1)
28✔
1044
                                go f.handleChannelReady(fmsg.peer, msg)
28✔
1045

1046
                        case *lnwire.Warning:
42✔
1047
                                f.handleWarningMsg(fmsg.peer, msg)
42✔
1048

UNCOV
1049
                        case *lnwire.Error:
×
UNCOV
1050
                                f.handleErrorMsg(fmsg.peer, msg)
×
1051
                        }
1052
                case req := <-f.fundingRequests:
56✔
1053
                        f.handleInitFundingMsg(req)
56✔
1054

UNCOV
1055
                case <-zombieSweepTicker.C:
×
UNCOV
1056
                        f.pruneZombieReservations()
×
1057

1058
                case <-f.quit:
103✔
1059
                        return
103✔
1060
                }
1061
        }
1062
}
1063

1064
// advanceFundingState will advance the channel through the steps after the
1065
// funding transaction is broadcasted, up until the point where the channel is
1066
// ready for operation. This includes waiting for the funding transaction to
1067
// confirm, sending channel_ready to the peer, adding the channel to the graph,
1068
// and announcing the channel. The updateChan can be set non-nil to get
1069
// OpenStatusUpdates.
1070
//
1071
// NOTE: This MUST be run as a goroutine.
1072
func (f *Manager) advanceFundingState(channel *channeldb.OpenChannel,
1073
        pendingChanID PendingChanID,
1074
        updateChan chan<- *lnrpc.OpenStatusUpdate) {
63✔
1075

63✔
1076
        defer f.wg.Done()
63✔
1077

63✔
1078
        // If the channel is still pending we must wait for the funding
63✔
1079
        // transaction to confirm.
63✔
1080
        if channel.IsPending {
118✔
1081
                err := f.advancePendingChannelState(channel, pendingChanID)
55✔
1082
                if err != nil {
76✔
1083
                        log.Errorf("Unable to advance pending state of "+
21✔
1084
                                "ChannelPoint(%v): %v",
21✔
1085
                                channel.FundingOutpoint, err)
21✔
1086
                        return
21✔
1087
                }
21✔
1088
        }
1089

1090
        var chanOpts []lnwallet.ChannelOpt
42✔
1091
        f.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
84✔
1092
                chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
42✔
1093
        })
42✔
1094
        f.cfg.AuxSigner.WhenSome(func(s lnwallet.AuxSigner) {
84✔
1095
                chanOpts = append(chanOpts, lnwallet.WithAuxSigner(s))
42✔
1096
        })
42✔
1097
        f.cfg.AuxResolver.WhenSome(func(s lnwallet.AuxContractResolver) {
42✔
1098
                chanOpts = append(chanOpts, lnwallet.WithAuxResolver(s))
×
1099
        })
×
1100

1101
        // We create the state-machine object which wraps the database state.
1102
        lnChannel, err := lnwallet.NewLightningChannel(
42✔
1103
                nil, channel, nil, chanOpts...,
42✔
1104
        )
42✔
1105
        if err != nil {
42✔
1106
                log.Errorf("Unable to create LightningChannel(%v): %v",
×
1107
                        channel.FundingOutpoint, err)
×
1108
                return
×
1109
        }
×
1110

1111
        for {
190✔
1112
                channelState, shortChanID, err := f.getChannelOpeningState(
148✔
1113
                        &channel.FundingOutpoint,
148✔
1114
                )
148✔
1115
                if err == channeldb.ErrChannelNotFound {
173✔
1116
                        // Channel not in fundingManager's opening database,
25✔
1117
                        // meaning it was successfully announced to the
25✔
1118
                        // network.
25✔
1119
                        // TODO(halseth): could do graph consistency check
25✔
1120
                        // here, and re-add the edge if missing.
25✔
1121
                        log.Debugf("ChannelPoint(%v) with chan_id=%x not "+
25✔
1122
                                "found in opening database, assuming already "+
25✔
1123
                                "announced to the network",
25✔
1124
                                channel.FundingOutpoint, pendingChanID)
25✔
1125
                        return
25✔
1126
                } else if err != nil {
148✔
1127
                        log.Errorf("Unable to query database for "+
×
1128
                                "channel opening state(%v): %v",
×
1129
                                channel.FundingOutpoint, err)
×
1130
                        return
×
1131
                }
×
1132

1133
                // If we did find the channel in the opening state database, we
1134
                // have seen the funding transaction being confirmed, but there
1135
                // are still steps left of the setup procedure. We continue the
1136
                // procedure where we left off.
1137
                err = f.stateStep(
123✔
1138
                        channel, lnChannel, shortChanID, pendingChanID,
123✔
1139
                        channelState, updateChan,
123✔
1140
                )
123✔
1141
                if err != nil {
140✔
1142
                        log.Errorf("Unable to advance state(%v): %v",
17✔
1143
                                channel.FundingOutpoint, err)
17✔
1144
                        return
17✔
1145
                }
17✔
1146
        }
1147
}
1148

1149
// stateStep advances the confirmed channel one step in the funding state
1150
// machine. This method is synchronous and the new channel opening state will
1151
// have been written to the database when it successfully returns. The
1152
// updateChan can be set non-nil to get OpenStatusUpdates.
1153
func (f *Manager) stateStep(channel *channeldb.OpenChannel,
1154
        lnChannel *lnwallet.LightningChannel,
1155
        shortChanID *lnwire.ShortChannelID, pendingChanID PendingChanID,
1156
        channelState channelOpeningState,
1157
        updateChan chan<- *lnrpc.OpenStatusUpdate) error {
123✔
1158

123✔
1159
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
123✔
1160
        log.Debugf("Channel(%v) with ShortChanID %v has opening state %v",
123✔
1161
                chanID, shortChanID, channelState)
123✔
1162

123✔
1163
        switch channelState {
123✔
1164
        // The funding transaction was confirmed, but we did not successfully
1165
        // send the channelReady message to the peer, so let's do that now.
1166
        case markedOpen:
35✔
1167
                err := f.sendChannelReady(channel, lnChannel)
35✔
1168
                if err != nil {
36✔
1169
                        return fmt.Errorf("failed sending channelReady: %w",
1✔
1170
                                err)
1✔
1171
                }
1✔
1172

1173
                // As the channelReady message is now sent to the peer, the
1174
                // channel is moved to the next state of the state machine. It
1175
                // will be moved to the last state (actually deleted from the
1176
                // database) after the channel is finally announced.
1177
                err = f.saveChannelOpeningState(
34✔
1178
                        &channel.FundingOutpoint, channelReadySent,
34✔
1179
                        shortChanID,
34✔
1180
                )
34✔
1181
                if err != nil {
34✔
1182
                        return fmt.Errorf("error setting channel state to"+
×
1183
                                " channelReadySent: %w", err)
×
1184
                }
×
1185

1186
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
34✔
1187
                        "sent ChannelReady", chanID, shortChanID)
34✔
1188

34✔
1189
                return nil
34✔
1190

1191
        // channelReady was sent to peer, but the channel was not added to the
1192
        // graph and the channel announcement was not sent.
1193
        case channelReadySent:
60✔
1194
                // We must wait until we've received the peer's channel_ready
60✔
1195
                // before sending a channel_update according to BOLT#07.
60✔
1196
                received, err := f.receivedChannelReady(
60✔
1197
                        channel.IdentityPub, chanID,
60✔
1198
                )
60✔
1199
                if err != nil {
61✔
1200
                        return fmt.Errorf("failed to check if channel_ready "+
1✔
1201
                                "was received: %v", err)
1✔
1202
                }
1✔
1203

1204
                if !received {
94✔
1205
                        // We haven't received ChannelReady, so we'll continue
35✔
1206
                        // to the next iteration of the loop after sleeping for
35✔
1207
                        // checkPeerChannelReadyInterval.
35✔
1208
                        select {
35✔
1209
                        case <-time.After(checkPeerChannelReadyInterval):
24✔
1210
                        case <-f.quit:
11✔
1211
                                return ErrFundingManagerShuttingDown
11✔
1212
                        }
1213

1214
                        return nil
24✔
1215
                }
1216

1217
                return f.handleChannelReadyReceived(
24✔
1218
                        channel, shortChanID, pendingChanID, updateChan,
24✔
1219
                )
24✔
1220

1221
        // The channel was added to the Router's topology, but the channel
1222
        // announcement was not sent.
1223
        case addedToGraph:
28✔
1224
                if channel.IsZeroConf() {
34✔
1225
                        // If this is a zero-conf channel, then we will wait
6✔
1226
                        // for it to be confirmed before announcing it to the
6✔
1227
                        // greater network.
6✔
1228
                        err := f.waitForZeroConfChannel(channel)
6✔
1229
                        if err != nil {
8✔
1230
                                return fmt.Errorf("failed waiting for zero "+
2✔
1231
                                        "channel: %v", err)
2✔
1232
                        }
2✔
1233

1234
                        // Update the local shortChanID variable such that
1235
                        // annAfterSixConfs uses the confirmed SCID.
1236
                        confirmedScid := channel.ZeroConfRealScid()
4✔
1237
                        shortChanID = &confirmedScid
4✔
1238
                }
1239

1240
                err := f.annAfterSixConfs(channel, shortChanID)
26✔
1241
                if err != nil {
28✔
1242
                        return fmt.Errorf("error sending channel "+
2✔
1243
                                "announcement: %v", err)
2✔
1244
                }
2✔
1245

1246
                // We delete the channel opening state from our internal
1247
                // database as the opening process has succeeded. We can do
1248
                // this because we assume the AuthenticatedGossiper queues the
1249
                // announcement messages, and persists them in case of a daemon
1250
                // shutdown.
1251
                err = f.deleteChannelOpeningState(&channel.FundingOutpoint)
24✔
1252
                if err != nil {
24✔
1253
                        return fmt.Errorf("error deleting channel state: %w",
×
1254
                                err)
×
1255
                }
×
1256

1257
                // After the fee parameters have been stored in the
1258
                // announcement we can delete them from the database. For
1259
                // private channels we do not announce the channel policy to
1260
                // the network but still need to delete them from the database.
1261
                err = f.deleteInitialForwardingPolicy(chanID)
24✔
1262
                if err != nil {
24✔
1263
                        log.Infof("Could not delete initial policy for chanId "+
×
1264
                                "%x", chanID)
×
1265
                }
×
1266

1267
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
24✔
1268
                        "announced", chanID, shortChanID)
24✔
1269

24✔
1270
                return nil
24✔
1271
        }
1272

1273
        return fmt.Errorf("undefined channelState: %v", channelState)
×
1274
}
1275

1276
// advancePendingChannelState waits for a pending channel's funding tx to
1277
// confirm, and marks it open in the database when that happens.
1278
func (f *Manager) advancePendingChannelState(channel *channeldb.OpenChannel,
1279
        pendingChanID PendingChanID) error {
55✔
1280

55✔
1281
        if channel.IsZeroConf() {
59✔
1282
                // Persist the alias to the alias database.
4✔
1283
                baseScid := channel.ShortChannelID
4✔
1284
                err := f.cfg.AliasManager.AddLocalAlias(
4✔
1285
                        baseScid, baseScid, true, false,
4✔
1286
                )
4✔
1287
                if err != nil {
4✔
1288
                        return fmt.Errorf("error adding local alias to "+
×
1289
                                "store: %v", err)
×
1290
                }
×
1291

1292
                // We don't wait for zero-conf channels to be confirmed and
1293
                // instead immediately proceed with the rest of the funding
1294
                // flow. The channel opening state is stored under the alias
1295
                // SCID.
1296
                err = f.saveChannelOpeningState(
4✔
1297
                        &channel.FundingOutpoint, markedOpen,
4✔
1298
                        &channel.ShortChannelID,
4✔
1299
                )
4✔
1300
                if err != nil {
4✔
1301
                        return fmt.Errorf("error setting zero-conf channel "+
×
1302
                                "state to markedOpen: %v", err)
×
1303
                }
×
1304

1305
                // The ShortChannelID is already set since it's an alias, but
1306
                // we still need to mark the channel as no longer pending.
1307
                err = channel.MarkAsOpen(channel.ShortChannelID)
4✔
1308
                if err != nil {
4✔
1309
                        return fmt.Errorf("error setting zero-conf channel's "+
×
1310
                                "pending flag to false: %v", err)
×
1311
                }
×
1312

1313
                // Inform the ChannelNotifier that the channel has transitioned
1314
                // from pending open to open.
1315
                f.cfg.NotifyOpenChannelEvent(channel.FundingOutpoint)
4✔
1316

4✔
1317
                // Find and close the discoverySignal for this channel such
4✔
1318
                // that ChannelReady messages will be processed.
4✔
1319
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
4✔
1320
                discoverySignal, ok := f.localDiscoverySignals.Load(chanID)
4✔
1321
                if ok {
8✔
1322
                        close(discoverySignal)
4✔
1323
                }
4✔
1324

1325
                return nil
4✔
1326
        }
1327

1328
        confChannel, err := f.waitForFundingWithTimeout(channel)
51✔
1329
        if err == ErrConfirmationTimeout {
53✔
1330
                return f.fundingTimeout(channel, pendingChanID)
2✔
1331
        } else if err != nil {
70✔
1332
                return fmt.Errorf("error waiting for funding "+
19✔
1333
                        "confirmation for ChannelPoint(%v): %v",
19✔
1334
                        channel.FundingOutpoint, err)
19✔
1335
        }
19✔
1336

1337
        if blockchain.IsCoinBaseTx(confChannel.fundingTx) {
32✔
1338
                // If it's a coinbase transaction, we need to wait for it to
2✔
1339
                // mature. We wait out an additional MinAcceptDepth on top of
2✔
1340
                // the coinbase maturity as an extra margin of safety.
2✔
1341
                maturity := f.cfg.Wallet.Cfg.NetParams.CoinbaseMaturity
2✔
1342
                numCoinbaseConfs := uint32(maturity)
2✔
1343

2✔
1344
                if channel.NumConfsRequired > maturity {
2✔
1345
                        numCoinbaseConfs = uint32(channel.NumConfsRequired)
×
1346
                }
×
1347

1348
                txid := &channel.FundingOutpoint.Hash
2✔
1349
                fundingScript, err := makeFundingScript(channel)
2✔
1350
                if err != nil {
2✔
1351
                        log.Errorf("unable to create funding script for "+
×
1352
                                "ChannelPoint(%v): %v",
×
1353
                                channel.FundingOutpoint, err)
×
1354

×
1355
                        return err
×
1356
                }
×
1357

1358
                confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
2✔
1359
                        txid, fundingScript, numCoinbaseConfs,
2✔
1360
                        channel.BroadcastHeight(),
2✔
1361
                )
2✔
1362
                if err != nil {
2✔
1363
                        log.Errorf("Unable to register for confirmation of "+
×
1364
                                "ChannelPoint(%v): %v",
×
1365
                                channel.FundingOutpoint, err)
×
1366

×
1367
                        return err
×
1368
                }
×
1369

1370
                select {
2✔
1371
                case _, ok := <-confNtfn.Confirmed:
2✔
1372
                        if !ok {
2✔
1373
                                return fmt.Errorf("ChainNotifier shutting "+
×
1374
                                        "down, can't complete funding flow "+
×
1375
                                        "for ChannelPoint(%v)",
×
1376
                                        channel.FundingOutpoint)
×
1377
                        }
×
1378

1379
                case <-f.quit:
×
1380
                        return ErrFundingManagerShuttingDown
×
1381
                }
1382
        }
1383

1384
        // Success, funding transaction was confirmed.
1385
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
30✔
1386
        log.Debugf("ChannelID(%v) is now fully confirmed! "+
30✔
1387
                "(shortChanID=%v)", chanID, confChannel.shortChanID)
30✔
1388

30✔
1389
        err = f.handleFundingConfirmation(channel, confChannel)
30✔
1390
        if err != nil {
30✔
1391
                return fmt.Errorf("unable to handle funding "+
×
1392
                        "confirmation for ChannelPoint(%v): %v",
×
1393
                        channel.FundingOutpoint, err)
×
1394
        }
×
1395

1396
        return nil
30✔
1397
}
1398

1399
// ProcessFundingMsg sends a message to the internal fundingManager goroutine,
1400
// allowing it to handle the lnwire.Message.
1401
func (f *Manager) ProcessFundingMsg(msg lnwire.Message, peer lnpeer.Peer) {
210✔
1402
        select {
210✔
1403
        case f.fundingMsgs <- &fundingMsg{msg, peer}:
210✔
1404
        case <-f.quit:
×
1405
                return
×
1406
        }
1407
}
1408

1409
// fundeeProcessOpenChannel creates an initial 'ChannelReservation' within the
1410
// wallet, then responds to the source peer with an accept channel message
1411
// progressing the funding workflow.
1412
//
1413
// TODO(roasbeef): add error chan to all, let channelManager handle
1414
// error+propagate.
1415
//
1416
//nolint:funlen
1417
func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
1418
        msg *lnwire.OpenChannel) {
54✔
1419

54✔
1420
        // Check number of pending channels to be smaller than maximum allowed
54✔
1421
        // number and send ErrorGeneric to remote peer if condition is
54✔
1422
        // violated.
54✔
1423
        peerPubKey := peer.IdentityKey()
54✔
1424
        peerIDKey := newSerializedKey(peerPubKey)
54✔
1425

54✔
1426
        amt := msg.FundingAmount
54✔
1427

54✔
1428
        // We get all pending channels for this peer. This is the list of the
54✔
1429
        // active reservations and the channels pending open in the database.
54✔
1430
        f.resMtx.RLock()
54✔
1431
        reservations := f.activeReservations[peerIDKey]
54✔
1432

54✔
1433
        // We don't count reservations that were created from a canned funding
54✔
1434
        // shim. The user has registered the shim and therefore expects this
54✔
1435
        // channel to arrive.
54✔
1436
        numPending := 0
54✔
1437
        for _, res := range reservations {
66✔
1438
                if !res.reservation.IsCannedShim() {
24✔
1439
                        numPending++
12✔
1440
                }
12✔
1441
        }
1442
        f.resMtx.RUnlock()
54✔
1443

54✔
1444
        // Create the channel identifier.
54✔
1445
        cid := newChanIdentifier(msg.PendingChannelID)
54✔
1446

54✔
1447
        // Also count the channels that are already pending. There we don't know
54✔
1448
        // the underlying intent anymore, unfortunately.
54✔
1449
        channels, err := f.cfg.ChannelDB.FetchOpenChannels(peerPubKey)
54✔
1450
        if err != nil {
54✔
1451
                f.failFundingFlow(peer, cid, err)
×
1452
                return
×
1453
        }
×
1454

1455
        for _, c := range channels {
66✔
1456
                // Pending channels that have a non-zero thaw height were also
12✔
1457
                // created through a canned funding shim. Those also don't
12✔
1458
                // count towards the DoS protection limit.
12✔
1459
                //
12✔
1460
                // TODO(guggero): Properly store the funding type (wallet, shim,
12✔
1461
                // PSBT) on the channel so we don't need to use the thaw height.
12✔
1462
                if c.IsPending && c.ThawHeight == 0 {
20✔
1463
                        numPending++
8✔
1464
                }
8✔
1465
        }
1466

1467
        // TODO(roasbeef): modify to only accept a _single_ pending channel per
1468
        // block unless white listed
1469
        if numPending >= f.cfg.MaxPendingChannels {
58✔
1470
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
4✔
1471

4✔
1472
                return
4✔
1473
        }
4✔
1474

1475
        // Ensure that the pendingChansLimit is respected.
1476
        pendingChans, err := f.cfg.ChannelDB.FetchPendingChannels()
50✔
1477
        if err != nil {
50✔
1478
                f.failFundingFlow(peer, cid, err)
×
1479
                return
×
1480
        }
×
1481

1482
        if len(pendingChans) > pendingChansLimit {
50✔
1483
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
×
1484
                return
×
1485
        }
×
1486

1487
        // We'll also reject any requests to create channels until we're fully
1488
        // synced to the network as we won't be able to properly validate the
1489
        // confirmation of the funding transaction.
1490
        isSynced, _, err := f.cfg.Wallet.IsSynced()
50✔
1491
        if err != nil || !isSynced {
50✔
1492
                if err != nil {
×
1493
                        log.Errorf("unable to query wallet: %v", err)
×
1494
                }
×
1495
                err := errors.New("Synchronizing blockchain")
×
1496
                f.failFundingFlow(peer, cid, err)
×
1497
                return
×
1498
        }
1499

1500
        // Ensure that the remote party respects our maximum channel size.
1501
        if amt > f.cfg.MaxChanSize {
52✔
1502
                f.failFundingFlow(
2✔
1503
                        peer, cid,
2✔
1504
                        lnwallet.ErrChanTooLarge(amt, f.cfg.MaxChanSize),
2✔
1505
                )
2✔
1506
                return
2✔
1507
        }
2✔
1508

1509
        // We'll, also ensure that the remote party isn't attempting to propose
1510
        // a channel that's below our current min channel size.
1511
        if amt < f.cfg.MinChanSize {
48✔
UNCOV
1512
                f.failFundingFlow(
×
UNCOV
1513
                        peer, cid,
×
UNCOV
1514
                        lnwallet.ErrChanTooSmall(amt, f.cfg.MinChanSize),
×
UNCOV
1515
                )
×
UNCOV
1516
                return
×
UNCOV
1517
        }
×
1518

1519
        // If request specifies non-zero push amount and 'rejectpush' is set,
1520
        // signal an error.
1521
        if f.cfg.RejectPush && msg.PushAmount > 0 {
49✔
1522
                f.failFundingFlow(peer, cid, lnwallet.ErrNonZeroPushAmount())
1✔
1523
                return
1✔
1524
        }
1✔
1525

1526
        // Send the OpenChannel request to the ChannelAcceptor to determine
1527
        // whether this node will accept the channel.
1528
        chanReq := &chanacceptor.ChannelAcceptRequest{
47✔
1529
                Node:        peer.IdentityKey(),
47✔
1530
                OpenChanMsg: msg,
47✔
1531
        }
47✔
1532

47✔
1533
        // Query our channel acceptor to determine whether we should reject
47✔
1534
        // the channel.
47✔
1535
        acceptorResp := f.cfg.OpenChannelPredicate.Accept(chanReq)
47✔
1536
        if acceptorResp.RejectChannel() {
47✔
UNCOV
1537
                f.failFundingFlow(peer, cid, acceptorResp.ChanAcceptError)
×
UNCOV
1538
                return
×
UNCOV
1539
        }
×
1540

1541
        log.Infof("Recv'd fundingRequest(amt=%v, push=%v, delay=%v, "+
47✔
1542
                "pendingId=%x) from peer(%x)", amt, msg.PushAmount,
47✔
1543
                msg.CsvDelay, msg.PendingChannelID,
47✔
1544
                peer.IdentityKey().SerializeCompressed())
47✔
1545

47✔
1546
        // Attempt to initialize a reservation within the wallet. If the wallet
47✔
1547
        // has insufficient resources to create the channel, then the
47✔
1548
        // reservation attempt may be rejected. Note that since we're on the
47✔
1549
        // responding side of a single funder workflow, we don't commit any
47✔
1550
        // funds to the channel ourselves.
47✔
1551
        //
47✔
1552
        // Before we init the channel, we'll also check to see what commitment
47✔
1553
        // format we can use with this peer. This is dependent on *both* us and
47✔
1554
        // the remote peer are signaling the proper feature bit if we're using
47✔
1555
        // implicit negotiation, and simply the channel type sent over if we're
47✔
1556
        // using explicit negotiation.
47✔
1557
        chanType, commitType, err := negotiateCommitmentType(
47✔
1558
                msg.ChannelType, peer.LocalFeatures(), peer.RemoteFeatures(),
47✔
1559
        )
47✔
1560
        if err != nil {
47✔
1561
                // TODO(roasbeef): should be using soft errors
×
1562
                log.Errorf("channel type negotiation failed: %v", err)
×
1563
                f.failFundingFlow(peer, cid, err)
×
1564
                return
×
1565
        }
×
1566

1567
        var scidFeatureVal bool
47✔
1568
        if hasFeatures(
47✔
1569
                peer.LocalFeatures(), peer.RemoteFeatures(),
47✔
1570
                lnwire.ScidAliasOptional,
47✔
1571
        ) {
50✔
1572

3✔
1573
                scidFeatureVal = true
3✔
1574
        }
3✔
1575

1576
        var (
47✔
1577
                zeroConf bool
47✔
1578
                scid     bool
47✔
1579
        )
47✔
1580

47✔
1581
        // Only echo back a channel type in AcceptChannel if we actually used
47✔
1582
        // explicit negotiation above.
47✔
1583
        if chanType != nil {
51✔
1584
                // Check if the channel type includes the zero-conf or
4✔
1585
                // scid-alias bits.
4✔
1586
                featureVec := lnwire.RawFeatureVector(*chanType)
4✔
1587
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
4✔
1588
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
4✔
1589

4✔
1590
                // If the zero-conf channel type was negotiated, ensure that
4✔
1591
                // the acceptor allows it.
4✔
1592
                if zeroConf && !acceptorResp.ZeroConf {
4✔
1593
                        // Fail the funding flow.
×
1594
                        flowErr := fmt.Errorf("channel acceptor blocked " +
×
1595
                                "zero-conf channel negotiation")
×
1596
                        log.Errorf("Cancelling funding flow for %v based on "+
×
1597
                                "channel acceptor response: %v", cid, flowErr)
×
1598
                        f.failFundingFlow(peer, cid, flowErr)
×
1599
                        return
×
1600
                }
×
1601

1602
                // If the zero-conf channel type wasn't negotiated and the
1603
                // fundee still wants a zero-conf channel, perform more checks.
1604
                // Require that both sides have the scid-alias feature bit set.
1605
                // We don't require anchors here - this is for compatibility
1606
                // with LDK.
1607
                if !zeroConf && acceptorResp.ZeroConf {
4✔
1608
                        if !scidFeatureVal {
×
1609
                                // Fail the funding flow.
×
1610
                                flowErr := fmt.Errorf("scid-alias feature " +
×
1611
                                        "must be negotiated for zero-conf")
×
1612
                                log.Errorf("Cancelling funding flow for "+
×
1613
                                        "zero-conf channel %v: %v", cid,
×
1614
                                        flowErr)
×
1615
                                f.failFundingFlow(peer, cid, flowErr)
×
1616
                                return
×
1617
                        }
×
1618

1619
                        // Set zeroConf to true to enable the zero-conf flow.
1620
                        zeroConf = true
×
1621
                }
1622
        }
1623

1624
        public := msg.ChannelFlags&lnwire.FFAnnounceChannel != 0
47✔
1625
        switch {
47✔
1626
        // Sending the option-scid-alias channel type for a public channel is
1627
        // disallowed.
1628
        case public && scid:
×
1629
                err = fmt.Errorf("option-scid-alias chantype for public " +
×
1630
                        "channel")
×
1631
                log.Errorf("Cancelling funding flow for public channel %v "+
×
1632
                        "with scid-alias: %v", cid, err)
×
1633
                f.failFundingFlow(peer, cid, err)
×
1634

×
1635
                return
×
1636

1637
        // The current variant of taproot channels can only be used with
1638
        // unadvertised channels for now.
1639
        case commitType.IsTaproot() && public:
×
1640
                err = fmt.Errorf("taproot channel type for public channel")
×
1641
                log.Errorf("Cancelling funding flow for public taproot "+
×
1642
                        "channel %v: %v", cid, err)
×
1643
                f.failFundingFlow(peer, cid, err)
×
1644

×
1645
                return
×
1646
        }
1647

1648
        // At this point, if we have an AuxFundingController active, we'll
1649
        // check to see if we have a special tapscript root to use in our
1650
        // MuSig funding output.
1651
        tapscriptRoot, err := fn.MapOptionZ(
47✔
1652
                f.cfg.AuxFundingController,
47✔
1653
                func(c AuxFundingController) AuxTapscriptResult {
47✔
1654
                        return c.DeriveTapscriptRoot(msg.PendingChannelID)
×
1655
                },
×
1656
        ).Unpack()
1657
        if err != nil {
47✔
1658
                err = fmt.Errorf("error deriving tapscript root: %w", err)
×
1659
                log.Error(err)
×
1660
                f.failFundingFlow(peer, cid, err)
×
1661

×
1662
                return
×
1663
        }
×
1664

1665
        req := &lnwallet.InitFundingReserveMsg{
47✔
1666
                ChainHash:        &msg.ChainHash,
47✔
1667
                PendingChanID:    msg.PendingChannelID,
47✔
1668
                NodeID:           peer.IdentityKey(),
47✔
1669
                NodeAddr:         peer.Address(),
47✔
1670
                LocalFundingAmt:  0,
47✔
1671
                RemoteFundingAmt: amt,
47✔
1672
                CommitFeePerKw:   chainfee.SatPerKWeight(msg.FeePerKiloWeight),
47✔
1673
                FundingFeePerKw:  0,
47✔
1674
                PushMSat:         msg.PushAmount,
47✔
1675
                Flags:            msg.ChannelFlags,
47✔
1676
                MinConfs:         1,
47✔
1677
                CommitType:       commitType,
47✔
1678
                ZeroConf:         zeroConf,
47✔
1679
                OptionScidAlias:  scid,
47✔
1680
                ScidAliasFeature: scidFeatureVal,
47✔
1681
                TapscriptRoot:    tapscriptRoot,
47✔
1682
        }
47✔
1683

47✔
1684
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
47✔
1685
        if err != nil {
47✔
1686
                log.Errorf("Unable to initialize reservation: %v", err)
×
1687
                f.failFundingFlow(peer, cid, err)
×
1688
                return
×
1689
        }
×
1690

1691
        log.Debugf("Initialized channel reservation: zeroConf=%v, psbt=%v, "+
47✔
1692
                "cannedShim=%v", reservation.IsZeroConf(),
47✔
1693
                reservation.IsPsbt(), reservation.IsCannedShim())
47✔
1694

47✔
1695
        if zeroConf {
49✔
1696
                // Store an alias for zero-conf channels. Other option-scid
2✔
1697
                // channels will do this at a later point.
2✔
1698
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
2✔
1699
                if err != nil {
2✔
1700
                        log.Errorf("Unable to request alias: %v", err)
×
1701
                        f.failFundingFlow(peer, cid, err)
×
1702
                        return
×
1703
                }
×
1704

1705
                reservation.AddAlias(aliasScid)
2✔
1706
        }
1707

1708
        // As we're the responder, we get to specify the number of confirmations
1709
        // that we require before both of us consider the channel open. We'll
1710
        // use our mapping to derive the proper number of confirmations based on
1711
        // the amount of the channel, and also if any funds are being pushed to
1712
        // us. If a depth value was set by our channel acceptor, we will use
1713
        // that value instead.
1714
        numConfsReq := f.cfg.NumRequiredConfs(msg.FundingAmount, msg.PushAmount)
47✔
1715
        if acceptorResp.MinAcceptDepth != 0 {
47✔
1716
                numConfsReq = acceptorResp.MinAcceptDepth
×
1717
        }
×
1718

1719
        // We'll ignore the min_depth calculated above if this is a zero-conf
1720
        // channel.
1721
        if zeroConf {
49✔
1722
                numConfsReq = 0
2✔
1723
        }
2✔
1724

1725
        reservation.SetNumConfsRequired(numConfsReq)
47✔
1726

47✔
1727
        // We'll also validate and apply all the constraints the initiating
47✔
1728
        // party is attempting to dictate for our commitment transaction.
47✔
1729
        stateBounds := &channeldb.ChannelStateBounds{
47✔
1730
                ChanReserve:      msg.ChannelReserve,
47✔
1731
                MaxPendingAmount: msg.MaxValueInFlight,
47✔
1732
                MinHTLC:          msg.HtlcMinimum,
47✔
1733
                MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs,
47✔
1734
        }
47✔
1735
        commitParams := &channeldb.CommitmentParams{
47✔
1736
                DustLimit: msg.DustLimit,
47✔
1737
                CsvDelay:  msg.CsvDelay,
47✔
1738
        }
47✔
1739
        err = reservation.CommitConstraints(
47✔
1740
                stateBounds, commitParams, f.cfg.MaxLocalCSVDelay, true,
47✔
1741
        )
47✔
1742
        if err != nil {
48✔
1743
                log.Errorf("Unacceptable channel constraints: %v", err)
1✔
1744
                f.failFundingFlow(peer, cid, err)
1✔
1745
                return
1✔
1746
        }
1✔
1747

1748
        // Check whether the peer supports upfront shutdown, and get a new
1749
        // wallet address if our node is configured to set shutdown addresses by
1750
        // default. We use the upfront shutdown script provided by our channel
1751
        // acceptor (if any) in lieu of user input.
1752
        shutdown, err := getUpfrontShutdownScript(
46✔
1753
                f.cfg.EnableUpfrontShutdown, peer, acceptorResp.UpfrontShutdown,
46✔
1754
                f.selectShutdownScript,
46✔
1755
        )
46✔
1756
        if err != nil {
46✔
1757
                f.failFundingFlow(
×
1758
                        peer, cid,
×
1759
                        fmt.Errorf("getUpfrontShutdownScript error: %w", err),
×
1760
                )
×
1761
                return
×
1762
        }
×
1763
        reservation.SetOurUpfrontShutdown(shutdown)
46✔
1764

46✔
1765
        // If a script enforced channel lease is being proposed, we'll need to
46✔
1766
        // validate its custom TLV records.
46✔
1767
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
46✔
UNCOV
1768
                if msg.LeaseExpiry == nil {
×
1769
                        err := errors.New("missing lease expiry")
×
1770
                        f.failFundingFlow(peer, cid, err)
×
1771
                        return
×
1772
                }
×
1773

1774
                // If we had a shim registered for this channel prior to
1775
                // receiving its corresponding OpenChannel message, then we'll
1776
                // validate the proposed LeaseExpiry against what was registered
1777
                // in our shim.
UNCOV
1778
                if reservation.LeaseExpiry() != 0 {
×
UNCOV
1779
                        if uint32(*msg.LeaseExpiry) !=
×
UNCOV
1780
                                reservation.LeaseExpiry() {
×
1781

×
1782
                                err := errors.New("lease expiry mismatch")
×
1783
                                f.failFundingFlow(peer, cid, err)
×
1784
                                return
×
1785
                        }
×
1786
                }
1787
        }
1788

1789
        log.Infof("Requiring %v confirmations for pendingChan(%x): "+
46✔
1790
                "amt=%v, push_amt=%v, committype=%v, upfrontShutdown=%x",
46✔
1791
                numConfsReq, msg.PendingChannelID, amt, msg.PushAmount,
46✔
1792
                commitType, msg.UpfrontShutdownScript)
46✔
1793

46✔
1794
        // Generate our required constraints for the remote party, using the
46✔
1795
        // values provided by the channel acceptor if they are non-zero.
46✔
1796
        remoteCsvDelay := f.cfg.RequiredRemoteDelay(amt)
46✔
1797
        if acceptorResp.CSVDelay != 0 {
46✔
1798
                remoteCsvDelay = acceptorResp.CSVDelay
×
1799
        }
×
1800

1801
        // If our default dust limit was above their ChannelReserve, we change
1802
        // it to the ChannelReserve. We must make sure the ChannelReserve we
1803
        // send in the AcceptChannel message is above both dust limits.
1804
        // Therefore, take the maximum of msg.DustLimit and our dust limit.
1805
        //
1806
        // NOTE: Even with this bounding, the ChannelAcceptor may return an
1807
        // BOLT#02-invalid ChannelReserve.
1808
        maxDustLimit := reservation.OurContribution().DustLimit
46✔
1809
        if msg.DustLimit > maxDustLimit {
46✔
1810
                maxDustLimit = msg.DustLimit
×
1811
        }
×
1812

1813
        chanReserve := f.cfg.RequiredRemoteChanReserve(amt, maxDustLimit)
46✔
1814
        if acceptorResp.Reserve != 0 {
46✔
1815
                chanReserve = acceptorResp.Reserve
×
1816
        }
×
1817

1818
        remoteMaxValue := f.cfg.RequiredRemoteMaxValue(amt)
46✔
1819
        if acceptorResp.InFlightTotal != 0 {
46✔
1820
                remoteMaxValue = acceptorResp.InFlightTotal
×
1821
        }
×
1822

1823
        maxHtlcs := f.cfg.RequiredRemoteMaxHTLCs(amt)
46✔
1824
        if acceptorResp.HtlcLimit != 0 {
46✔
1825
                maxHtlcs = acceptorResp.HtlcLimit
×
1826
        }
×
1827

1828
        // Default to our default minimum hltc value, replacing it with the
1829
        // channel acceptor's value if it is set.
1830
        minHtlc := f.cfg.DefaultMinHtlcIn
46✔
1831
        if acceptorResp.MinHtlcIn != 0 {
46✔
1832
                minHtlc = acceptorResp.MinHtlcIn
×
1833
        }
×
1834

1835
        // If we are handling a FundingOpen request then we need to specify the
1836
        // default channel fees since they are not provided by the responder
1837
        // interactively.
1838
        ourContribution := reservation.OurContribution()
46✔
1839
        forwardingPolicy := f.defaultForwardingPolicy(
46✔
1840
                ourContribution.ChannelStateBounds,
46✔
1841
        )
46✔
1842

46✔
1843
        // Once the reservation has been created successfully, we add it to
46✔
1844
        // this peer's map of pending reservations to track this particular
46✔
1845
        // reservation until either abort or completion.
46✔
1846
        f.resMtx.Lock()
46✔
1847
        if _, ok := f.activeReservations[peerIDKey]; !ok {
88✔
1848
                f.activeReservations[peerIDKey] = make(pendingChannels)
42✔
1849
        }
42✔
1850
        resCtx := &reservationWithCtx{
46✔
1851
                reservation:       reservation,
46✔
1852
                chanAmt:           amt,
46✔
1853
                forwardingPolicy:  *forwardingPolicy,
46✔
1854
                remoteCsvDelay:    remoteCsvDelay,
46✔
1855
                remoteMinHtlc:     minHtlc,
46✔
1856
                remoteMaxValue:    remoteMaxValue,
46✔
1857
                remoteMaxHtlcs:    maxHtlcs,
46✔
1858
                remoteChanReserve: chanReserve,
46✔
1859
                maxLocalCsv:       f.cfg.MaxLocalCSVDelay,
46✔
1860
                channelType:       chanType,
46✔
1861
                err:               make(chan error, 1),
46✔
1862
                peer:              peer,
46✔
1863
        }
46✔
1864
        f.activeReservations[peerIDKey][msg.PendingChannelID] = resCtx
46✔
1865
        f.resMtx.Unlock()
46✔
1866

46✔
1867
        // Update the timestamp once the fundingOpenMsg has been handled.
46✔
1868
        defer resCtx.updateTimestamp()
46✔
1869

46✔
1870
        cfg := channeldb.ChannelConfig{
46✔
1871
                ChannelStateBounds: channeldb.ChannelStateBounds{
46✔
1872
                        MaxPendingAmount: remoteMaxValue,
46✔
1873
                        ChanReserve:      chanReserve,
46✔
1874
                        MinHTLC:          minHtlc,
46✔
1875
                        MaxAcceptedHtlcs: maxHtlcs,
46✔
1876
                },
46✔
1877
                CommitmentParams: channeldb.CommitmentParams{
46✔
1878
                        DustLimit: msg.DustLimit,
46✔
1879
                        CsvDelay:  remoteCsvDelay,
46✔
1880
                },
46✔
1881
                MultiSigKey: keychain.KeyDescriptor{
46✔
1882
                        PubKey: copyPubKey(msg.FundingKey),
46✔
1883
                },
46✔
1884
                RevocationBasePoint: keychain.KeyDescriptor{
46✔
1885
                        PubKey: copyPubKey(msg.RevocationPoint),
46✔
1886
                },
46✔
1887
                PaymentBasePoint: keychain.KeyDescriptor{
46✔
1888
                        PubKey: copyPubKey(msg.PaymentPoint),
46✔
1889
                },
46✔
1890
                DelayBasePoint: keychain.KeyDescriptor{
46✔
1891
                        PubKey: copyPubKey(msg.DelayedPaymentPoint),
46✔
1892
                },
46✔
1893
                HtlcBasePoint: keychain.KeyDescriptor{
46✔
1894
                        PubKey: copyPubKey(msg.HtlcPoint),
46✔
1895
                },
46✔
1896
        }
46✔
1897

46✔
1898
        // With our parameters set, we'll now process their contribution so we
46✔
1899
        // can move the funding workflow ahead.
46✔
1900
        remoteContribution := &lnwallet.ChannelContribution{
46✔
1901
                FundingAmount:        amt,
46✔
1902
                FirstCommitmentPoint: msg.FirstCommitmentPoint,
46✔
1903
                ChannelConfig:        &cfg,
46✔
1904
                UpfrontShutdown:      msg.UpfrontShutdownScript,
46✔
1905
        }
46✔
1906

46✔
1907
        if resCtx.reservation.IsTaproot() {
48✔
1908
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
2✔
1909
                if err != nil {
2✔
1910
                        log.Error(errNoLocalNonce)
×
1911

×
1912
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
1913

×
1914
                        return
×
1915
                }
×
1916

1917
                remoteContribution.LocalNonce = &musig2.Nonces{
2✔
1918
                        PubNonce: localNonce,
2✔
1919
                }
2✔
1920
        }
1921

1922
        err = reservation.ProcessSingleContribution(remoteContribution)
46✔
1923
        if err != nil {
52✔
1924
                log.Errorf("unable to add contribution reservation: %v", err)
6✔
1925
                f.failFundingFlow(peer, cid, err)
6✔
1926
                return
6✔
1927
        }
6✔
1928

1929
        log.Infof("Sending fundingResp for pending_id(%x)",
40✔
1930
                msg.PendingChannelID)
40✔
1931
        bounds := remoteContribution.ChannelConfig.ChannelStateBounds
40✔
1932
        log.Debugf("Remote party accepted channel state space bounds: %v",
40✔
1933
                lnutils.SpewLogClosure(bounds))
40✔
1934
        params := remoteContribution.ChannelConfig.CommitmentParams
40✔
1935
        log.Debugf("Remote party accepted commitment rendering params: %v",
40✔
1936
                lnutils.SpewLogClosure(params))
40✔
1937

40✔
1938
        reservation.SetState(lnwallet.SentAcceptChannel)
40✔
1939

40✔
1940
        // With the initiator's contribution recorded, respond with our
40✔
1941
        // contribution in the next message of the workflow.
40✔
1942
        fundingAccept := lnwire.AcceptChannel{
40✔
1943
                PendingChannelID:      msg.PendingChannelID,
40✔
1944
                DustLimit:             ourContribution.DustLimit,
40✔
1945
                MaxValueInFlight:      remoteMaxValue,
40✔
1946
                ChannelReserve:        chanReserve,
40✔
1947
                MinAcceptDepth:        uint32(numConfsReq),
40✔
1948
                HtlcMinimum:           minHtlc,
40✔
1949
                CsvDelay:              remoteCsvDelay,
40✔
1950
                MaxAcceptedHTLCs:      maxHtlcs,
40✔
1951
                FundingKey:            ourContribution.MultiSigKey.PubKey,
40✔
1952
                RevocationPoint:       ourContribution.RevocationBasePoint.PubKey,
40✔
1953
                PaymentPoint:          ourContribution.PaymentBasePoint.PubKey,
40✔
1954
                DelayedPaymentPoint:   ourContribution.DelayBasePoint.PubKey,
40✔
1955
                HtlcPoint:             ourContribution.HtlcBasePoint.PubKey,
40✔
1956
                FirstCommitmentPoint:  ourContribution.FirstCommitmentPoint,
40✔
1957
                UpfrontShutdownScript: ourContribution.UpfrontShutdown,
40✔
1958
                ChannelType:           chanType,
40✔
1959
                LeaseExpiry:           msg.LeaseExpiry,
40✔
1960
        }
40✔
1961

40✔
1962
        if commitType.IsTaproot() {
42✔
1963
                fundingAccept.LocalNonce = lnwire.SomeMusig2Nonce(
2✔
1964
                        ourContribution.LocalNonce.PubNonce,
2✔
1965
                )
2✔
1966
        }
2✔
1967

1968
        if err := peer.SendMessage(true, &fundingAccept); err != nil {
40✔
1969
                log.Errorf("unable to send funding response to peer: %v", err)
×
1970
                f.failFundingFlow(peer, cid, err)
×
1971
                return
×
1972
        }
×
1973
}
1974

1975
// funderProcessAcceptChannel processes a response to the workflow initiation
1976
// sent by the remote peer. This message then queues a message with the funding
1977
// outpoint, and a commitment signature to the remote peer.
1978
//
1979
//nolint:funlen
1980
func (f *Manager) funderProcessAcceptChannel(peer lnpeer.Peer,
1981
        msg *lnwire.AcceptChannel) {
32✔
1982

32✔
1983
        pendingChanID := msg.PendingChannelID
32✔
1984
        peerKey := peer.IdentityKey()
32✔
1985
        var peerKeyBytes []byte
32✔
1986
        if peerKey != nil {
64✔
1987
                peerKeyBytes = peerKey.SerializeCompressed()
32✔
1988
        }
32✔
1989

1990
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
32✔
1991
        if err != nil {
32✔
1992
                log.Warnf("Can't find reservation (peerKey:%x, chan_id:%v)",
×
1993
                        peerKeyBytes, pendingChanID)
×
1994
                return
×
1995
        }
×
1996

1997
        // Update the timestamp once the fundingAcceptMsg has been handled.
1998
        defer resCtx.updateTimestamp()
32✔
1999

32✔
2000
        if resCtx.reservation.State() != lnwallet.SentOpenChannel {
32✔
2001
                return
×
2002
        }
×
2003

2004
        log.Infof("Recv'd fundingResponse for pending_id(%x)",
32✔
2005
                pendingChanID[:])
32✔
2006

32✔
2007
        // Create the channel identifier.
32✔
2008
        cid := newChanIdentifier(msg.PendingChannelID)
32✔
2009

32✔
2010
        // Perform some basic validation of any custom TLV records included.
32✔
2011
        //
32✔
2012
        // TODO: Return errors as funding.Error to give context to remote peer?
32✔
2013
        if resCtx.channelType != nil {
36✔
2014
                // We'll want to quickly check that the ChannelType echoed by
4✔
2015
                // the channel request recipient matches what we proposed.
4✔
2016
                if msg.ChannelType == nil {
5✔
2017
                        err := errors.New("explicit channel type not echoed " +
1✔
2018
                                "back")
1✔
2019
                        f.failFundingFlow(peer, cid, err)
1✔
2020
                        return
1✔
2021
                }
1✔
2022
                proposedFeatures := lnwire.RawFeatureVector(*resCtx.channelType)
3✔
2023
                ackedFeatures := lnwire.RawFeatureVector(*msg.ChannelType)
3✔
2024
                if !proposedFeatures.Equals(&ackedFeatures) {
3✔
2025
                        err := errors.New("channel type mismatch")
×
2026
                        f.failFundingFlow(peer, cid, err)
×
2027
                        return
×
2028
                }
×
2029

2030
                // We'll want to do the same with the LeaseExpiry if one should
2031
                // be set.
2032
                if resCtx.reservation.LeaseExpiry() != 0 {
3✔
UNCOV
2033
                        if msg.LeaseExpiry == nil {
×
2034
                                err := errors.New("lease expiry not echoed " +
×
2035
                                        "back")
×
2036
                                f.failFundingFlow(peer, cid, err)
×
2037
                                return
×
2038
                        }
×
UNCOV
2039
                        if uint32(*msg.LeaseExpiry) !=
×
UNCOV
2040
                                resCtx.reservation.LeaseExpiry() {
×
2041

×
2042
                                err := errors.New("lease expiry mismatch")
×
2043
                                f.failFundingFlow(peer, cid, err)
×
2044
                                return
×
2045
                        }
×
2046
                }
2047
        } else if msg.ChannelType != nil {
28✔
2048
                // The spec isn't too clear about whether it's okay to set the
×
2049
                // channel type in the accept_channel response if we didn't
×
2050
                // explicitly set it in the open_channel message. For now, we
×
2051
                // check that it's the same type we'd have arrived through
×
2052
                // implicit negotiation. If it's another type, we fail the flow.
×
2053
                _, implicitCommitType := implicitNegotiateCommitmentType(
×
2054
                        peer.LocalFeatures(), peer.RemoteFeatures(),
×
2055
                )
×
2056

×
2057
                _, negotiatedCommitType, err := negotiateCommitmentType(
×
2058
                        msg.ChannelType, peer.LocalFeatures(),
×
2059
                        peer.RemoteFeatures(),
×
2060
                )
×
2061
                if err != nil {
×
2062
                        err := errors.New("received unexpected channel type")
×
2063
                        f.failFundingFlow(peer, cid, err)
×
2064
                        return
×
2065
                }
×
2066

2067
                if implicitCommitType != negotiatedCommitType {
×
2068
                        err := errors.New("negotiated unexpected channel type")
×
2069
                        f.failFundingFlow(peer, cid, err)
×
2070
                        return
×
2071
                }
×
2072
        }
2073

2074
        // The required number of confirmations should not be greater than the
2075
        // maximum number of confirmations required by the ChainNotifier to
2076
        // properly dispatch confirmations.
2077
        if msg.MinAcceptDepth > chainntnfs.MaxNumConfs {
32✔
2078
                err := lnwallet.ErrNumConfsTooLarge(
1✔
2079
                        msg.MinAcceptDepth, chainntnfs.MaxNumConfs,
1✔
2080
                )
1✔
2081
                log.Warnf("Unacceptable channel constraints: %v", err)
1✔
2082
                f.failFundingFlow(peer, cid, err)
1✔
2083
                return
1✔
2084
        }
1✔
2085

2086
        // Check that zero-conf channels have minimum depth set to 0.
2087
        if resCtx.reservation.IsZeroConf() && msg.MinAcceptDepth != 0 {
30✔
2088
                err = fmt.Errorf("zero-conf channel has min_depth non-zero")
×
2089
                log.Warn(err)
×
2090
                f.failFundingFlow(peer, cid, err)
×
2091
                return
×
2092
        }
×
2093

2094
        // If this is not a zero-conf channel but the peer responded with a
2095
        // min-depth of zero, we will use our minimum of 1 instead.
2096
        minDepth := msg.MinAcceptDepth
30✔
2097
        if !resCtx.reservation.IsZeroConf() && minDepth == 0 {
30✔
2098
                log.Infof("Responder to pending_id=%v sent a minimum "+
×
2099
                        "confirmation depth of 0 for non-zero-conf channel. "+
×
2100
                        "We will use a minimum depth of 1 instead.",
×
2101
                        cid.tempChanID)
×
2102

×
2103
                minDepth = 1
×
2104
        }
×
2105

2106
        // We'll also specify the responder's preference for the number of
2107
        // required confirmations, and also the set of channel constraints
2108
        // they've specified for commitment states we can create.
2109
        resCtx.reservation.SetNumConfsRequired(uint16(minDepth))
30✔
2110
        bounds := channeldb.ChannelStateBounds{
30✔
2111
                ChanReserve:      msg.ChannelReserve,
30✔
2112
                MaxPendingAmount: msg.MaxValueInFlight,
30✔
2113
                MinHTLC:          msg.HtlcMinimum,
30✔
2114
                MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs,
30✔
2115
        }
30✔
2116
        commitParams := channeldb.CommitmentParams{
30✔
2117
                DustLimit: msg.DustLimit,
30✔
2118
                CsvDelay:  msg.CsvDelay,
30✔
2119
        }
30✔
2120
        err = resCtx.reservation.CommitConstraints(
30✔
2121
                &bounds, &commitParams, resCtx.maxLocalCsv, false,
30✔
2122
        )
30✔
2123
        if err != nil {
31✔
2124
                log.Warnf("Unacceptable channel constraints: %v", err)
1✔
2125
                f.failFundingFlow(peer, cid, err)
1✔
2126
                return
1✔
2127
        }
1✔
2128

2129
        cfg := channeldb.ChannelConfig{
29✔
2130
                ChannelStateBounds: channeldb.ChannelStateBounds{
29✔
2131
                        MaxPendingAmount: resCtx.remoteMaxValue,
29✔
2132
                        ChanReserve:      resCtx.remoteChanReserve,
29✔
2133
                        MinHTLC:          resCtx.remoteMinHtlc,
29✔
2134
                        MaxAcceptedHtlcs: resCtx.remoteMaxHtlcs,
29✔
2135
                },
29✔
2136
                CommitmentParams: channeldb.CommitmentParams{
29✔
2137
                        DustLimit: msg.DustLimit,
29✔
2138
                        CsvDelay:  resCtx.remoteCsvDelay,
29✔
2139
                },
29✔
2140
                MultiSigKey: keychain.KeyDescriptor{
29✔
2141
                        PubKey: copyPubKey(msg.FundingKey),
29✔
2142
                },
29✔
2143
                RevocationBasePoint: keychain.KeyDescriptor{
29✔
2144
                        PubKey: copyPubKey(msg.RevocationPoint),
29✔
2145
                },
29✔
2146
                PaymentBasePoint: keychain.KeyDescriptor{
29✔
2147
                        PubKey: copyPubKey(msg.PaymentPoint),
29✔
2148
                },
29✔
2149
                DelayBasePoint: keychain.KeyDescriptor{
29✔
2150
                        PubKey: copyPubKey(msg.DelayedPaymentPoint),
29✔
2151
                },
29✔
2152
                HtlcBasePoint: keychain.KeyDescriptor{
29✔
2153
                        PubKey: copyPubKey(msg.HtlcPoint),
29✔
2154
                },
29✔
2155
        }
29✔
2156

29✔
2157
        // The remote node has responded with their portion of the channel
29✔
2158
        // contribution. At this point, we can process their contribution which
29✔
2159
        // allows us to construct and sign both the commitment transaction, and
29✔
2160
        // the funding transaction.
29✔
2161
        remoteContribution := &lnwallet.ChannelContribution{
29✔
2162
                FirstCommitmentPoint: msg.FirstCommitmentPoint,
29✔
2163
                ChannelConfig:        &cfg,
29✔
2164
                UpfrontShutdown:      msg.UpfrontShutdownScript,
29✔
2165
        }
29✔
2166

29✔
2167
        if resCtx.reservation.IsTaproot() {
31✔
2168
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
2✔
2169
                if err != nil {
2✔
2170
                        log.Error(errNoLocalNonce)
×
2171

×
2172
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
2173

×
2174
                        return
×
2175
                }
×
2176

2177
                remoteContribution.LocalNonce = &musig2.Nonces{
2✔
2178
                        PubNonce: localNonce,
2✔
2179
                }
2✔
2180
        }
2181

2182
        err = resCtx.reservation.ProcessContribution(remoteContribution)
29✔
2183

29✔
2184
        // The wallet has detected that a PSBT funding process was requested by
29✔
2185
        // the user and has halted the funding process after negotiating the
29✔
2186
        // multisig keys. We now have everything that is needed for the user to
29✔
2187
        // start constructing a PSBT that sends to the multisig funding address.
29✔
2188
        var psbtIntent *chanfunding.PsbtIntent
29✔
2189
        if psbtErr, ok := err.(*lnwallet.PsbtFundingRequired); ok {
29✔
UNCOV
2190
                // Return the information that is needed by the user to
×
UNCOV
2191
                // construct the PSBT back to the caller.
×
UNCOV
2192
                addr, amt, packet, err := psbtErr.Intent.FundingParams()
×
UNCOV
2193
                if err != nil {
×
2194
                        log.Errorf("Unable to process PSBT funding params "+
×
2195
                                "for contribution from %x: %v", peerKeyBytes,
×
2196
                                err)
×
2197
                        f.failFundingFlow(peer, cid, err)
×
2198
                        return
×
2199
                }
×
UNCOV
2200
                var buf bytes.Buffer
×
UNCOV
2201
                err = packet.Serialize(&buf)
×
UNCOV
2202
                if err != nil {
×
2203
                        log.Errorf("Unable to serialize PSBT for "+
×
2204
                                "contribution from %x: %v", peerKeyBytes, err)
×
2205
                        f.failFundingFlow(peer, cid, err)
×
2206
                        return
×
2207
                }
×
UNCOV
2208
                resCtx.updates <- &lnrpc.OpenStatusUpdate{
×
UNCOV
2209
                        PendingChanId: pendingChanID[:],
×
UNCOV
2210
                        Update: &lnrpc.OpenStatusUpdate_PsbtFund{
×
UNCOV
2211
                                PsbtFund: &lnrpc.ReadyForPsbtFunding{
×
UNCOV
2212
                                        FundingAddress: addr.EncodeAddress(),
×
UNCOV
2213
                                        FundingAmount:  amt,
×
UNCOV
2214
                                        Psbt:           buf.Bytes(),
×
UNCOV
2215
                                },
×
UNCOV
2216
                        },
×
UNCOV
2217
                }
×
UNCOV
2218
                psbtIntent = psbtErr.Intent
×
2219
        } else if err != nil {
29✔
2220
                log.Errorf("Unable to process contribution from %x: %v",
×
2221
                        peerKeyBytes, err)
×
2222
                f.failFundingFlow(peer, cid, err)
×
2223
                return
×
2224
        }
×
2225

2226
        log.Infof("pendingChan(%x): remote party proposes num_confs=%v, "+
29✔
2227
                "csv_delay=%v", pendingChanID[:], msg.MinAcceptDepth,
29✔
2228
                msg.CsvDelay)
29✔
2229
        bounds = remoteContribution.ChannelConfig.ChannelStateBounds
29✔
2230
        log.Debugf("Remote party accepted channel state space bounds: %v",
29✔
2231
                lnutils.SpewLogClosure(bounds))
29✔
2232
        commitParams = remoteContribution.ChannelConfig.CommitmentParams
29✔
2233
        log.Debugf("Remote party accepted commitment rendering params: %v",
29✔
2234
                lnutils.SpewLogClosure(commitParams))
29✔
2235

29✔
2236
        // If the user requested funding through a PSBT, we cannot directly
29✔
2237
        // continue now and need to wait for the fully funded and signed PSBT
29✔
2238
        // to arrive. To not block any other channels from opening, we wait in
29✔
2239
        // a separate goroutine.
29✔
2240
        if psbtIntent != nil {
29✔
UNCOV
2241
                f.wg.Add(1)
×
UNCOV
2242
                go func() {
×
UNCOV
2243
                        defer f.wg.Done()
×
UNCOV
2244

×
UNCOV
2245
                        f.waitForPsbt(psbtIntent, resCtx, cid)
×
UNCOV
2246
                }()
×
2247

2248
                // With the new goroutine spawned, we can now exit to unblock
2249
                // the main event loop.
UNCOV
2250
                return
×
2251
        }
2252

2253
        // In a normal, non-PSBT funding flow, we can jump directly to the next
2254
        // step where we expect our contribution to be finalized.
2255
        f.continueFundingAccept(resCtx, cid)
29✔
2256
}
2257

2258
// waitForPsbt blocks until either a signed PSBT arrives, an error occurs or
2259
// the funding manager shuts down. In the case of a valid PSBT, the funding flow
2260
// is continued.
2261
//
2262
// NOTE: This method must be called as a goroutine.
2263
func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
UNCOV
2264
        resCtx *reservationWithCtx, cid *chanIdentifier) {
×
UNCOV
2265

×
UNCOV
2266
        // failFlow is a helper that logs an error message with the current
×
UNCOV
2267
        // context and then fails the funding flow.
×
UNCOV
2268
        peerKey := resCtx.peer.IdentityKey()
×
UNCOV
2269
        failFlow := func(errMsg string, cause error) {
×
UNCOV
2270
                log.Errorf("Unable to handle funding accept message "+
×
UNCOV
2271
                        "for peer_key=%x, pending_chan_id=%x: %s: %v",
×
UNCOV
2272
                        peerKey.SerializeCompressed(), cid.tempChanID, errMsg,
×
UNCOV
2273
                        cause)
×
UNCOV
2274
                f.failFundingFlow(resCtx.peer, cid, cause)
×
UNCOV
2275
        }
×
2276

2277
        // We'll now wait until the intent has received the final and complete
2278
        // funding transaction. If the channel is closed without any error being
2279
        // sent, we know everything's going as expected.
UNCOV
2280
        select {
×
UNCOV
2281
        case err := <-intent.PsbtReady:
×
UNCOV
2282
                switch err {
×
2283
                // If the user canceled the funding reservation, we need to
2284
                // inform the other peer about us canceling the reservation.
UNCOV
2285
                case chanfunding.ErrUserCanceled:
×
UNCOV
2286
                        failFlow("aborting PSBT flow", err)
×
UNCOV
2287
                        return
×
2288

2289
                // If the remote canceled the funding reservation, we don't need
2290
                // to send another fail message. But we want to inform the user
2291
                // about what happened.
UNCOV
2292
                case chanfunding.ErrRemoteCanceled:
×
UNCOV
2293
                        log.Infof("Remote canceled, aborting PSBT flow "+
×
UNCOV
2294
                                "for peer_key=%x, pending_chan_id=%x",
×
UNCOV
2295
                                peerKey.SerializeCompressed(), cid.tempChanID)
×
UNCOV
2296
                        return
×
2297

2298
                // Nil error means the flow continues normally now.
UNCOV
2299
                case nil:
×
2300

2301
                // For any other error, we'll fail the funding flow.
2302
                default:
×
2303
                        failFlow("error waiting for PSBT flow", err)
×
2304
                        return
×
2305
                }
2306

2307
                // At this point, we'll see if there's an AuxFundingDesc we
2308
                // need to deliver so the funding process can continue
2309
                // properly.
UNCOV
2310
                auxFundingDesc, err := fn.MapOptionZ(
×
UNCOV
2311
                        f.cfg.AuxFundingController,
×
UNCOV
2312
                        func(c AuxFundingController) AuxFundingDescResult {
×
2313
                                return c.DescFromPendingChanID(
×
2314
                                        cid.tempChanID,
×
2315
                                        lnwallet.NewAuxChanState(
×
2316
                                                resCtx.reservation.ChanState(),
×
2317
                                        ),
×
2318
                                        resCtx.reservation.CommitmentKeyRings(),
×
2319
                                        true,
×
2320
                                )
×
2321
                        },
×
2322
                ).Unpack()
UNCOV
2323
                if err != nil {
×
2324
                        failFlow("error continuing PSBT flow", err)
×
2325
                        return
×
2326
                }
×
2327

2328
                // A non-nil error means we can continue the funding flow.
2329
                // Notify the wallet so it can prepare everything we need to
2330
                // continue.
2331
                //
2332
                // We'll also pass along the aux funding controller as well,
2333
                // which may be used to help process the finalized PSBT.
UNCOV
2334
                err = resCtx.reservation.ProcessPsbt(auxFundingDesc)
×
UNCOV
2335
                if err != nil {
×
2336
                        failFlow("error continuing PSBT flow", err)
×
2337
                        return
×
2338
                }
×
2339

2340
                // We are now ready to continue the funding flow.
UNCOV
2341
                f.continueFundingAccept(resCtx, cid)
×
2342

2343
        // Handle a server shutdown as well because the reservation won't
2344
        // survive a restart as it's in memory only.
2345
        case <-f.quit:
×
2346
                log.Errorf("Unable to handle funding accept message "+
×
2347
                        "for peer_key=%x, pending_chan_id=%x: funding manager "+
×
2348
                        "shutting down", peerKey.SerializeCompressed(),
×
2349
                        cid.tempChanID)
×
2350
                return
×
2351
        }
2352
}
2353

2354
// continueFundingAccept continues the channel funding flow once our
2355
// contribution is finalized, the channel output is known and the funding
2356
// transaction is signed.
2357
func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
2358
        cid *chanIdentifier) {
29✔
2359

29✔
2360
        // Now that we have their contribution, we can extract, then send over
29✔
2361
        // both the funding out point and our signature for their version of
29✔
2362
        // the commitment transaction to the remote peer.
29✔
2363
        outPoint := resCtx.reservation.FundingOutpoint()
29✔
2364
        _, sig := resCtx.reservation.OurSignatures()
29✔
2365

29✔
2366
        // A new channel has almost finished the funding process. In order to
29✔
2367
        // properly synchronize with the writeHandler goroutine, we add a new
29✔
2368
        // channel to the barriers map which will be closed once the channel is
29✔
2369
        // fully open.
29✔
2370
        channelID := lnwire.NewChanIDFromOutPoint(*outPoint)
29✔
2371
        log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
29✔
2372

29✔
2373
        // The next message that advances the funding flow will reference the
29✔
2374
        // channel via its permanent channel ID, so we'll set up this mapping
29✔
2375
        // so we can retrieve the reservation context once we get the
29✔
2376
        // FundingSigned message.
29✔
2377
        f.resMtx.Lock()
29✔
2378
        f.signedReservations[channelID] = cid.tempChanID
29✔
2379
        f.resMtx.Unlock()
29✔
2380

29✔
2381
        log.Infof("Generated ChannelPoint(%v) for pending_id(%x)", outPoint,
29✔
2382
                cid.tempChanID[:])
29✔
2383

29✔
2384
        // Before sending FundingCreated sent, we notify Brontide to keep track
29✔
2385
        // of this pending open channel.
29✔
2386
        err := resCtx.peer.AddPendingChannel(channelID, f.quit)
29✔
2387
        if err != nil {
29✔
2388
                pubKey := resCtx.peer.IdentityKey().SerializeCompressed()
×
2389
                log.Errorf("Unable to add pending channel %v with peer %x: %v",
×
2390
                        channelID, pubKey, err)
×
2391
        }
×
2392

2393
        // Once Brontide is aware of this channel, we need to set it in
2394
        // chanIdentifier so this channel will be removed from Brontide if the
2395
        // funding flow fails.
2396
        cid.setChanID(channelID)
29✔
2397

29✔
2398
        // Send the FundingCreated msg.
29✔
2399
        fundingCreated := &lnwire.FundingCreated{
29✔
2400
                PendingChannelID: cid.tempChanID,
29✔
2401
                FundingPoint:     *outPoint,
29✔
2402
        }
29✔
2403

29✔
2404
        // If this is a taproot channel, then we'll need to populate the musig2
29✔
2405
        // partial sig field instead of the regular commit sig field.
29✔
2406
        if resCtx.reservation.IsTaproot() {
31✔
2407
                partialSig, ok := sig.(*lnwallet.MusigPartialSig)
2✔
2408
                if !ok {
2✔
2409
                        err := fmt.Errorf("expected musig partial sig, got %T",
×
2410
                                sig)
×
2411
                        log.Error(err)
×
2412
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2413

×
2414
                        return
×
2415
                }
×
2416

2417
                fundingCreated.PartialSig = lnwire.MaybePartialSigWithNonce(
2✔
2418
                        partialSig.ToWireSig(),
2✔
2419
                )
2✔
2420
        } else {
27✔
2421
                fundingCreated.CommitSig, err = lnwire.NewSigFromSignature(sig)
27✔
2422
                if err != nil {
27✔
2423
                        log.Errorf("Unable to parse signature: %v", err)
×
2424
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2425
                        return
×
2426
                }
×
2427
        }
2428

2429
        resCtx.reservation.SetState(lnwallet.SentFundingCreated)
29✔
2430

29✔
2431
        if err := resCtx.peer.SendMessage(true, fundingCreated); err != nil {
29✔
2432
                log.Errorf("Unable to send funding complete message: %v", err)
×
2433
                f.failFundingFlow(resCtx.peer, cid, err)
×
2434
                return
×
2435
        }
×
2436
}
2437

2438
// fundeeProcessFundingCreated progresses the funding workflow when the daemon
2439
// is on the responding side of a single funder workflow. Once this message has
2440
// been processed, a signature is sent to the remote peer allowing it to
2441
// broadcast the funding transaction, progressing the workflow into the final
2442
// stage.
2443
//
2444
//nolint:funlen
2445
func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
2446
        msg *lnwire.FundingCreated) {
27✔
2447

27✔
2448
        peerKey := peer.IdentityKey()
27✔
2449
        pendingChanID := msg.PendingChannelID
27✔
2450

27✔
2451
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
27✔
2452
        if err != nil {
27✔
2453
                log.Warnf("can't find reservation (peer_id:%v, chan_id:%x)",
×
2454
                        peerKey, pendingChanID[:])
×
2455
                return
×
2456
        }
×
2457

2458
        // The channel initiator has responded with the funding outpoint of the
2459
        // final funding transaction, as well as a signature for our version of
2460
        // the commitment transaction. So at this point, we can validate the
2461
        // initiator's commitment transaction, then send our own if it's valid.
2462
        fundingOut := msg.FundingPoint
27✔
2463
        log.Infof("completing pending_id(%x) with ChannelPoint(%v)",
27✔
2464
                pendingChanID[:], fundingOut)
27✔
2465

27✔
2466
        if resCtx.reservation.State() != lnwallet.SentAcceptChannel {
27✔
2467
                return
×
2468
        }
×
2469

2470
        // Create the channel identifier without setting the active channel ID.
2471
        cid := newChanIdentifier(pendingChanID)
27✔
2472

27✔
2473
        // For taproot channels, the commit signature is actually the partial
27✔
2474
        // signature. Otherwise, we can convert the ECDSA commit signature into
27✔
2475
        // our internal input.Signature type.
27✔
2476
        var commitSig input.Signature
27✔
2477
        if resCtx.reservation.IsTaproot() {
29✔
2478
                partialSig, err := msg.PartialSig.UnwrapOrErrV(errNoPartialSig)
2✔
2479
                if err != nil {
2✔
2480
                        f.failFundingFlow(peer, cid, err)
×
2481

×
2482
                        return
×
2483
                }
×
2484

2485
                commitSig = new(lnwallet.MusigPartialSig).FromWireSig(
2✔
2486
                        &partialSig,
2✔
2487
                )
2✔
2488
        } else {
25✔
2489
                commitSig, err = msg.CommitSig.ToSignature()
25✔
2490
                if err != nil {
25✔
2491
                        log.Errorf("unable to parse signature: %v", err)
×
2492
                        f.failFundingFlow(peer, cid, err)
×
2493
                        return
×
2494
                }
×
2495
        }
2496

2497
        // At this point, we'll see if there's an AuxFundingDesc we need to
2498
        // deliver so the funding process can continue properly.
2499
        auxFundingDesc, err := fn.MapOptionZ(
27✔
2500
                f.cfg.AuxFundingController,
27✔
2501
                func(c AuxFundingController) AuxFundingDescResult {
27✔
2502
                        return c.DescFromPendingChanID(
×
2503
                                cid.tempChanID, lnwallet.NewAuxChanState(
×
2504
                                        resCtx.reservation.ChanState(),
×
2505
                                ), resCtx.reservation.CommitmentKeyRings(),
×
2506
                                true,
×
2507
                        )
×
2508
                },
×
2509
        ).Unpack()
2510
        if err != nil {
27✔
2511
                log.Errorf("error continuing PSBT flow: %v", err)
×
2512
                f.failFundingFlow(peer, cid, err)
×
2513
                return
×
2514
        }
×
2515

2516
        // With all the necessary data available, attempt to advance the
2517
        // funding workflow to the next stage. If this succeeds then the
2518
        // funding transaction will broadcast after our next message.
2519
        // CompleteReservationSingle will also mark the channel as 'IsPending'
2520
        // in the database.
2521
        //
2522
        // We'll also directly pass in the AuxFunding controller as well,
2523
        // which may be used by the reservation system to finalize funding our
2524
        // side.
2525
        completeChan, err := resCtx.reservation.CompleteReservationSingle(
27✔
2526
                &fundingOut, commitSig, auxFundingDesc,
27✔
2527
        )
27✔
2528
        if err != nil {
27✔
2529
                log.Errorf("unable to complete single reservation: %v", err)
×
2530
                f.failFundingFlow(peer, cid, err)
×
2531
                return
×
2532
        }
×
2533

2534
        // Get forwarding policy before deleting the reservation context.
2535
        forwardingPolicy := resCtx.forwardingPolicy
27✔
2536

27✔
2537
        // The channel is marked IsPending in the database, and can be removed
27✔
2538
        // from the set of active reservations.
27✔
2539
        f.deleteReservationCtx(peerKey, cid.tempChanID)
27✔
2540

27✔
2541
        // If something goes wrong before the funding transaction is confirmed,
27✔
2542
        // we use this convenience method to delete the pending OpenChannel
27✔
2543
        // from the database.
27✔
2544
        deleteFromDatabase := func() {
27✔
2545
                localBalance := completeChan.LocalCommitment.LocalBalance.ToSatoshis()
×
2546
                closeInfo := &channeldb.ChannelCloseSummary{
×
2547
                        ChanPoint:               completeChan.FundingOutpoint,
×
2548
                        ChainHash:               completeChan.ChainHash,
×
2549
                        RemotePub:               completeChan.IdentityPub,
×
2550
                        CloseType:               channeldb.FundingCanceled,
×
2551
                        Capacity:                completeChan.Capacity,
×
2552
                        SettledBalance:          localBalance,
×
2553
                        RemoteCurrentRevocation: completeChan.RemoteCurrentRevocation,
×
2554
                        RemoteNextRevocation:    completeChan.RemoteNextRevocation,
×
2555
                        LocalChanConfig:         completeChan.LocalChanCfg,
×
2556
                }
×
2557

×
2558
                // Close the channel with us as the initiator because we are
×
2559
                // deciding to exit the funding flow due to an internal error.
×
2560
                if err := completeChan.CloseChannel(
×
2561
                        closeInfo, channeldb.ChanStatusLocalCloseInitiator,
×
2562
                ); err != nil {
×
2563
                        log.Errorf("Failed closing channel %v: %v",
×
2564
                                completeChan.FundingOutpoint, err)
×
2565
                }
×
2566
        }
2567

2568
        // A new channel has almost finished the funding process. In order to
2569
        // properly synchronize with the writeHandler goroutine, we add a new
2570
        // channel to the barriers map which will be closed once the channel is
2571
        // fully open.
2572
        channelID := lnwire.NewChanIDFromOutPoint(fundingOut)
27✔
2573
        log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
27✔
2574

27✔
2575
        fundingSigned := &lnwire.FundingSigned{}
27✔
2576

27✔
2577
        // For taproot channels, we'll need to send over a partial signature
27✔
2578
        // that includes the nonce along side the signature.
27✔
2579
        _, sig := resCtx.reservation.OurSignatures()
27✔
2580
        if resCtx.reservation.IsTaproot() {
29✔
2581
                partialSig, ok := sig.(*lnwallet.MusigPartialSig)
2✔
2582
                if !ok {
2✔
2583
                        err := fmt.Errorf("expected musig partial sig, got %T",
×
2584
                                sig)
×
2585
                        log.Error(err)
×
2586
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2587
                        deleteFromDatabase()
×
2588

×
2589
                        return
×
2590
                }
×
2591

2592
                fundingSigned.PartialSig = lnwire.MaybePartialSigWithNonce(
2✔
2593
                        partialSig.ToWireSig(),
2✔
2594
                )
2✔
2595
        } else {
25✔
2596
                fundingSigned.CommitSig, err = lnwire.NewSigFromSignature(sig)
25✔
2597
                if err != nil {
25✔
2598
                        log.Errorf("unable to parse signature: %v", err)
×
2599
                        f.failFundingFlow(peer, cid, err)
×
2600
                        deleteFromDatabase()
×
2601

×
2602
                        return
×
2603
                }
×
2604
        }
2605

2606
        // Before sending FundingSigned, we notify Brontide first to keep track
2607
        // of this pending open channel.
2608
        if err := peer.AddPendingChannel(channelID, f.quit); err != nil {
27✔
2609
                pubKey := peer.IdentityKey().SerializeCompressed()
×
2610
                log.Errorf("Unable to add pending channel %v with peer %x: %v",
×
2611
                        cid.chanID, pubKey, err)
×
2612
        }
×
2613

2614
        // Once Brontide is aware of this channel, we need to set it in
2615
        // chanIdentifier so this channel will be removed from Brontide if the
2616
        // funding flow fails.
2617
        cid.setChanID(channelID)
27✔
2618

27✔
2619
        fundingSigned.ChanID = cid.chanID
27✔
2620

27✔
2621
        log.Infof("sending FundingSigned for pending_id(%x) over "+
27✔
2622
                "ChannelPoint(%v)", pendingChanID[:], fundingOut)
27✔
2623

27✔
2624
        // With their signature for our version of the commitment transaction
27✔
2625
        // verified, we can now send over our signature to the remote peer.
27✔
2626
        if err := peer.SendMessage(true, fundingSigned); err != nil {
27✔
2627
                log.Errorf("unable to send FundingSigned message: %v", err)
×
2628
                f.failFundingFlow(peer, cid, err)
×
2629
                deleteFromDatabase()
×
2630
                return
×
2631
        }
×
2632

2633
        // With a permanent channel id established we can save the respective
2634
        // forwarding policy in the database. In the channel announcement phase
2635
        // this forwarding policy is retrieved and applied.
2636
        err = f.saveInitialForwardingPolicy(cid.chanID, &forwardingPolicy)
27✔
2637
        if err != nil {
27✔
2638
                log.Errorf("Unable to store the forwarding policy: %v", err)
×
2639
        }
×
2640

2641
        // Now that we've sent over our final signature for this channel, we'll
2642
        // send it to the ChainArbitrator so it can watch for any on-chain
2643
        // actions during this final confirmation stage.
2644
        if err := f.cfg.WatchNewChannel(completeChan, peerKey); err != nil {
27✔
2645
                log.Errorf("Unable to send new ChannelPoint(%v) for "+
×
2646
                        "arbitration: %v", fundingOut, err)
×
2647
        }
×
2648

2649
        // Create an entry in the local discovery map so we can ensure that we
2650
        // process the channel confirmation fully before we receive a
2651
        // channel_ready message.
2652
        f.localDiscoverySignals.Store(cid.chanID, make(chan struct{}))
27✔
2653

27✔
2654
        // Inform the ChannelNotifier that the channel has entered
27✔
2655
        // pending open state.
27✔
2656
        f.cfg.NotifyPendingOpenChannelEvent(fundingOut, completeChan)
27✔
2657

27✔
2658
        // At this point we have sent our last funding message to the
27✔
2659
        // initiating peer before the funding transaction will be broadcast.
27✔
2660
        // With this last message, our job as the responder is now complete.
27✔
2661
        // We'll wait for the funding transaction to reach the specified number
27✔
2662
        // of confirmations, then start normal operations.
27✔
2663
        //
27✔
2664
        // When we get to this point we have sent the signComplete message to
27✔
2665
        // the channel funder, and BOLT#2 specifies that we MUST remember the
27✔
2666
        // channel for reconnection. The channel is already marked
27✔
2667
        // as pending in the database, so in case of a disconnect or restart,
27✔
2668
        // we will continue waiting for the confirmation the next time we start
27✔
2669
        // the funding manager. In case the funding transaction never appears
27✔
2670
        // on the blockchain, we must forget this channel. We therefore
27✔
2671
        // completely forget about this channel if we haven't seen the funding
27✔
2672
        // transaction in 288 blocks (~ 48 hrs), by canceling the reservation
27✔
2673
        // and canceling the wait for the funding confirmation.
27✔
2674
        f.wg.Add(1)
27✔
2675
        go f.advanceFundingState(completeChan, pendingChanID, nil)
27✔
2676
}
2677

2678
// funderProcessFundingSigned processes the final message received in a single
2679
// funder workflow. Once this message is processed, the funding transaction is
2680
// broadcast. Once the funding transaction reaches a sufficient number of
2681
// confirmations, a message is sent to the responding peer along with a compact
2682
// encoding of the location of the channel within the blockchain.
2683
func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
2684
        msg *lnwire.FundingSigned) {
27✔
2685

27✔
2686
        // As the funding signed message will reference the reservation by its
27✔
2687
        // permanent channel ID, we'll need to perform an intermediate look up
27✔
2688
        // before we can obtain the reservation.
27✔
2689
        f.resMtx.Lock()
27✔
2690
        pendingChanID, ok := f.signedReservations[msg.ChanID]
27✔
2691
        delete(f.signedReservations, msg.ChanID)
27✔
2692
        f.resMtx.Unlock()
27✔
2693

27✔
2694
        // Create the channel identifier and set the channel ID.
27✔
2695
        //
27✔
2696
        // NOTE: we may get an empty pending channel ID here if the key cannot
27✔
2697
        // be found, which means when we cancel the reservation context in
27✔
2698
        // `failFundingFlow`, we will get an error. In this case, we will send
27✔
2699
        // an error msg to our peer using the active channel ID.
27✔
2700
        //
27✔
2701
        // TODO(yy): refactor the funding flow to fix this case.
27✔
2702
        cid := newChanIdentifier(pendingChanID)
27✔
2703
        cid.setChanID(msg.ChanID)
27✔
2704

27✔
2705
        // If the pending channel ID is not found, fail the funding flow.
27✔
2706
        if !ok {
27✔
2707
                // NOTE: we directly overwrite the pending channel ID here for
×
2708
                // this rare case since we don't have a valid pending channel
×
2709
                // ID.
×
2710
                cid.tempChanID = msg.ChanID
×
2711

×
2712
                err := fmt.Errorf("unable to find signed reservation for "+
×
2713
                        "chan_id=%x", msg.ChanID)
×
2714
                log.Warnf(err.Error())
×
2715
                f.failFundingFlow(peer, cid, err)
×
2716
                return
×
2717
        }
×
2718

2719
        peerKey := peer.IdentityKey()
27✔
2720
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
27✔
2721
        if err != nil {
27✔
2722
                log.Warnf("Unable to find reservation (peer_id:%v, "+
×
2723
                        "chan_id:%x)", peerKey, pendingChanID[:])
×
2724
                // TODO: add ErrChanNotFound?
×
2725
                f.failFundingFlow(peer, cid, err)
×
2726
                return
×
2727
        }
×
2728

2729
        if resCtx.reservation.State() != lnwallet.SentFundingCreated {
27✔
2730
                err := fmt.Errorf("unable to find reservation for chan_id=%x",
×
2731
                        msg.ChanID)
×
2732
                f.failFundingFlow(peer, cid, err)
×
2733

×
2734
                return
×
2735
        }
×
2736

2737
        // Create an entry in the local discovery map so we can ensure that we
2738
        // process the channel confirmation fully before we receive a
2739
        // channel_ready message.
2740
        fundingPoint := resCtx.reservation.FundingOutpoint()
27✔
2741
        permChanID := lnwire.NewChanIDFromOutPoint(*fundingPoint)
27✔
2742
        f.localDiscoverySignals.Store(permChanID, make(chan struct{}))
27✔
2743

27✔
2744
        // We have to store the forwardingPolicy before the reservation context
27✔
2745
        // is deleted. The policy will then be read and applied in
27✔
2746
        // newChanAnnouncement.
27✔
2747
        err = f.saveInitialForwardingPolicy(
27✔
2748
                permChanID, &resCtx.forwardingPolicy,
27✔
2749
        )
27✔
2750
        if err != nil {
27✔
2751
                log.Errorf("Unable to store the forwarding policy: %v", err)
×
2752
        }
×
2753

2754
        // For taproot channels, the commit signature is actually the partial
2755
        // signature. Otherwise, we can convert the ECDSA commit signature into
2756
        // our internal input.Signature type.
2757
        var commitSig input.Signature
27✔
2758
        if resCtx.reservation.IsTaproot() {
29✔
2759
                partialSig, err := msg.PartialSig.UnwrapOrErrV(errNoPartialSig)
2✔
2760
                if err != nil {
2✔
2761
                        f.failFundingFlow(peer, cid, err)
×
2762

×
2763
                        return
×
2764
                }
×
2765

2766
                commitSig = new(lnwallet.MusigPartialSig).FromWireSig(
2✔
2767
                        &partialSig,
2✔
2768
                )
2✔
2769
        } else {
25✔
2770
                commitSig, err = msg.CommitSig.ToSignature()
25✔
2771
                if err != nil {
25✔
2772
                        log.Errorf("unable to parse signature: %v", err)
×
2773
                        f.failFundingFlow(peer, cid, err)
×
2774
                        return
×
2775
                }
×
2776
        }
2777

2778
        completeChan, err := resCtx.reservation.CompleteReservation(
27✔
2779
                nil, commitSig,
27✔
2780
        )
27✔
2781
        if err != nil {
27✔
2782
                log.Errorf("Unable to complete reservation sign "+
×
2783
                        "complete: %v", err)
×
2784
                f.failFundingFlow(peer, cid, err)
×
2785
                return
×
2786
        }
×
2787

2788
        // The channel is now marked IsPending in the database, and we can
2789
        // delete it from our set of active reservations.
2790
        f.deleteReservationCtx(peerKey, pendingChanID)
27✔
2791

27✔
2792
        // Broadcast the finalized funding transaction to the network, but only
27✔
2793
        // if we actually have the funding transaction.
27✔
2794
        if completeChan.ChanType.HasFundingTx() {
53✔
2795
                fundingTx := completeChan.FundingTxn
26✔
2796
                var fundingTxBuf bytes.Buffer
26✔
2797
                if err := fundingTx.Serialize(&fundingTxBuf); err != nil {
26✔
2798
                        log.Errorf("Unable to serialize funding "+
×
2799
                                "transaction %v: %v", fundingTx.TxHash(), err)
×
2800

×
2801
                        // Clear the buffer of any bytes that were written
×
2802
                        // before the serialization error to prevent logging an
×
2803
                        // incomplete transaction.
×
2804
                        fundingTxBuf.Reset()
×
2805
                }
×
2806

2807
                log.Infof("Broadcasting funding tx for ChannelPoint(%v): %x",
26✔
2808
                        completeChan.FundingOutpoint, fundingTxBuf.Bytes())
26✔
2809

26✔
2810
                // Set a nil short channel ID at this stage because we do not
26✔
2811
                // know it until our funding tx confirms.
26✔
2812
                label := labels.MakeLabel(
26✔
2813
                        labels.LabelTypeChannelOpen, nil,
26✔
2814
                )
26✔
2815

26✔
2816
                err = f.cfg.PublishTransaction(fundingTx, label)
26✔
2817
                if err != nil {
26✔
2818
                        log.Errorf("Unable to broadcast funding tx %x for "+
×
2819
                                "ChannelPoint(%v): %v", fundingTxBuf.Bytes(),
×
2820
                                completeChan.FundingOutpoint, err)
×
2821

×
2822
                        // We failed to broadcast the funding transaction, but
×
2823
                        // watch the channel regardless, in case the
×
2824
                        // transaction made it to the network. We will retry
×
2825
                        // broadcast at startup.
×
2826
                        //
×
2827
                        // TODO(halseth): retry more often? Handle with CPFP?
×
2828
                        // Just delete from the DB?
×
2829
                }
×
2830
        }
2831

2832
        // Before we proceed, if we have a funding hook that wants a
2833
        // notification that it's safe to broadcast the funding transaction,
2834
        // then we'll send that now.
2835
        err = fn.MapOptionZ(
27✔
2836
                f.cfg.AuxFundingController,
27✔
2837
                func(controller AuxFundingController) error {
27✔
2838
                        return controller.ChannelFinalized(cid.tempChanID)
×
2839
                },
×
2840
        )
2841
        if err != nil {
27✔
2842
                log.Errorf("Failed to inform aux funding controller about "+
×
2843
                        "ChannelPoint(%v) being finalized: %v", fundingPoint,
×
2844
                        err)
×
2845
        }
×
2846

2847
        // Now that we have a finalized reservation for this funding flow,
2848
        // we'll send the to be active channel to the ChainArbitrator so it can
2849
        // watch for any on-chain actions before the channel has fully
2850
        // confirmed.
2851
        if err := f.cfg.WatchNewChannel(completeChan, peerKey); err != nil {
27✔
2852
                log.Errorf("Unable to send new ChannelPoint(%v) for "+
×
2853
                        "arbitration: %v", fundingPoint, err)
×
2854
        }
×
2855

2856
        log.Infof("Finalizing pending_id(%x) over ChannelPoint(%v), "+
27✔
2857
                "waiting for channel open on-chain", pendingChanID[:],
27✔
2858
                fundingPoint)
27✔
2859

27✔
2860
        // Send an update to the upstream client that the negotiation process
27✔
2861
        // is over.
27✔
2862
        upd := &lnrpc.OpenStatusUpdate{
27✔
2863
                Update: &lnrpc.OpenStatusUpdate_ChanPending{
27✔
2864
                        ChanPending: &lnrpc.PendingUpdate{
27✔
2865
                                Txid:        fundingPoint.Hash[:],
27✔
2866
                                OutputIndex: fundingPoint.Index,
27✔
2867
                        },
27✔
2868
                },
27✔
2869
                PendingChanId: pendingChanID[:],
27✔
2870
        }
27✔
2871

27✔
2872
        select {
27✔
2873
        case resCtx.updates <- upd:
27✔
2874
                // Inform the ChannelNotifier that the channel has entered
27✔
2875
                // pending open state.
27✔
2876
                f.cfg.NotifyPendingOpenChannelEvent(*fundingPoint, completeChan)
27✔
2877
        case <-f.quit:
×
2878
                return
×
2879
        }
2880

2881
        // At this point we have broadcast the funding transaction and done all
2882
        // necessary processing.
2883
        f.wg.Add(1)
27✔
2884
        go f.advanceFundingState(completeChan, pendingChanID, resCtx.updates)
27✔
2885
}
2886

2887
// confirmedChannel wraps a confirmed funding transaction, as well as the short
2888
// channel ID which identifies that channel into a single struct. We'll use
2889
// this to pass around the final state of a channel after it has been
2890
// confirmed.
2891
type confirmedChannel struct {
2892
        // shortChanID expresses where in the block the funding transaction was
2893
        // located.
2894
        shortChanID lnwire.ShortChannelID
2895

2896
        // fundingTx is the funding transaction that created the channel.
2897
        fundingTx *wire.MsgTx
2898
}
2899

2900
// fundingTimeout is called when callers of waitForFundingWithTimeout receive
2901
// an ErrConfirmationTimeout. It is used to clean-up channel state and mark the
2902
// channel as closed. The error is only returned for the responder of the
2903
// channel flow.
2904
func (f *Manager) fundingTimeout(c *channeldb.OpenChannel,
2905
        pendingID PendingChanID) error {
2✔
2906

2✔
2907
        // We'll get a timeout if the number of blocks mined since the channel
2✔
2908
        // was initiated reaches MaxWaitNumBlocksFundingConf and we are not the
2✔
2909
        // channel initiator.
2✔
2910
        localBalance := c.LocalCommitment.LocalBalance.ToSatoshis()
2✔
2911
        closeInfo := &channeldb.ChannelCloseSummary{
2✔
2912
                ChainHash:               c.ChainHash,
2✔
2913
                ChanPoint:               c.FundingOutpoint,
2✔
2914
                RemotePub:               c.IdentityPub,
2✔
2915
                Capacity:                c.Capacity,
2✔
2916
                SettledBalance:          localBalance,
2✔
2917
                CloseType:               channeldb.FundingCanceled,
2✔
2918
                RemoteCurrentRevocation: c.RemoteCurrentRevocation,
2✔
2919
                RemoteNextRevocation:    c.RemoteNextRevocation,
2✔
2920
                LocalChanConfig:         c.LocalChanCfg,
2✔
2921
        }
2✔
2922

2✔
2923
        // Close the channel with us as the initiator because we are timing the
2✔
2924
        // channel out.
2✔
2925
        if err := c.CloseChannel(
2✔
2926
                closeInfo, channeldb.ChanStatusLocalCloseInitiator,
2✔
2927
        ); err != nil {
2✔
2928
                return fmt.Errorf("failed closing channel %v: %w",
×
2929
                        c.FundingOutpoint, err)
×
2930
        }
×
2931

2932
        timeoutErr := fmt.Errorf("timeout waiting for funding tx (%v) to "+
2✔
2933
                "confirm", c.FundingOutpoint)
2✔
2934

2✔
2935
        // When the peer comes online, we'll notify it that we are now
2✔
2936
        // considering the channel flow canceled.
2✔
2937
        f.wg.Add(1)
2✔
2938
        go func() {
4✔
2939
                defer f.wg.Done()
2✔
2940

2✔
2941
                peer, err := f.waitForPeerOnline(c.IdentityPub)
2✔
2942
                switch err {
2✔
2943
                // We're already shutting down, so we can just return.
2944
                case ErrFundingManagerShuttingDown:
×
2945
                        return
×
2946

2947
                // nil error means we continue on.
2948
                case nil:
2✔
2949

2950
                // For unexpected errors, we print the error and still try to
2951
                // fail the funding flow.
2952
                default:
×
2953
                        log.Errorf("Unexpected error while waiting for peer "+
×
2954
                                "to come online: %v", err)
×
2955
                }
2956

2957
                // Create channel identifier and set the channel ID.
2958
                cid := newChanIdentifier(pendingID)
2✔
2959
                cid.setChanID(lnwire.NewChanIDFromOutPoint(c.FundingOutpoint))
2✔
2960

2✔
2961
                // TODO(halseth): should this send be made
2✔
2962
                // reliable?
2✔
2963

2✔
2964
                // The reservation won't exist at this point, but we'll send an
2✔
2965
                // Error message over anyways with ChanID set to pendingID.
2✔
2966
                f.failFundingFlow(peer, cid, timeoutErr)
2✔
2967
        }()
2968

2969
        return timeoutErr
2✔
2970
}
2971

2972
// waitForFundingWithTimeout is a wrapper around waitForFundingConfirmation and
2973
// waitForTimeout that will return ErrConfirmationTimeout if we are not the
2974
// channel initiator and the MaxWaitNumBlocksFundingConf has passed from the
2975
// funding broadcast height. In case of confirmation, the short channel ID of
2976
// the channel and the funding transaction will be returned.
2977
func (f *Manager) waitForFundingWithTimeout(
2978
        ch *channeldb.OpenChannel) (*confirmedChannel, error) {
57✔
2979

57✔
2980
        confChan := make(chan *confirmedChannel)
57✔
2981
        timeoutChan := make(chan error, 1)
57✔
2982
        cancelChan := make(chan struct{})
57✔
2983

57✔
2984
        f.wg.Add(1)
57✔
2985
        go f.waitForFundingConfirmation(ch, cancelChan, confChan)
57✔
2986

57✔
2987
        // If we are not the initiator, we have no money at stake and will
57✔
2988
        // timeout waiting for the funding transaction to confirm after a
57✔
2989
        // while.
57✔
2990
        if !ch.IsInitiator && !ch.IsZeroConf() {
82✔
2991
                f.wg.Add(1)
25✔
2992
                go f.waitForTimeout(ch, cancelChan, timeoutChan)
25✔
2993
        }
25✔
2994
        defer close(cancelChan)
57✔
2995

57✔
2996
        select {
57✔
2997
        case err := <-timeoutChan:
2✔
2998
                if err != nil {
2✔
2999
                        return nil, err
×
3000
                }
×
3001
                return nil, ErrConfirmationTimeout
2✔
3002

3003
        case <-f.quit:
21✔
3004
                // The fundingManager is shutting down, and will resume wait on
21✔
3005
                // startup.
21✔
3006
                return nil, ErrFundingManagerShuttingDown
21✔
3007

3008
        case confirmedChannel, ok := <-confChan:
34✔
3009
                if !ok {
34✔
3010
                        return nil, fmt.Errorf("waiting for funding" +
×
3011
                                "confirmation failed")
×
3012
                }
×
3013
                return confirmedChannel, nil
34✔
3014
        }
3015
}
3016

3017
// makeFundingScript re-creates the funding script for the funding transaction
3018
// of the target channel.
3019
func makeFundingScript(channel *channeldb.OpenChannel) ([]byte, error) {
77✔
3020
        localKey := channel.LocalChanCfg.MultiSigKey.PubKey
77✔
3021
        remoteKey := channel.RemoteChanCfg.MultiSigKey.PubKey
77✔
3022

77✔
3023
        if channel.ChanType.IsTaproot() {
82✔
3024
                pkScript, _, err := input.GenTaprootFundingScript(
5✔
3025
                        localKey, remoteKey, int64(channel.Capacity),
5✔
3026
                        channel.TapscriptRoot,
5✔
3027
                )
5✔
3028
                if err != nil {
5✔
3029
                        return nil, err
×
3030
                }
×
3031

3032
                return pkScript, nil
5✔
3033
        }
3034

3035
        multiSigScript, err := input.GenMultiSigScript(
72✔
3036
                localKey.SerializeCompressed(),
72✔
3037
                remoteKey.SerializeCompressed(),
72✔
3038
        )
72✔
3039
        if err != nil {
72✔
3040
                return nil, err
×
3041
        }
×
3042

3043
        return input.WitnessScriptHash(multiSigScript)
72✔
3044
}
3045

3046
// waitForFundingConfirmation handles the final stages of the channel funding
3047
// process once the funding transaction has been broadcast. The primary
3048
// function of waitForFundingConfirmation is to wait for blockchain
3049
// confirmation, and then to notify the other systems that must be notified
3050
// when a channel has become active for lightning transactions.
3051
// The wait can be canceled by closing the cancelChan. In case of success,
3052
// a *lnwire.ShortChannelID will be passed to confChan.
3053
//
3054
// NOTE: This MUST be run as a goroutine.
3055
func (f *Manager) waitForFundingConfirmation(
3056
        completeChan *channeldb.OpenChannel, cancelChan <-chan struct{},
3057
        confChan chan<- *confirmedChannel) {
57✔
3058

57✔
3059
        defer f.wg.Done()
57✔
3060
        defer close(confChan)
57✔
3061

57✔
3062
        // Register with the ChainNotifier for a notification once the funding
57✔
3063
        // transaction reaches `numConfs` confirmations.
57✔
3064
        txid := completeChan.FundingOutpoint.Hash
57✔
3065
        fundingScript, err := makeFundingScript(completeChan)
57✔
3066
        if err != nil {
57✔
3067
                log.Errorf("unable to create funding script for "+
×
3068
                        "ChannelPoint(%v): %v", completeChan.FundingOutpoint,
×
3069
                        err)
×
3070
                return
×
3071
        }
×
3072
        numConfs := uint32(completeChan.NumConfsRequired)
57✔
3073

57✔
3074
        // If the underlying channel is a zero-conf channel, we'll set numConfs
57✔
3075
        // to 6, since it will be zero here.
57✔
3076
        if completeChan.IsZeroConf() {
63✔
3077
                numConfs = 6
6✔
3078
        }
6✔
3079

3080
        confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
57✔
3081
                &txid, fundingScript, numConfs,
57✔
3082
                completeChan.BroadcastHeight(),
57✔
3083
        )
57✔
3084
        if err != nil {
57✔
3085
                log.Errorf("Unable to register for confirmation of "+
×
3086
                        "ChannelPoint(%v): %v", completeChan.FundingOutpoint,
×
3087
                        err)
×
3088
                return
×
3089
        }
×
3090

3091
        log.Infof("Waiting for funding tx (%v) to reach %v confirmations",
57✔
3092
                txid, numConfs)
57✔
3093

57✔
3094
        var confDetails *chainntnfs.TxConfirmation
57✔
3095
        var ok bool
57✔
3096

57✔
3097
        // Wait until the specified number of confirmations has been reached,
57✔
3098
        // we get a cancel signal, or the wallet signals a shutdown.
57✔
3099
        select {
57✔
3100
        case confDetails, ok = <-confNtfn.Confirmed:
34✔
3101
                // fallthrough
3102

3103
        case <-cancelChan:
4✔
3104
                log.Warnf("canceled waiting for funding confirmation, "+
4✔
3105
                        "stopping funding flow for ChannelPoint(%v)",
4✔
3106
                        completeChan.FundingOutpoint)
4✔
3107
                return
4✔
3108

3109
        case <-f.quit:
19✔
3110
                log.Warnf("fundingManager shutting down, stopping funding "+
19✔
3111
                        "flow for ChannelPoint(%v)",
19✔
3112
                        completeChan.FundingOutpoint)
19✔
3113
                return
19✔
3114
        }
3115

3116
        if !ok {
34✔
3117
                log.Warnf("ChainNotifier shutting down, cannot complete "+
×
3118
                        "funding flow for ChannelPoint(%v)",
×
3119
                        completeChan.FundingOutpoint)
×
3120
                return
×
3121
        }
×
3122

3123
        fundingPoint := completeChan.FundingOutpoint
34✔
3124
        log.Infof("ChannelPoint(%v) is now active: ChannelID(%v)",
34✔
3125
                fundingPoint, lnwire.NewChanIDFromOutPoint(fundingPoint))
34✔
3126

34✔
3127
        // With the block height and the transaction index known, we can
34✔
3128
        // construct the compact chanID which is used on the network to unique
34✔
3129
        // identify channels.
34✔
3130
        shortChanID := lnwire.ShortChannelID{
34✔
3131
                BlockHeight: confDetails.BlockHeight,
34✔
3132
                TxIndex:     confDetails.TxIndex,
34✔
3133
                TxPosition:  uint16(fundingPoint.Index),
34✔
3134
        }
34✔
3135

34✔
3136
        select {
34✔
3137
        case confChan <- &confirmedChannel{
3138
                shortChanID: shortChanID,
3139
                fundingTx:   confDetails.Tx,
3140
        }:
34✔
3141
        case <-f.quit:
×
3142
                return
×
3143
        }
3144
}
3145

3146
// waitForTimeout will close the timeout channel if MaxWaitNumBlocksFundingConf
3147
// has passed from the broadcast height of the given channel. In case of error,
3148
// the error is sent on timeoutChan. The wait can be canceled by closing the
3149
// cancelChan.
3150
//
3151
// NOTE: timeoutChan MUST be buffered.
3152
// NOTE: This MUST be run as a goroutine.
3153
func (f *Manager) waitForTimeout(completeChan *channeldb.OpenChannel,
3154
        cancelChan <-chan struct{}, timeoutChan chan<- error) {
25✔
3155

25✔
3156
        defer f.wg.Done()
25✔
3157

25✔
3158
        epochClient, err := f.cfg.Notifier.RegisterBlockEpochNtfn(nil)
25✔
3159
        if err != nil {
25✔
3160
                timeoutChan <- fmt.Errorf("unable to register for epoch "+
×
3161
                        "notification: %v", err)
×
3162
                return
×
3163
        }
×
3164

3165
        defer epochClient.Cancel()
25✔
3166

25✔
3167
        // On block maxHeight we will cancel the funding confirmation wait.
25✔
3168
        broadcastHeight := completeChan.BroadcastHeight()
25✔
3169
        maxHeight := broadcastHeight + MaxWaitNumBlocksFundingConf
25✔
3170
        for {
52✔
3171
                select {
27✔
3172
                case epoch, ok := <-epochClient.Epochs:
4✔
3173
                        if !ok {
4✔
3174
                                timeoutChan <- fmt.Errorf("epoch client " +
×
3175
                                        "shutting down")
×
3176
                                return
×
3177
                        }
×
3178

3179
                        // Close the timeout channel and exit if the block is
3180
                        // above the max height.
3181
                        if uint32(epoch.Height) >= maxHeight {
6✔
3182
                                log.Warnf("Waited for %v blocks without "+
2✔
3183
                                        "seeing funding transaction confirmed,"+
2✔
3184
                                        " cancelling.",
2✔
3185
                                        MaxWaitNumBlocksFundingConf)
2✔
3186

2✔
3187
                                // Notify the caller of the timeout.
2✔
3188
                                close(timeoutChan)
2✔
3189
                                return
2✔
3190
                        }
2✔
3191

3192
                        // TODO: If we are the channel initiator implement
3193
                        // a method for recovering the funds from the funding
3194
                        // transaction
3195

3196
                case <-cancelChan:
15✔
3197
                        return
15✔
3198

3199
                case <-f.quit:
8✔
3200
                        // The fundingManager is shutting down, will resume
8✔
3201
                        // waiting for the funding transaction on startup.
8✔
3202
                        return
8✔
3203
                }
3204
        }
3205
}
3206

3207
// makeLabelForTx updates the label for the confirmed funding transaction. If
3208
// we opened the channel, and lnd's wallet published our funding tx (which is
3209
// not the case for some channels) then we update our transaction label with
3210
// our short channel ID, which is known now that our funding transaction has
3211
// confirmed. We do not label transactions we did not publish, because our
3212
// wallet has no knowledge of them.
3213
func (f *Manager) makeLabelForTx(c *channeldb.OpenChannel) {
34✔
3214
        if c.IsInitiator && c.ChanType.HasFundingTx() {
50✔
3215
                shortChanID := c.ShortChanID()
16✔
3216

16✔
3217
                // For zero-conf channels, we'll use the actually-confirmed
16✔
3218
                // short channel id.
16✔
3219
                if c.IsZeroConf() {
18✔
3220
                        shortChanID = c.ZeroConfRealScid()
2✔
3221
                }
2✔
3222

3223
                label := labels.MakeLabel(
16✔
3224
                        labels.LabelTypeChannelOpen, &shortChanID,
16✔
3225
                )
16✔
3226

16✔
3227
                err := f.cfg.UpdateLabel(c.FundingOutpoint.Hash, label)
16✔
3228
                if err != nil {
16✔
3229
                        log.Errorf("unable to update label: %v", err)
×
3230
                }
×
3231
        }
3232
}
3233

3234
// handleFundingConfirmation marks a channel as open in the database, and set
3235
// the channelOpeningState markedOpen. In addition it will report the now
3236
// decided short channel ID to the switch, and close the local discovery signal
3237
// for this channel.
3238
func (f *Manager) handleFundingConfirmation(
3239
        completeChan *channeldb.OpenChannel,
3240
        confChannel *confirmedChannel) error {
30✔
3241

30✔
3242
        fundingPoint := completeChan.FundingOutpoint
30✔
3243
        chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
30✔
3244

30✔
3245
        // TODO(roasbeef): ideally persistent state update for chan above
30✔
3246
        // should be abstracted
30✔
3247

30✔
3248
        // Now that that the channel has been fully confirmed, we'll request
30✔
3249
        // that the wallet fully verify this channel to ensure that it can be
30✔
3250
        // used.
30✔
3251
        err := f.cfg.Wallet.ValidateChannel(completeChan, confChannel.fundingTx)
30✔
3252
        if err != nil {
30✔
3253
                // TODO(roasbeef): delete chan state?
×
3254
                return fmt.Errorf("unable to validate channel: %w", err)
×
3255
        }
×
3256

3257
        // Now that the channel has been validated, we'll persist an alias for
3258
        // this channel if the option-scid-alias feature-bit was negotiated.
3259
        if completeChan.NegotiatedAliasFeature() {
32✔
3260
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
2✔
3261
                if err != nil {
2✔
3262
                        return fmt.Errorf("unable to request alias: %w", err)
×
3263
                }
×
3264

3265
                err = f.cfg.AliasManager.AddLocalAlias(
2✔
3266
                        aliasScid, confChannel.shortChanID, true, false,
2✔
3267
                )
2✔
3268
                if err != nil {
2✔
3269
                        return fmt.Errorf("unable to request alias: %w", err)
×
3270
                }
×
3271
        }
3272

3273
        // The funding transaction now being confirmed, we add this channel to
3274
        // the fundingManager's internal persistent state machine that we use
3275
        // to track the remaining process of the channel opening. This is
3276
        // useful to resume the opening process in case of restarts. We set the
3277
        // opening state before we mark the channel opened in the database,
3278
        // such that we can receover from one of the db writes failing.
3279
        err = f.saveChannelOpeningState(
30✔
3280
                &fundingPoint, markedOpen, &confChannel.shortChanID,
30✔
3281
        )
30✔
3282
        if err != nil {
30✔
3283
                return fmt.Errorf("error setting channel state to "+
×
3284
                        "markedOpen: %v", err)
×
3285
        }
×
3286

3287
        // Now that the channel has been fully confirmed and we successfully
3288
        // saved the opening state, we'll mark it as open within the database.
3289
        err = completeChan.MarkAsOpen(confChannel.shortChanID)
30✔
3290
        if err != nil {
30✔
3291
                return fmt.Errorf("error setting channel pending flag to "+
×
3292
                        "false:        %v", err)
×
3293
        }
×
3294

3295
        // Update the confirmed funding transaction label.
3296
        f.makeLabelForTx(completeChan)
30✔
3297

30✔
3298
        // Inform the ChannelNotifier that the channel has transitioned from
30✔
3299
        // pending open to open.
30✔
3300
        f.cfg.NotifyOpenChannelEvent(completeChan.FundingOutpoint)
30✔
3301

30✔
3302
        // Close the discoverySignal channel, indicating to a separate
30✔
3303
        // goroutine that the channel now is marked as open in the database
30✔
3304
        // and that it is acceptable to process channel_ready messages
30✔
3305
        // from the peer.
30✔
3306
        if discoverySignal, ok := f.localDiscoverySignals.Load(chanID); ok {
60✔
3307
                close(discoverySignal)
30✔
3308
        }
30✔
3309

3310
        return nil
30✔
3311
}
3312

3313
// sendChannelReady creates and sends the channelReady message.
3314
// This should be called after the funding transaction has been confirmed,
3315
// and the channelState is 'markedOpen'.
3316
func (f *Manager) sendChannelReady(completeChan *channeldb.OpenChannel,
3317
        channel *lnwallet.LightningChannel) error {
35✔
3318

35✔
3319
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
35✔
3320

35✔
3321
        var peerKey [33]byte
35✔
3322
        copy(peerKey[:], completeChan.IdentityPub.SerializeCompressed())
35✔
3323

35✔
3324
        // Next, we'll send over the channel_ready message which marks that we
35✔
3325
        // consider the channel open by presenting the remote party with our
35✔
3326
        // next revocation key. Without the revocation key, the remote party
35✔
3327
        // will be unable to propose state transitions.
35✔
3328
        nextRevocation, err := channel.NextRevocationKey()
35✔
3329
        if err != nil {
35✔
3330
                return fmt.Errorf("unable to create next revocation: %w", err)
×
3331
        }
×
3332
        channelReadyMsg := lnwire.NewChannelReady(chanID, nextRevocation)
35✔
3333

35✔
3334
        // If this is a taproot channel, then we also need to send along our
35✔
3335
        // set of musig2 nonces as well.
35✔
3336
        if completeChan.ChanType.IsTaproot() {
39✔
3337
                log.Infof("ChanID(%v): generating musig2 nonces...",
4✔
3338
                        chanID)
4✔
3339

4✔
3340
                f.nonceMtx.Lock()
4✔
3341
                localNonce, ok := f.pendingMusigNonces[chanID]
4✔
3342
                if !ok {
8✔
3343
                        // If we don't have any nonces generated yet for this
4✔
3344
                        // first state, then we'll generate them now and stow
4✔
3345
                        // them away.  When we receive the funding locked
4✔
3346
                        // message, we'll then pass along this same set of
4✔
3347
                        // nonces.
4✔
3348
                        newNonce, err := channel.GenMusigNonces()
4✔
3349
                        if err != nil {
4✔
3350
                                f.nonceMtx.Unlock()
×
3351
                                return err
×
3352
                        }
×
3353

3354
                        // Now that we've generated the nonce for this channel,
3355
                        // we'll store it in the set of pending nonces.
3356
                        localNonce = newNonce
4✔
3357
                        f.pendingMusigNonces[chanID] = localNonce
4✔
3358
                }
3359
                f.nonceMtx.Unlock()
4✔
3360

4✔
3361
                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce(
4✔
3362
                        localNonce.PubNonce,
4✔
3363
                )
4✔
3364
        }
3365

3366
        // If the channel negotiated the option-scid-alias feature bit, we'll
3367
        // send a TLV segment that includes an alias the peer can use in their
3368
        // invoice hop hints. We'll send the first alias we find for the
3369
        // channel since it does not matter which alias we send. We'll error
3370
        // out in the odd case that no aliases are found.
3371
        if completeChan.NegotiatedAliasFeature() {
41✔
3372
                aliases := f.cfg.AliasManager.GetAliases(
6✔
3373
                        completeChan.ShortChanID(),
6✔
3374
                )
6✔
3375
                if len(aliases) == 0 {
6✔
3376
                        return fmt.Errorf("no aliases found")
×
3377
                }
×
3378

3379
                // We can use a pointer to aliases since GetAliases returns a
3380
                // copy of the alias slice.
3381
                channelReadyMsg.AliasScid = &aliases[0]
6✔
3382
        }
3383

3384
        // If the peer has disconnected before we reach this point, we will need
3385
        // to wait for him to come back online before sending the channelReady
3386
        // message. This is special for channelReady, since failing to send any
3387
        // of the previous messages in the funding flow just cancels the flow.
3388
        // But now the funding transaction is confirmed, the channel is open
3389
        // and we have to make sure the peer gets the channelReady message when
3390
        // it comes back online. This is also crucial during restart of lnd,
3391
        // where we might try to resend the channelReady message before the
3392
        // server has had the time to connect to the peer. We keep trying to
3393
        // send channelReady until we succeed, or the fundingManager is shut
3394
        // down.
3395
        for {
70✔
3396
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
35✔
3397
                if err != nil {
36✔
3398
                        return err
1✔
3399
                }
1✔
3400

3401
                localAlias := peer.LocalFeatures().HasFeature(
34✔
3402
                        lnwire.ScidAliasOptional,
34✔
3403
                )
34✔
3404
                remoteAlias := peer.RemoteFeatures().HasFeature(
34✔
3405
                        lnwire.ScidAliasOptional,
34✔
3406
                )
34✔
3407

34✔
3408
                // We could also refresh the channel state instead of checking
34✔
3409
                // whether the feature was negotiated, but this saves us a
34✔
3410
                // database read.
34✔
3411
                if channelReadyMsg.AliasScid == nil && localAlias &&
34✔
3412
                        remoteAlias {
34✔
3413

×
3414
                        // If an alias was not assigned above and the scid
×
3415
                        // alias feature was negotiated, check if we already
×
3416
                        // have an alias stored in case handleChannelReady was
×
3417
                        // called before this. If an alias exists, use that in
×
3418
                        // channel_ready. Otherwise, request and store an
×
3419
                        // alias and use that.
×
3420
                        aliases := f.cfg.AliasManager.GetAliases(
×
3421
                                completeChan.ShortChannelID,
×
3422
                        )
×
3423
                        if len(aliases) == 0 {
×
3424
                                // No aliases were found.
×
3425
                                alias, err := f.cfg.AliasManager.RequestAlias()
×
3426
                                if err != nil {
×
3427
                                        return err
×
3428
                                }
×
3429

3430
                                err = f.cfg.AliasManager.AddLocalAlias(
×
3431
                                        alias, completeChan.ShortChannelID,
×
3432
                                        false, false,
×
3433
                                )
×
3434
                                if err != nil {
×
3435
                                        return err
×
3436
                                }
×
3437

3438
                                channelReadyMsg.AliasScid = &alias
×
3439
                        } else {
×
3440
                                channelReadyMsg.AliasScid = &aliases[0]
×
3441
                        }
×
3442
                }
3443

3444
                log.Infof("Peer(%x) is online, sending ChannelReady "+
34✔
3445
                        "for ChannelID(%v)", peerKey, chanID)
34✔
3446

34✔
3447
                if err := peer.SendMessage(true, channelReadyMsg); err == nil {
68✔
3448
                        // Sending succeeded, we can break out and continue the
34✔
3449
                        // funding flow.
34✔
3450
                        break
34✔
3451
                }
3452

3453
                log.Warnf("Unable to send channelReady to peer %x: %v. "+
×
3454
                        "Will retry when online", peerKey, err)
×
3455
        }
3456

3457
        return nil
34✔
3458
}
3459

3460
// receivedChannelReady checks whether or not we've received a ChannelReady
3461
// from the remote peer. If we have, RemoteNextRevocation will be set.
3462
func (f *Manager) receivedChannelReady(node *btcec.PublicKey,
3463
        chanID lnwire.ChannelID) (bool, error) {
60✔
3464

60✔
3465
        // If the funding manager has exited, return an error to stop looping.
60✔
3466
        // Note that the peer may appear as online while the funding manager
60✔
3467
        // has stopped due to the shutdown order in the server.
60✔
3468
        select {
60✔
3469
        case <-f.quit:
1✔
3470
                return false, ErrFundingManagerShuttingDown
1✔
3471
        default:
59✔
3472
        }
3473

3474
        // Avoid a tight loop if peer is offline.
3475
        if _, err := f.waitForPeerOnline(node); err != nil {
59✔
3476
                log.Errorf("Wait for peer online failed: %v", err)
×
3477
                return false, err
×
3478
        }
×
3479

3480
        // If we cannot find the channel, then we haven't processed the
3481
        // remote's channelReady message.
3482
        channel, err := f.cfg.FindChannel(node, chanID)
59✔
3483
        if err != nil {
59✔
3484
                log.Errorf("Unable to locate ChannelID(%v) to determine if "+
×
3485
                        "ChannelReady was received", chanID)
×
3486
                return false, err
×
3487
        }
×
3488

3489
        // If we haven't insert the next revocation point, we haven't finished
3490
        // processing the channel ready message.
3491
        if channel.RemoteNextRevocation == nil {
94✔
3492
                return false, nil
35✔
3493
        }
35✔
3494

3495
        // Finally, the barrier signal is removed once we finish
3496
        // `handleChannelReady`. If we can still find the signal, we haven't
3497
        // finished processing it yet.
3498
        _, loaded := f.handleChannelReadyBarriers.Load(chanID)
24✔
3499

24✔
3500
        return !loaded, nil
24✔
3501
}
3502

3503
// extractAnnounceParams extracts the various channel announcement and update
3504
// parameters that will be needed to construct a ChannelAnnouncement and a
3505
// ChannelUpdate.
3506
func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) (
3507
        lnwire.MilliSatoshi, lnwire.MilliSatoshi) {
26✔
3508

26✔
3509
        // We'll obtain the min HTLC value we can forward in our direction, as
26✔
3510
        // we'll use this value within our ChannelUpdate. This constraint is
26✔
3511
        // originally set by the remote node, as it will be the one that will
26✔
3512
        // need to determine the smallest HTLC it deems economically relevant.
26✔
3513
        fwdMinHTLC := c.LocalChanCfg.MinHTLC
26✔
3514

26✔
3515
        // We don't necessarily want to go as low as the remote party allows.
26✔
3516
        // Check it against our default forwarding policy.
26✔
3517
        if fwdMinHTLC < f.cfg.DefaultRoutingPolicy.MinHTLCOut {
26✔
UNCOV
3518
                fwdMinHTLC = f.cfg.DefaultRoutingPolicy.MinHTLCOut
×
UNCOV
3519
        }
×
3520

3521
        // We'll obtain the max HTLC value we can forward in our direction, as
3522
        // we'll use this value within our ChannelUpdate. This value must be <=
3523
        // channel capacity and <= the maximum in-flight msats set by the peer.
3524
        fwdMaxHTLC := c.LocalChanCfg.MaxPendingAmount
26✔
3525
        capacityMSat := lnwire.NewMSatFromSatoshis(c.Capacity)
26✔
3526
        if fwdMaxHTLC > capacityMSat {
26✔
3527
                fwdMaxHTLC = capacityMSat
×
3528
        }
×
3529

3530
        return fwdMinHTLC, fwdMaxHTLC
26✔
3531
}
3532

3533
// addToGraph sends a ChannelAnnouncement and a ChannelUpdate to the
3534
// gossiper so that the channel is added to the graph builder's internal graph.
3535
// These announcement messages are NOT broadcasted to the greater network,
3536
// only to the channel counter party. The proofs required to announce the
3537
// channel to the greater network will be created and sent in annAfterSixConfs.
3538
// The peerAlias is used for zero-conf channels to give the counter-party a
3539
// ChannelUpdate they understand. ourPolicy may be set for various
3540
// option-scid-alias channels to re-use the same policy.
3541
func (f *Manager) addToGraph(completeChan *channeldb.OpenChannel,
3542
        shortChanID *lnwire.ShortChannelID,
3543
        peerAlias *lnwire.ShortChannelID,
3544
        ourPolicy *models.ChannelEdgePolicy) error {
26✔
3545

26✔
3546
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
26✔
3547

26✔
3548
        fwdMinHTLC, fwdMaxHTLC := f.extractAnnounceParams(completeChan)
26✔
3549

26✔
3550
        ann, err := f.newChanAnnouncement(
26✔
3551
                f.cfg.IDKey, completeChan.IdentityPub,
26✔
3552
                &completeChan.LocalChanCfg.MultiSigKey,
26✔
3553
                completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
26✔
3554
                chanID, fwdMinHTLC, fwdMaxHTLC, ourPolicy,
26✔
3555
                completeChan.ChanType,
26✔
3556
        )
26✔
3557
        if err != nil {
26✔
3558
                return fmt.Errorf("error generating channel "+
×
3559
                        "announcement: %v", err)
×
3560
        }
×
3561

3562
        // Send ChannelAnnouncement and ChannelUpdate to the gossiper to add
3563
        // to the Router's topology.
3564
        errChan := f.cfg.SendAnnouncement(
26✔
3565
                ann.chanAnn, discovery.ChannelCapacity(completeChan.Capacity),
26✔
3566
                discovery.ChannelPoint(completeChan.FundingOutpoint),
26✔
3567
                discovery.TapscriptRoot(completeChan.TapscriptRoot),
26✔
3568
        )
26✔
3569
        select {
26✔
3570
        case err := <-errChan:
26✔
3571
                if err != nil {
26✔
3572
                        if graph.IsError(err, graph.ErrOutdated,
×
3573
                                graph.ErrIgnored) {
×
3574

×
3575
                                log.Debugf("Graph rejected "+
×
3576
                                        "ChannelAnnouncement: %v", err)
×
3577
                        } else {
×
3578
                                return fmt.Errorf("error sending channel "+
×
3579
                                        "announcement: %v", err)
×
3580
                        }
×
3581
                }
3582
        case <-f.quit:
×
3583
                return ErrFundingManagerShuttingDown
×
3584
        }
3585

3586
        errChan = f.cfg.SendAnnouncement(
26✔
3587
                ann.chanUpdateAnn, discovery.RemoteAlias(peerAlias),
26✔
3588
        )
26✔
3589
        select {
26✔
3590
        case err := <-errChan:
26✔
3591
                if err != nil {
26✔
3592
                        if graph.IsError(err, graph.ErrOutdated,
×
3593
                                graph.ErrIgnored) {
×
3594

×
3595
                                log.Debugf("Graph rejected "+
×
3596
                                        "ChannelUpdate: %v", err)
×
3597
                        } else {
×
3598
                                return fmt.Errorf("error sending channel "+
×
3599
                                        "update: %v", err)
×
3600
                        }
×
3601
                }
3602
        case <-f.quit:
×
3603
                return ErrFundingManagerShuttingDown
×
3604
        }
3605

3606
        return nil
26✔
3607
}
3608

3609
// annAfterSixConfs broadcasts the necessary channel announcement messages to
3610
// the network after 6 confs. Should be called after the channelReady message
3611
// is sent and the channel is added to the graph (channelState is
3612
// 'addedToGraph') and the channel is ready to be used. This is the last
3613
// step in the channel opening process, and the opening state will be deleted
3614
// from the database if successful.
3615
func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
3616
        shortChanID *lnwire.ShortChannelID) error {
26✔
3617

26✔
3618
        // If this channel is not meant to be announced to the greater network,
26✔
3619
        // we'll only send our NodeAnnouncement to our counterparty to ensure we
26✔
3620
        // don't leak any of our information.
26✔
3621
        announceChan := completeChan.ChannelFlags&lnwire.FFAnnounceChannel != 0
26✔
3622
        if !announceChan {
34✔
3623
                log.Debugf("Will not announce private channel %v.",
8✔
3624
                        shortChanID.ToUint64())
8✔
3625

8✔
3626
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
8✔
3627
                if err != nil {
8✔
3628
                        return err
×
3629
                }
×
3630

3631
                nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
8✔
3632
                if err != nil {
8✔
3633
                        return fmt.Errorf("unable to retrieve current node "+
×
3634
                                "announcement: %v", err)
×
3635
                }
×
3636

3637
                chanID := lnwire.NewChanIDFromOutPoint(
8✔
3638
                        completeChan.FundingOutpoint,
8✔
3639
                )
8✔
3640
                pubKey := peer.PubKey()
8✔
3641
                log.Debugf("Sending our NodeAnnouncement for "+
8✔
3642
                        "ChannelID(%v) to %x", chanID, pubKey)
8✔
3643

8✔
3644
                // TODO(halseth): make reliable. If the peer is not online this
8✔
3645
                // will fail, and the opening process will stop. Should instead
8✔
3646
                // block here, waiting for the peer to come online.
8✔
3647
                if err := peer.SendMessage(true, &nodeAnn); err != nil {
8✔
3648
                        return fmt.Errorf("unable to send node announcement "+
×
3649
                                "to peer %x: %v", pubKey, err)
×
3650
                }
×
3651
        } else {
18✔
3652
                // Otherwise, we'll wait until the funding transaction has
18✔
3653
                // reached 6 confirmations before announcing it.
18✔
3654
                numConfs := uint32(completeChan.NumConfsRequired)
18✔
3655
                if numConfs < 6 {
36✔
3656
                        numConfs = 6
18✔
3657
                }
18✔
3658
                txid := completeChan.FundingOutpoint.Hash
18✔
3659
                log.Debugf("Will announce channel %v after ChannelPoint"+
18✔
3660
                        "(%v) has gotten %d confirmations",
18✔
3661
                        shortChanID.ToUint64(), completeChan.FundingOutpoint,
18✔
3662
                        numConfs)
18✔
3663

18✔
3664
                fundingScript, err := makeFundingScript(completeChan)
18✔
3665
                if err != nil {
18✔
3666
                        return fmt.Errorf("unable to create funding script "+
×
3667
                                "for ChannelPoint(%v): %v",
×
3668
                                completeChan.FundingOutpoint, err)
×
3669
                }
×
3670

3671
                // Register with the ChainNotifier for a notification once the
3672
                // funding transaction reaches at least 6 confirmations.
3673
                confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
18✔
3674
                        &txid, fundingScript, numConfs,
18✔
3675
                        completeChan.BroadcastHeight(),
18✔
3676
                )
18✔
3677
                if err != nil {
18✔
3678
                        return fmt.Errorf("unable to register for "+
×
3679
                                "confirmation of ChannelPoint(%v): %v",
×
3680
                                completeChan.FundingOutpoint, err)
×
3681
                }
×
3682

3683
                // Wait until 6 confirmations has been reached or the wallet
3684
                // signals a shutdown.
3685
                select {
18✔
3686
                case _, ok := <-confNtfn.Confirmed:
16✔
3687
                        if !ok {
16✔
3688
                                return fmt.Errorf("ChainNotifier shutting "+
×
3689
                                        "down, cannot complete funding flow "+
×
3690
                                        "for ChannelPoint(%v)",
×
3691
                                        completeChan.FundingOutpoint)
×
3692
                        }
×
3693
                        // Fallthrough.
3694

3695
                case <-f.quit:
2✔
3696
                        return fmt.Errorf("%v, stopping funding flow for "+
2✔
3697
                                "ChannelPoint(%v)",
2✔
3698
                                ErrFundingManagerShuttingDown,
2✔
3699
                                completeChan.FundingOutpoint)
2✔
3700
                }
3701

3702
                fundingPoint := completeChan.FundingOutpoint
16✔
3703
                chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
16✔
3704

16✔
3705
                log.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
16✔
3706
                        &fundingPoint, shortChanID)
16✔
3707

16✔
3708
                // If this is a non-zero-conf option-scid-alias channel, we'll
16✔
3709
                // delete the mappings the gossiper uses so that ChannelUpdates
16✔
3710
                // with aliases won't be accepted. This is done elsewhere for
16✔
3711
                // zero-conf channels.
16✔
3712
                isScidFeature := completeChan.NegotiatedAliasFeature()
16✔
3713
                isZeroConf := completeChan.IsZeroConf()
16✔
3714
                if isScidFeature && !isZeroConf {
16✔
UNCOV
3715
                        baseScid := completeChan.ShortChanID()
×
UNCOV
3716
                        err := f.cfg.AliasManager.DeleteSixConfs(baseScid)
×
UNCOV
3717
                        if err != nil {
×
3718
                                return fmt.Errorf("failed deleting six confs "+
×
3719
                                        "maps: %v", err)
×
3720
                        }
×
3721

3722
                        // We'll delete the edge and add it again via
3723
                        // addToGraph. This is because the peer may have
3724
                        // sent us a ChannelUpdate with an alias and we don't
3725
                        // want to relay this.
UNCOV
3726
                        ourPolicy, err := f.cfg.DeleteAliasEdge(baseScid)
×
UNCOV
3727
                        if err != nil {
×
3728
                                return fmt.Errorf("failed deleting real edge "+
×
3729
                                        "for alias channel from graph: %v",
×
3730
                                        err)
×
3731
                        }
×
3732

UNCOV
3733
                        err = f.addToGraph(
×
UNCOV
3734
                                completeChan, &baseScid, nil, ourPolicy,
×
UNCOV
3735
                        )
×
UNCOV
3736
                        if err != nil {
×
3737
                                return fmt.Errorf("failed to re-add to "+
×
3738
                                        "graph: %v", err)
×
3739
                        }
×
3740
                }
3741

3742
                // Create and broadcast the proofs required to make this channel
3743
                // public and usable for other nodes for routing.
3744
                err = f.announceChannel(
16✔
3745
                        f.cfg.IDKey, completeChan.IdentityPub,
16✔
3746
                        &completeChan.LocalChanCfg.MultiSigKey,
16✔
3747
                        completeChan.RemoteChanCfg.MultiSigKey.PubKey,
16✔
3748
                        *shortChanID, chanID, completeChan.ChanType,
16✔
3749
                )
16✔
3750
                if err != nil {
16✔
UNCOV
3751
                        return fmt.Errorf("channel announcement failed: %w",
×
UNCOV
3752
                                err)
×
UNCOV
3753
                }
×
3754

3755
                log.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
16✔
3756
                        "sent to gossiper", &fundingPoint, shortChanID)
16✔
3757
        }
3758

3759
        return nil
24✔
3760
}
3761

3762
// waitForZeroConfChannel is called when the state is addedToGraph with
3763
// a zero-conf channel. This will wait for the real confirmation, add the
3764
// confirmed SCID to the router graph, and then announce after six confs.
3765
func (f *Manager) waitForZeroConfChannel(c *channeldb.OpenChannel) error {
6✔
3766
        // First we'll check whether the channel is confirmed on-chain. If it
6✔
3767
        // is already confirmed, the chainntnfs subsystem will return with the
6✔
3768
        // confirmed tx. Otherwise, we'll wait here until confirmation occurs.
6✔
3769
        confChan, err := f.waitForFundingWithTimeout(c)
6✔
3770
        if err != nil {
8✔
3771
                return fmt.Errorf("error waiting for zero-conf funding "+
2✔
3772
                        "confirmation for ChannelPoint(%v): %v",
2✔
3773
                        c.FundingOutpoint, err)
2✔
3774
        }
2✔
3775

3776
        // We'll need to refresh the channel state so that things are properly
3777
        // populated when validating the channel state. Otherwise, a panic may
3778
        // occur due to inconsistency in the OpenChannel struct.
3779
        err = c.Refresh()
4✔
3780
        if err != nil {
4✔
UNCOV
3781
                return fmt.Errorf("unable to refresh channel state: %w", err)
×
UNCOV
3782
        }
×
3783

3784
        // Now that we have the confirmed transaction and the proper SCID,
3785
        // we'll call ValidateChannel to ensure the confirmed tx is properly
3786
        // formatted.
3787
        err = f.cfg.Wallet.ValidateChannel(c, confChan.fundingTx)
4✔
3788
        if err != nil {
4✔
3789
                return fmt.Errorf("unable to validate zero-conf channel: "+
×
3790
                        "%v", err)
×
3791
        }
×
3792

3793
        // Once we know the confirmed ShortChannelID, we'll need to save it to
3794
        // the database and refresh the OpenChannel struct with it.
3795
        err = c.MarkRealScid(confChan.shortChanID)
4✔
3796
        if err != nil {
4✔
3797
                return fmt.Errorf("unable to set confirmed SCID for zero "+
×
3798
                        "channel: %v", err)
×
3799
        }
×
3800

3801
        // Six confirmations have been reached. If this channel is public,
3802
        // we'll delete some of the alias mappings the gossiper uses.
3803
        isPublic := c.ChannelFlags&lnwire.FFAnnounceChannel != 0
4✔
3804
        if isPublic {
6✔
3805
                err = f.cfg.AliasManager.DeleteSixConfs(c.ShortChannelID)
2✔
3806
                if err != nil {
2✔
3807
                        return fmt.Errorf("unable to delete base alias after "+
×
3808
                                "six confirmations: %v", err)
×
3809
                }
×
3810

3811
                // TODO: Make this atomic!
3812
                ourPolicy, err := f.cfg.DeleteAliasEdge(c.ShortChanID())
2✔
3813
                if err != nil {
2✔
3814
                        return fmt.Errorf("unable to delete alias edge from "+
×
3815
                                "graph: %v", err)
×
3816
                }
×
3817

3818
                // We'll need to update the graph with the new ShortChannelID
3819
                // via an addToGraph call. We don't pass in the peer's
3820
                // alias since we'll be using the confirmed SCID from now on
3821
                // regardless if it's public or not.
3822
                err = f.addToGraph(
2✔
3823
                        c, &confChan.shortChanID, nil, ourPolicy,
2✔
3824
                )
2✔
3825
                if err != nil {
2✔
3826
                        return fmt.Errorf("failed adding confirmed zero-conf "+
×
3827
                                "SCID to graph: %v", err)
×
3828
                }
×
3829
        }
3830

3831
        // Since we have now marked down the confirmed SCID, we'll also need to
3832
        // tell the Switch to refresh the relevant ChannelLink so that forwards
3833
        // under the confirmed SCID are possible if this is a public channel.
3834
        err = f.cfg.ReportShortChanID(c.FundingOutpoint)
4✔
3835
        if err != nil {
4✔
3836
                // This should only fail if the link is not found in the
×
3837
                // Switch's linkIndex map. If this is the case, then the peer
×
3838
                // has gone offline and the next time the link is loaded, it
×
3839
                // will have a refreshed state. Just log an error here.
×
3840
                log.Errorf("unable to report scid for zero-conf channel "+
×
3841
                        "channel: %v", err)
×
3842
        }
×
3843

3844
        // Update the confirmed transaction's label.
3845
        f.makeLabelForTx(c)
4✔
3846

4✔
3847
        return nil
4✔
3848
}
3849

3850
// genFirstStateMusigNonce generates a nonces for the "first" local state. This
3851
// is the verification nonce for the state created for us after the initial
3852
// commitment transaction signed as part of the funding flow.
3853
func genFirstStateMusigNonce(channel *channeldb.OpenChannel,
3854
) (*musig2.Nonces, error) {
4✔
3855

4✔
3856
        musig2ShaChain, err := channeldb.DeriveMusig2Shachain(
4✔
3857
                channel.RevocationProducer,
4✔
3858
        )
4✔
3859
        if err != nil {
4✔
3860
                return nil, fmt.Errorf("unable to generate musig channel "+
×
3861
                        "nonces: %v", err)
×
3862
        }
×
3863

3864
        // We use the _next_ commitment height here as we need to generate the
3865
        // nonce for the next state the remote party will sign for us.
3866
        verNonce, err := channeldb.NewMusigVerificationNonce(
4✔
3867
                channel.LocalChanCfg.MultiSigKey.PubKey,
4✔
3868
                channel.LocalCommitment.CommitHeight+1,
4✔
3869
                musig2ShaChain,
4✔
3870
        )
4✔
3871
        if err != nil {
4✔
3872
                return nil, fmt.Errorf("unable to generate musig channel "+
×
3873
                        "nonces: %v", err)
×
3874
        }
×
3875

3876
        return verNonce, nil
4✔
3877
}
3878

3879
// handleChannelReady finalizes the channel funding process and enables the
3880
// channel to enter normal operating mode.
3881
func (f *Manager) handleChannelReady(peer lnpeer.Peer, //nolint:funlen
3882
        msg *lnwire.ChannelReady) {
28✔
3883

28✔
3884
        defer f.wg.Done()
28✔
3885

28✔
3886
        // If we are in development mode, we'll wait for specified duration
28✔
3887
        // before processing the channel ready message.
28✔
3888
        if f.cfg.Dev != nil {
28✔
UNCOV
3889
                duration := f.cfg.Dev.ProcessChannelReadyWait
×
UNCOV
3890
                log.Warnf("Channel(%v): sleeping %v before processing "+
×
UNCOV
3891
                        "channel_ready", msg.ChanID, duration)
×
UNCOV
3892

×
UNCOV
3893
                select {
×
UNCOV
3894
                case <-time.After(duration):
×
UNCOV
3895
                        log.Warnf("Channel(%v): slept %v before processing "+
×
UNCOV
3896
                                "channel_ready", msg.ChanID, duration)
×
3897
                case <-f.quit:
×
3898
                        log.Warnf("Channel(%v): quit sleeping", msg.ChanID)
×
3899
                        return
×
3900
                }
3901
        }
3902

3903
        log.Debugf("Received ChannelReady for ChannelID(%v) from "+
28✔
3904
                "peer %x", msg.ChanID,
28✔
3905
                peer.IdentityKey().SerializeCompressed())
28✔
3906

28✔
3907
        // We now load or create a new channel barrier for this channel.
28✔
3908
        _, loaded := f.handleChannelReadyBarriers.LoadOrStore(
28✔
3909
                msg.ChanID, struct{}{},
28✔
3910
        )
28✔
3911

28✔
3912
        // If we are currently in the process of handling a channel_ready
28✔
3913
        // message for this channel, ignore.
28✔
3914
        if loaded {
29✔
3915
                log.Infof("Already handling channelReady for "+
1✔
3916
                        "ChannelID(%v), ignoring.", msg.ChanID)
1✔
3917
                return
1✔
3918
        }
1✔
3919

3920
        // If not already handling channelReady for this channel, then the
3921
        // `LoadOrStore` has set up a barrier, and it will be removed once this
3922
        // function exits.
3923
        defer f.handleChannelReadyBarriers.Delete(msg.ChanID)
27✔
3924

27✔
3925
        localDiscoverySignal, ok := f.localDiscoverySignals.Load(msg.ChanID)
27✔
3926
        if ok {
52✔
3927
                // Before we proceed with processing the channel_ready
25✔
3928
                // message, we'll wait for the local waitForFundingConfirmation
25✔
3929
                // goroutine to signal that it has the necessary state in
25✔
3930
                // place. Otherwise, we may be missing critical information
25✔
3931
                // required to handle forwarded HTLC's.
25✔
3932
                select {
25✔
3933
                case <-localDiscoverySignal:
25✔
3934
                        // Fallthrough
3935
                case <-f.quit:
×
3936
                        return
×
3937
                }
3938

3939
                // With the signal received, we can now safely delete the entry
3940
                // from the map.
3941
                f.localDiscoverySignals.Delete(msg.ChanID)
25✔
3942
        }
3943

3944
        // First, we'll attempt to locate the channel whose funding workflow is
3945
        // being finalized by this message. We go to the database rather than
3946
        // our reservation map as we may have restarted, mid funding flow. Also
3947
        // provide the node's public key to make the search faster.
3948
        chanID := msg.ChanID
27✔
3949
        channel, err := f.cfg.FindChannel(peer.IdentityKey(), chanID)
27✔
3950
        if err != nil {
27✔
3951
                log.Errorf("Unable to locate ChannelID(%v), cannot complete "+
×
3952
                        "funding", chanID)
×
3953
                return
×
3954
        }
×
3955

3956
        // If this is a taproot channel, then we can generate the set of nonces
3957
        // the remote party needs to send the next remote commitment here.
3958
        var firstVerNonce *musig2.Nonces
27✔
3959
        if channel.ChanType.IsTaproot() {
31✔
3960
                firstVerNonce, err = genFirstStateMusigNonce(channel)
4✔
3961
                if err != nil {
4✔
3962
                        log.Error(err)
×
3963
                        return
×
3964
                }
×
3965
        }
3966

3967
        // We'll need to store the received TLV alias if the option_scid_alias
3968
        // feature was negotiated. This will be used to provide route hints
3969
        // during invoice creation. In the zero-conf case, it is also used to
3970
        // provide a ChannelUpdate to the remote peer. This is done before the
3971
        // call to InsertNextRevocation in case the call to PutPeerAlias fails.
3972
        // If it were to fail on the first call to handleChannelReady, we
3973
        // wouldn't want the channel to be usable yet.
3974
        if channel.NegotiatedAliasFeature() {
33✔
3975
                // If the AliasScid field is nil, we must fail out. We will
6✔
3976
                // most likely not be able to route through the peer.
6✔
3977
                if msg.AliasScid == nil {
6✔
3978
                        log.Debugf("Consider closing ChannelID(%v), peer "+
×
3979
                                "does not implement the option-scid-alias "+
×
3980
                                "feature properly", chanID)
×
3981
                        return
×
3982
                }
×
3983

3984
                // We'll store the AliasScid so that invoice creation can use
3985
                // it.
3986
                err = f.cfg.AliasManager.PutPeerAlias(chanID, *msg.AliasScid)
6✔
3987
                if err != nil {
6✔
3988
                        log.Errorf("unable to store peer's alias: %v", err)
×
3989
                        return
×
3990
                }
×
3991

3992
                // If we do not have an alias stored, we'll create one now.
3993
                // This is only used in the upgrade case where a user toggles
3994
                // the option-scid-alias feature-bit to on. We'll also send the
3995
                // channel_ready message here in case the link is created
3996
                // before sendChannelReady is called.
3997
                aliases := f.cfg.AliasManager.GetAliases(
6✔
3998
                        channel.ShortChannelID,
6✔
3999
                )
6✔
4000
                if len(aliases) == 0 {
6✔
4001
                        // No aliases were found so we'll request and store an
×
4002
                        // alias and use it in the channel_ready message.
×
4003
                        alias, err := f.cfg.AliasManager.RequestAlias()
×
4004
                        if err != nil {
×
4005
                                log.Errorf("unable to request alias: %v", err)
×
4006
                                return
×
4007
                        }
×
4008

4009
                        err = f.cfg.AliasManager.AddLocalAlias(
×
4010
                                alias, channel.ShortChannelID, false, false,
×
4011
                        )
×
4012
                        if err != nil {
×
4013
                                log.Errorf("unable to add local alias: %v",
×
4014
                                        err)
×
4015
                                return
×
4016
                        }
×
4017

4018
                        secondPoint, err := channel.SecondCommitmentPoint()
×
4019
                        if err != nil {
×
4020
                                log.Errorf("unable to fetch second "+
×
4021
                                        "commitment point: %v", err)
×
4022
                                return
×
4023
                        }
×
4024

4025
                        channelReadyMsg := lnwire.NewChannelReady(
×
4026
                                chanID, secondPoint,
×
4027
                        )
×
4028
                        channelReadyMsg.AliasScid = &alias
×
4029

×
4030
                        if firstVerNonce != nil {
×
4031
                                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce( //nolint:ll
×
4032
                                        firstVerNonce.PubNonce,
×
4033
                                )
×
4034
                        }
×
4035

4036
                        err = peer.SendMessage(true, channelReadyMsg)
×
4037
                        if err != nil {
×
4038
                                log.Errorf("unable to send channel_ready: %v",
×
4039
                                        err)
×
4040
                                return
×
4041
                        }
×
4042
                }
4043
        }
4044

4045
        // If the RemoteNextRevocation is non-nil, it means that we have
4046
        // already processed channelReady for this channel, so ignore. This
4047
        // check is after the alias logic so we store the peer's most recent
4048
        // alias. The spec requires us to validate that subsequent
4049
        // channel_ready messages use the same per commitment point (the
4050
        // second), but it is not actually necessary since we'll just end up
4051
        // ignoring it. We are, however, required to *send* the same per
4052
        // commitment point, since another pedantic implementation might
4053
        // verify it.
4054
        if channel.RemoteNextRevocation != nil {
28✔
4055
                log.Infof("Received duplicate channelReady for "+
1✔
4056
                        "ChannelID(%v), ignoring.", chanID)
1✔
4057
                return
1✔
4058
        }
1✔
4059

4060
        // If this is a taproot channel, then we'll need to map the received
4061
        // nonces to a nonce pair, and also fetch our pending nonces, which are
4062
        // required in order to make the channel whole.
4063
        var chanOpts []lnwallet.ChannelOpt
26✔
4064
        if channel.ChanType.IsTaproot() {
30✔
4065
                f.nonceMtx.Lock()
4✔
4066
                localNonce, ok := f.pendingMusigNonces[chanID]
4✔
4067
                if !ok {
4✔
UNCOV
4068
                        // If there's no pending nonce for this channel ID,
×
UNCOV
4069
                        // we'll use the one generated above.
×
UNCOV
4070
                        localNonce = firstVerNonce
×
UNCOV
4071
                        f.pendingMusigNonces[chanID] = firstVerNonce
×
UNCOV
4072
                }
×
4073
                f.nonceMtx.Unlock()
4✔
4074

4✔
4075
                log.Infof("ChanID(%v): applying local+remote musig2 nonces",
4✔
4076
                        chanID)
4✔
4077

4✔
4078
                remoteNonce, err := msg.NextLocalNonce.UnwrapOrErrV(
4✔
4079
                        errNoLocalNonce,
4✔
4080
                )
4✔
4081
                if err != nil {
4✔
4082
                        cid := newChanIdentifier(msg.ChanID)
×
4083
                        f.sendWarning(peer, cid, err)
×
4084

×
4085
                        return
×
4086
                }
×
4087

4088
                chanOpts = append(
4✔
4089
                        chanOpts,
4✔
4090
                        lnwallet.WithLocalMusigNonces(localNonce),
4✔
4091
                        lnwallet.WithRemoteMusigNonces(&musig2.Nonces{
4✔
4092
                                PubNonce: remoteNonce,
4✔
4093
                        }),
4✔
4094
                )
4✔
4095

4✔
4096
                // Inform the aux funding controller that the liquidity in the
4✔
4097
                // custom channel is now ready to be advertised. We potentially
4✔
4098
                // haven't sent our own channel ready message yet, but other
4✔
4099
                // than that the channel is ready to count toward available
4✔
4100
                // liquidity.
4✔
4101
                err = fn.MapOptionZ(
4✔
4102
                        f.cfg.AuxFundingController,
4✔
4103
                        func(controller AuxFundingController) error {
4✔
4104
                                return controller.ChannelReady(
×
4105
                                        lnwallet.NewAuxChanState(channel),
×
4106
                                )
×
4107
                        },
×
4108
                )
4109
                if err != nil {
4✔
4110
                        cid := newChanIdentifier(msg.ChanID)
×
4111
                        f.sendWarning(peer, cid, err)
×
4112

×
4113
                        return
×
4114
                }
×
4115
        }
4116

4117
        // The channel_ready message contains the next commitment point we'll
4118
        // need to create the next commitment state for the remote party. So
4119
        // we'll insert that into the channel now before passing it along to
4120
        // other sub-systems.
4121
        err = channel.InsertNextRevocation(msg.NextPerCommitmentPoint)
26✔
4122
        if err != nil {
26✔
4123
                log.Errorf("unable to insert next commitment point: %v", err)
×
4124
                return
×
4125
        }
×
4126

4127
        // Before we can add the channel to the peer, we'll need to ensure that
4128
        // we have an initial forwarding policy set.
4129
        if err := f.ensureInitialForwardingPolicy(chanID, channel); err != nil {
26✔
4130
                log.Errorf("Unable to ensure initial forwarding policy: %v",
×
4131
                        err)
×
4132
        }
×
4133

4134
        err = peer.AddNewChannel(&lnpeer.NewChannel{
26✔
4135
                OpenChannel: channel,
26✔
4136
                ChanOpts:    chanOpts,
26✔
4137
        }, f.quit)
26✔
4138
        if err != nil {
26✔
4139
                log.Errorf("Unable to add new channel %v with peer %x: %v",
×
4140
                        channel.FundingOutpoint,
×
4141
                        peer.IdentityKey().SerializeCompressed(), err,
×
4142
                )
×
4143
        }
×
4144
}
4145

4146
// handleChannelReadyReceived is called once the remote's channelReady message
4147
// is received and processed. At this stage, we must have sent out our
4148
// channelReady message, once the remote's channelReady is processed, the
4149
// channel is now active, thus we change its state to `addedToGraph` to
4150
// let the channel start handling routing.
4151
func (f *Manager) handleChannelReadyReceived(channel *channeldb.OpenChannel,
4152
        scid *lnwire.ShortChannelID, pendingChanID PendingChanID,
4153
        updateChan chan<- *lnrpc.OpenStatusUpdate) error {
24✔
4154

24✔
4155
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
24✔
4156

24✔
4157
        // Since we've sent+received funding locked at this point, we
24✔
4158
        // can clean up the pending musig2 nonce state.
24✔
4159
        f.nonceMtx.Lock()
24✔
4160
        delete(f.pendingMusigNonces, chanID)
24✔
4161
        f.nonceMtx.Unlock()
24✔
4162

24✔
4163
        var peerAlias *lnwire.ShortChannelID
24✔
4164
        if channel.IsZeroConf() {
28✔
4165
                // We'll need to wait until channel_ready has been received and
4✔
4166
                // the peer lets us know the alias they want to use for the
4✔
4167
                // channel. With this information, we can then construct a
4✔
4168
                // ChannelUpdate for them.  If an alias does not yet exist,
4✔
4169
                // we'll just return, letting the next iteration of the loop
4✔
4170
                // check again.
4✔
4171
                var defaultAlias lnwire.ShortChannelID
4✔
4172
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
4✔
4173
                foundAlias, _ := f.cfg.AliasManager.GetPeerAlias(chanID)
4✔
4174
                if foundAlias == defaultAlias {
4✔
4175
                        return nil
×
4176
                }
×
4177

4178
                peerAlias = &foundAlias
4✔
4179
        }
4180

4181
        err := f.addToGraph(channel, scid, peerAlias, nil)
24✔
4182
        if err != nil {
24✔
4183
                return fmt.Errorf("failed adding to graph: %w", err)
×
4184
        }
×
4185

4186
        // As the channel is now added to the ChannelRouter's topology, the
4187
        // channel is moved to the next state of the state machine. It will be
4188
        // moved to the last state (actually deleted from the database) after
4189
        // the channel is finally announced.
4190
        err = f.saveChannelOpeningState(
24✔
4191
                &channel.FundingOutpoint, addedToGraph, scid,
24✔
4192
        )
24✔
4193
        if err != nil {
24✔
4194
                return fmt.Errorf("error setting channel state to"+
×
4195
                        " addedToGraph: %w", err)
×
4196
        }
×
4197

4198
        log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
24✔
4199
                "added to graph", chanID, scid)
24✔
4200

24✔
4201
        err = fn.MapOptionZ(
24✔
4202
                f.cfg.AuxFundingController,
24✔
4203
                func(controller AuxFundingController) error {
24✔
4204
                        return controller.ChannelReady(
×
4205
                                lnwallet.NewAuxChanState(channel),
×
4206
                        )
×
4207
                },
×
4208
        )
4209
        if err != nil {
24✔
4210
                return fmt.Errorf("failed notifying aux funding controller "+
×
4211
                        "about channel ready: %w", err)
×
4212
        }
×
4213

4214
        // Give the caller a final update notifying them that the channel is
4215
        fundingPoint := channel.FundingOutpoint
24✔
4216
        cp := &lnrpc.ChannelPoint{
24✔
4217
                FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
24✔
4218
                        FundingTxidBytes: fundingPoint.Hash[:],
24✔
4219
                },
24✔
4220
                OutputIndex: fundingPoint.Index,
24✔
4221
        }
24✔
4222

24✔
4223
        if updateChan != nil {
34✔
4224
                upd := &lnrpc.OpenStatusUpdate{
10✔
4225
                        Update: &lnrpc.OpenStatusUpdate_ChanOpen{
10✔
4226
                                ChanOpen: &lnrpc.ChannelOpenUpdate{
10✔
4227
                                        ChannelPoint: cp,
10✔
4228
                                },
10✔
4229
                        },
10✔
4230
                        PendingChanId: pendingChanID[:],
10✔
4231
                }
10✔
4232

10✔
4233
                select {
10✔
4234
                case updateChan <- upd:
10✔
4235
                case <-f.quit:
×
4236
                        return ErrFundingManagerShuttingDown
×
4237
                }
4238
        }
4239

4240
        return nil
24✔
4241
}
4242

4243
// ensureInitialForwardingPolicy ensures that we have an initial forwarding
4244
// policy set for the given channel. If we don't, we'll fall back to the default
4245
// values.
4246
func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID,
4247
        channel *channeldb.OpenChannel) error {
26✔
4248

26✔
4249
        // Before we can add the channel to the peer, we'll need to ensure that
26✔
4250
        // we have an initial forwarding policy set. This should always be the
26✔
4251
        // case except for a channel that was created with lnd <= 0.15.5 and
26✔
4252
        // is still pending while updating to this version.
26✔
4253
        var needDBUpdate bool
26✔
4254
        forwardingPolicy, err := f.getInitialForwardingPolicy(chanID)
26✔
4255
        if err != nil {
26✔
4256
                log.Errorf("Unable to fetch initial forwarding policy, "+
×
4257
                        "falling back to default values: %v", err)
×
4258

×
4259
                forwardingPolicy = f.defaultForwardingPolicy(
×
4260
                        channel.LocalChanCfg.ChannelStateBounds,
×
4261
                )
×
4262
                needDBUpdate = true
×
4263
        }
×
4264

4265
        // We only started storing the actual values for MinHTLCOut and MaxHTLC
4266
        // after 0.16.x, so if a channel was opened with such a version and is
4267
        // still pending while updating to this version, we'll need to set the
4268
        // values to the default values.
4269
        if forwardingPolicy.MinHTLCOut == 0 {
39✔
4270
                forwardingPolicy.MinHTLCOut = channel.LocalChanCfg.MinHTLC
13✔
4271
                needDBUpdate = true
13✔
4272
        }
13✔
4273
        if forwardingPolicy.MaxHTLC == 0 {
39✔
4274
                forwardingPolicy.MaxHTLC = channel.LocalChanCfg.MaxPendingAmount
13✔
4275
                needDBUpdate = true
13✔
4276
        }
13✔
4277

4278
        // And finally, if we found that the values currently stored aren't
4279
        // sufficient for the link, we'll update the database.
4280
        if needDBUpdate {
39✔
4281
                err := f.saveInitialForwardingPolicy(chanID, forwardingPolicy)
13✔
4282
                if err != nil {
13✔
4283
                        return fmt.Errorf("unable to update initial "+
×
4284
                                "forwarding policy: %v", err)
×
4285
                }
×
4286
        }
4287

4288
        return nil
26✔
4289
}
4290

4291
// chanAnnouncement encapsulates the two authenticated announcements that we
4292
// send out to the network after a new channel has been created locally.
4293
type chanAnnouncement struct {
4294
        chanAnn       *lnwire.ChannelAnnouncement1
4295
        chanUpdateAnn *lnwire.ChannelUpdate1
4296
        chanProof     *lnwire.AnnounceSignatures1
4297
}
4298

4299
// newChanAnnouncement creates the authenticated channel announcement messages
4300
// required to broadcast a newly created channel to the network. The
4301
// announcement is two part: the first part authenticates the existence of the
4302
// channel and contains four signatures binding the funding pub keys and
4303
// identity pub keys of both parties to the channel, and the second segment is
4304
// authenticated only by us and contains our directional routing policy for the
4305
// channel. ourPolicy may be set in order to re-use an existing, non-default
4306
// policy.
4307
func (f *Manager) newChanAnnouncement(localPubKey,
4308
        remotePubKey *btcec.PublicKey, localFundingKey *keychain.KeyDescriptor,
4309
        remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
4310
        chanID lnwire.ChannelID, fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi,
4311
        ourPolicy *models.ChannelEdgePolicy,
4312
        chanType channeldb.ChannelType) (*chanAnnouncement, error) {
42✔
4313

42✔
4314
        chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
42✔
4315

42✔
4316
        // The unconditional section of the announcement is the ShortChannelID
42✔
4317
        // itself which compactly encodes the location of the funding output
42✔
4318
        // within the blockchain.
42✔
4319
        chanAnn := &lnwire.ChannelAnnouncement1{
42✔
4320
                ShortChannelID: shortChanID,
42✔
4321
                Features:       lnwire.NewRawFeatureVector(),
42✔
4322
                ChainHash:      chainHash,
42✔
4323
        }
42✔
4324

42✔
4325
        // If this is a taproot channel, then we'll set a special bit in the
42✔
4326
        // feature vector to indicate to the routing layer that this needs a
42✔
4327
        // slightly different type of validation.
42✔
4328
        //
42✔
4329
        // TODO(roasbeef): temp, remove after gossip 1.5
42✔
4330
        if chanType.IsTaproot() {
46✔
4331
                log.Debugf("Applying taproot feature bit to "+
4✔
4332
                        "ChannelAnnouncement for %v", chanID)
4✔
4333

4✔
4334
                chanAnn.Features.Set(
4✔
4335
                        lnwire.SimpleTaprootChannelsRequiredStaging,
4✔
4336
                )
4✔
4337
        }
4✔
4338

4339
        // The chanFlags field indicates which directed edge of the channel is
4340
        // being updated within the ChannelUpdateAnnouncement announcement
4341
        // below. A value of zero means it's the edge of the "first" node and 1
4342
        // being the other node.
4343
        var chanFlags lnwire.ChanUpdateChanFlags
42✔
4344

42✔
4345
        // The lexicographical ordering of the two identity public keys of the
42✔
4346
        // nodes indicates which of the nodes is "first". If our serialized
42✔
4347
        // identity key is lower than theirs then we're the "first" node and
42✔
4348
        // second otherwise.
42✔
4349
        selfBytes := localPubKey.SerializeCompressed()
42✔
4350
        remoteBytes := remotePubKey.SerializeCompressed()
42✔
4351
        if bytes.Compare(selfBytes, remoteBytes) == -1 {
63✔
4352
                copy(chanAnn.NodeID1[:], localPubKey.SerializeCompressed())
21✔
4353
                copy(chanAnn.NodeID2[:], remotePubKey.SerializeCompressed())
21✔
4354
                copy(
21✔
4355
                        chanAnn.BitcoinKey1[:],
21✔
4356
                        localFundingKey.PubKey.SerializeCompressed(),
21✔
4357
                )
21✔
4358
                copy(
21✔
4359
                        chanAnn.BitcoinKey2[:],
21✔
4360
                        remoteFundingKey.SerializeCompressed(),
21✔
4361
                )
21✔
4362

21✔
4363
                // If we're the first node then update the chanFlags to
21✔
4364
                // indicate the "direction" of the update.
21✔
4365
                chanFlags = 0
21✔
4366
        } else {
42✔
4367
                copy(chanAnn.NodeID1[:], remotePubKey.SerializeCompressed())
21✔
4368
                copy(chanAnn.NodeID2[:], localPubKey.SerializeCompressed())
21✔
4369
                copy(
21✔
4370
                        chanAnn.BitcoinKey1[:],
21✔
4371
                        remoteFundingKey.SerializeCompressed(),
21✔
4372
                )
21✔
4373
                copy(
21✔
4374
                        chanAnn.BitcoinKey2[:],
21✔
4375
                        localFundingKey.PubKey.SerializeCompressed(),
21✔
4376
                )
21✔
4377

21✔
4378
                // If we're the second node then update the chanFlags to
21✔
4379
                // indicate the "direction" of the update.
21✔
4380
                chanFlags = 1
21✔
4381
        }
21✔
4382

4383
        // Our channel update message flags will signal that we support the
4384
        // max_htlc field.
4385
        msgFlags := lnwire.ChanUpdateRequiredMaxHtlc
42✔
4386

42✔
4387
        // We announce the channel with the default values. Some of
42✔
4388
        // these values can later be changed by crafting a new ChannelUpdate.
42✔
4389
        chanUpdateAnn := &lnwire.ChannelUpdate1{
42✔
4390
                ShortChannelID: shortChanID,
42✔
4391
                ChainHash:      chainHash,
42✔
4392
                Timestamp:      uint32(time.Now().Unix()),
42✔
4393
                MessageFlags:   msgFlags,
42✔
4394
                ChannelFlags:   chanFlags,
42✔
4395
                TimeLockDelta: uint16(
42✔
4396
                        f.cfg.DefaultRoutingPolicy.TimeLockDelta,
42✔
4397
                ),
42✔
4398
                HtlcMinimumMsat: fwdMinHTLC,
42✔
4399
                HtlcMaximumMsat: fwdMaxHTLC,
42✔
4400
        }
42✔
4401

42✔
4402
        // The caller of newChanAnnouncement is expected to provide the initial
42✔
4403
        // forwarding policy to be announced. If no persisted initial policy
42✔
4404
        // values are found, then we will use the default policy values in the
42✔
4405
        // channel announcement.
42✔
4406
        storedFwdingPolicy, err := f.getInitialForwardingPolicy(chanID)
42✔
4407
        if err != nil && !errors.Is(err, channeldb.ErrChannelNotFound) {
42✔
4408
                return nil, errors.Errorf("unable to generate channel "+
×
4409
                        "update announcement: %v", err)
×
4410
        }
×
4411

4412
        switch {
42✔
UNCOV
4413
        case ourPolicy != nil:
×
UNCOV
4414
                // If ourPolicy is non-nil, modify the default parameters of the
×
UNCOV
4415
                // ChannelUpdate.
×
UNCOV
4416
                chanUpdateAnn.MessageFlags = ourPolicy.MessageFlags
×
UNCOV
4417
                chanUpdateAnn.ChannelFlags = ourPolicy.ChannelFlags
×
UNCOV
4418
                chanUpdateAnn.TimeLockDelta = ourPolicy.TimeLockDelta
×
UNCOV
4419
                chanUpdateAnn.HtlcMinimumMsat = ourPolicy.MinHTLC
×
UNCOV
4420
                chanUpdateAnn.HtlcMaximumMsat = ourPolicy.MaxHTLC
×
UNCOV
4421
                chanUpdateAnn.BaseFee = uint32(ourPolicy.FeeBaseMSat)
×
UNCOV
4422
                chanUpdateAnn.FeeRate = uint32(
×
UNCOV
4423
                        ourPolicy.FeeProportionalMillionths,
×
UNCOV
4424
                )
×
4425

4426
        case storedFwdingPolicy != nil:
42✔
4427
                chanUpdateAnn.BaseFee = uint32(storedFwdingPolicy.BaseFee)
42✔
4428
                chanUpdateAnn.FeeRate = uint32(storedFwdingPolicy.FeeRate)
42✔
4429

4430
        default:
×
4431
                log.Infof("No channel forwarding policy specified for channel "+
×
4432
                        "announcement of ChannelID(%v). "+
×
4433
                        "Assuming default fee parameters.", chanID)
×
4434
                chanUpdateAnn.BaseFee = uint32(
×
4435
                        f.cfg.DefaultRoutingPolicy.BaseFee,
×
4436
                )
×
4437
                chanUpdateAnn.FeeRate = uint32(
×
4438
                        f.cfg.DefaultRoutingPolicy.FeeRate,
×
4439
                )
×
4440
        }
4441

4442
        // With the channel update announcement constructed, we'll generate a
4443
        // signature that signs a double-sha digest of the announcement.
4444
        // This'll serve to authenticate this announcement and any other future
4445
        // updates we may send.
4446
        chanUpdateMsg, err := chanUpdateAnn.DataToSign()
42✔
4447
        if err != nil {
42✔
4448
                return nil, err
×
4449
        }
×
4450
        sig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanUpdateMsg, true)
42✔
4451
        if err != nil {
42✔
4452
                return nil, errors.Errorf("unable to generate channel "+
×
4453
                        "update announcement signature: %v", err)
×
4454
        }
×
4455
        chanUpdateAnn.Signature, err = lnwire.NewSigFromSignature(sig)
42✔
4456
        if err != nil {
42✔
4457
                return nil, errors.Errorf("unable to generate channel "+
×
4458
                        "update announcement signature: %v", err)
×
4459
        }
×
4460

4461
        // The channel existence proofs itself is currently announced in
4462
        // distinct message. In order to properly authenticate this message, we
4463
        // need two signatures: one under the identity public key used which
4464
        // signs the message itself and another signature of the identity
4465
        // public key under the funding key itself.
4466
        //
4467
        // TODO(roasbeef): use SignAnnouncement here instead?
4468
        chanAnnMsg, err := chanAnn.DataToSign()
42✔
4469
        if err != nil {
42✔
4470
                return nil, err
×
4471
        }
×
4472
        nodeSig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanAnnMsg, true)
42✔
4473
        if err != nil {
42✔
4474
                return nil, errors.Errorf("unable to generate node "+
×
4475
                        "signature for channel announcement: %v", err)
×
4476
        }
×
4477
        bitcoinSig, err := f.cfg.SignMessage(
42✔
4478
                localFundingKey.KeyLocator, chanAnnMsg, true,
42✔
4479
        )
42✔
4480
        if err != nil {
42✔
4481
                return nil, errors.Errorf("unable to generate bitcoin "+
×
4482
                        "signature for node public key: %v", err)
×
4483
        }
×
4484

4485
        // Finally, we'll generate the announcement proof which we'll use to
4486
        // provide the other side with the necessary signatures required to
4487
        // allow them to reconstruct the full channel announcement.
4488
        proof := &lnwire.AnnounceSignatures1{
42✔
4489
                ChannelID:      chanID,
42✔
4490
                ShortChannelID: shortChanID,
42✔
4491
        }
42✔
4492
        proof.NodeSignature, err = lnwire.NewSigFromSignature(nodeSig)
42✔
4493
        if err != nil {
42✔
4494
                return nil, err
×
4495
        }
×
4496
        proof.BitcoinSignature, err = lnwire.NewSigFromSignature(bitcoinSig)
42✔
4497
        if err != nil {
42✔
4498
                return nil, err
×
4499
        }
×
4500

4501
        return &chanAnnouncement{
42✔
4502
                chanAnn:       chanAnn,
42✔
4503
                chanUpdateAnn: chanUpdateAnn,
42✔
4504
                chanProof:     proof,
42✔
4505
        }, nil
42✔
4506
}
4507

4508
// announceChannel announces a newly created channel to the rest of the network
4509
// by crafting the two authenticated announcements required for the peers on
4510
// the network to recognize the legitimacy of the channel. The crafted
4511
// announcements are then sent to the channel router to handle broadcasting to
4512
// the network during its next trickle.
4513
// This method is synchronous and will return when all the network requests
4514
// finish, either successfully or with an error.
4515
func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
4516
        localFundingKey *keychain.KeyDescriptor,
4517
        remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
4518
        chanID lnwire.ChannelID, chanType channeldb.ChannelType) error {
16✔
4519

16✔
4520
        // First, we'll create the batch of announcements to be sent upon
16✔
4521
        // initial channel creation. This includes the channel announcement
16✔
4522
        // itself, the channel update announcement, and our half of the channel
16✔
4523
        // proof needed to fully authenticate the channel.
16✔
4524
        //
16✔
4525
        // We can pass in zeroes for the min and max htlc policy, because we
16✔
4526
        // only use the channel announcement message from the returned struct.
16✔
4527
        ann, err := f.newChanAnnouncement(
16✔
4528
                localIDKey, remoteIDKey, localFundingKey, remoteFundingKey,
16✔
4529
                shortChanID, chanID, 0, 0, nil, chanType,
16✔
4530
        )
16✔
4531
        if err != nil {
16✔
4532
                log.Errorf("can't generate channel announcement: %v", err)
×
4533
                return err
×
4534
        }
×
4535

4536
        // We only send the channel proof announcement and the node announcement
4537
        // because addToGraph previously sent the ChannelAnnouncement and
4538
        // the ChannelUpdate announcement messages. The channel proof and node
4539
        // announcements are broadcast to the greater network.
4540
        errChan := f.cfg.SendAnnouncement(ann.chanProof)
16✔
4541
        select {
16✔
4542
        case err := <-errChan:
16✔
4543
                if err != nil {
16✔
UNCOV
4544
                        if graph.IsError(err, graph.ErrOutdated,
×
UNCOV
4545
                                graph.ErrIgnored) {
×
4546

×
4547
                                log.Debugf("Graph rejected "+
×
4548
                                        "AnnounceSignatures: %v", err)
×
UNCOV
4549
                        } else {
×
UNCOV
4550
                                log.Errorf("Unable to send channel "+
×
UNCOV
4551
                                        "proof: %v", err)
×
UNCOV
4552
                                return err
×
UNCOV
4553
                        }
×
4554
                }
4555

4556
        case <-f.quit:
×
4557
                return ErrFundingManagerShuttingDown
×
4558
        }
4559

4560
        // Now that the channel is announced to the network, we will also
4561
        // obtain and send a node announcement. This is done since a node
4562
        // announcement is only accepted after a channel is known for that
4563
        // particular node, and this might be our first channel.
4564
        nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
16✔
4565
        if err != nil {
16✔
4566
                log.Errorf("can't generate node announcement: %v", err)
×
4567
                return err
×
4568
        }
×
4569

4570
        errChan = f.cfg.SendAnnouncement(&nodeAnn)
16✔
4571
        select {
16✔
4572
        case err := <-errChan:
16✔
4573
                if err != nil {
16✔
UNCOV
4574
                        if graph.IsError(err, graph.ErrOutdated,
×
UNCOV
4575
                                graph.ErrIgnored) {
×
UNCOV
4576

×
UNCOV
4577
                                log.Debugf("Graph rejected "+
×
UNCOV
4578
                                        "NodeAnnouncement: %v", err)
×
UNCOV
4579
                        } else {
×
4580
                                log.Errorf("Unable to send node "+
×
4581
                                        "announcement: %v", err)
×
4582
                                return err
×
4583
                        }
×
4584
                }
4585

4586
        case <-f.quit:
×
4587
                return ErrFundingManagerShuttingDown
×
4588
        }
4589

4590
        return nil
16✔
4591
}
4592

4593
// InitFundingWorkflow sends a message to the funding manager instructing it
4594
// to initiate a single funder workflow with the source peer.
4595
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
56✔
4596
        f.fundingRequests <- msg
56✔
4597
}
56✔
4598

4599
// getUpfrontShutdownScript takes a user provided script and a getScript
4600
// function which can be used to generate an upfront shutdown script. If our
4601
// peer does not support the feature, this function will error if a non-zero
4602
// script was provided by the user, and return an empty script otherwise. If
4603
// our peer does support the feature, we will return the user provided script
4604
// if non-zero, or a freshly generated script if our node is configured to set
4605
// upfront shutdown scripts automatically.
4606
func getUpfrontShutdownScript(enableUpfrontShutdown bool, peer lnpeer.Peer,
4607
        script lnwire.DeliveryAddress,
4608
        getScript func(bool) (lnwire.DeliveryAddress, error)) (lnwire.DeliveryAddress,
4609
        error) {
108✔
4610

108✔
4611
        // Check whether the remote peer supports upfront shutdown scripts.
108✔
4612
        remoteUpfrontShutdown := peer.RemoteFeatures().HasFeature(
108✔
4613
                lnwire.UpfrontShutdownScriptOptional,
108✔
4614
        )
108✔
4615

108✔
4616
        // If the peer does not support upfront shutdown scripts, and one has been
108✔
4617
        // provided, return an error because the feature is not supported.
108✔
4618
        if !remoteUpfrontShutdown && len(script) != 0 {
109✔
4619
                return nil, errUpfrontShutdownScriptNotSupported
1✔
4620
        }
1✔
4621

4622
        // If the peer does not support upfront shutdown, return an empty address.
4623
        if !remoteUpfrontShutdown {
210✔
4624
                return nil, nil
103✔
4625
        }
103✔
4626

4627
        // If the user has provided an script and the peer supports the feature,
4628
        // return it. Note that user set scripts override the enable upfront
4629
        // shutdown flag.
4630
        if len(script) > 0 {
6✔
4631
                return script, nil
2✔
4632
        }
2✔
4633

4634
        // If we do not have setting of upfront shutdown script enabled, return
4635
        // an empty script.
4636
        if !enableUpfrontShutdown {
3✔
4637
                return nil, nil
1✔
4638
        }
1✔
4639

4640
        // We can safely send a taproot address iff, both sides have negotiated
4641
        // the shutdown-any-segwit feature.
4642
        taprootOK := peer.RemoteFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) &&
1✔
4643
                peer.LocalFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional)
1✔
4644

1✔
4645
        return getScript(taprootOK)
1✔
4646
}
4647

4648
// handleInitFundingMsg creates a channel reservation within the daemon's
4649
// wallet, then sends a funding request to the remote peer kicking off the
4650
// funding workflow.
4651
func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
56✔
4652
        var (
56✔
4653
                peerKey        = msg.Peer.IdentityKey()
56✔
4654
                localAmt       = msg.LocalFundingAmt
56✔
4655
                baseFee        = msg.BaseFee
56✔
4656
                feeRate        = msg.FeeRate
56✔
4657
                minHtlcIn      = msg.MinHtlcIn
56✔
4658
                remoteCsvDelay = msg.RemoteCsvDelay
56✔
4659
                maxValue       = msg.MaxValueInFlight
56✔
4660
                maxHtlcs       = msg.MaxHtlcs
56✔
4661
                maxCSV         = msg.MaxLocalCsv
56✔
4662
                chanReserve    = msg.RemoteChanReserve
56✔
4663
                outpoints      = msg.Outpoints
56✔
4664
        )
56✔
4665

56✔
4666
        // If no maximum CSV delay was set for this channel, we use our default
56✔
4667
        // value.
56✔
4668
        if maxCSV == 0 {
112✔
4669
                maxCSV = f.cfg.MaxLocalCSVDelay
56✔
4670
        }
56✔
4671

4672
        log.Infof("Initiating fundingRequest(local_amt=%v "+
56✔
4673
                "(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
56✔
4674
                "min_confs=%v)", localAmt, msg.SubtractFees, msg.PushAmt,
56✔
4675
                msg.ChainHash, peerKey.SerializeCompressed(), msg.MinConfs)
56✔
4676

56✔
4677
        // We set the channel flags to indicate whether we want this channel to
56✔
4678
        // be announced to the network.
56✔
4679
        var channelFlags lnwire.FundingFlag
56✔
4680
        if !msg.Private {
107✔
4681
                // This channel will be announced.
51✔
4682
                channelFlags = lnwire.FFAnnounceChannel
51✔
4683
        }
51✔
4684

4685
        // If the caller specified their own channel ID, then we'll use that.
4686
        // Otherwise we'll generate a fresh one as normal.  This will be used
4687
        // to track this reservation throughout its lifetime.
4688
        var chanID PendingChanID
56✔
4689
        if msg.PendingChanID == zeroID {
112✔
4690
                chanID = f.nextPendingChanID()
56✔
4691
        } else {
56✔
UNCOV
4692
                // If the user specified their own pending channel ID, then
×
UNCOV
4693
                // we'll ensure it doesn't collide with any existing pending
×
UNCOV
4694
                // channel ID.
×
UNCOV
4695
                chanID = msg.PendingChanID
×
UNCOV
4696
                if _, err := f.getReservationCtx(peerKey, chanID); err == nil {
×
4697
                        msg.Err <- fmt.Errorf("pendingChannelID(%x) "+
×
4698
                                "already present", chanID[:])
×
4699
                        return
×
4700
                }
×
4701
        }
4702

4703
        // Check whether the peer supports upfront shutdown, and get an address
4704
        // which should be used (either a user specified address or a new
4705
        // address from the wallet if our node is configured to set shutdown
4706
        // address by default).
4707
        shutdown, err := getUpfrontShutdownScript(
56✔
4708
                f.cfg.EnableUpfrontShutdown, msg.Peer, msg.ShutdownScript,
56✔
4709
                f.selectShutdownScript,
56✔
4710
        )
56✔
4711
        if err != nil {
56✔
4712
                msg.Err <- err
×
4713
                return
×
4714
        }
×
4715

4716
        // Initialize a funding reservation with the local wallet. If the
4717
        // wallet doesn't have enough funds to commit to this channel, then the
4718
        // request will fail, and be aborted.
4719
        //
4720
        // Before we init the channel, we'll also check to see what commitment
4721
        // format we can use with this peer. This is dependent on *both* us and
4722
        // the remote peer are signaling the proper feature bit.
4723
        chanType, commitType, err := negotiateCommitmentType(
56✔
4724
                msg.ChannelType, msg.Peer.LocalFeatures(),
56✔
4725
                msg.Peer.RemoteFeatures(),
56✔
4726
        )
56✔
4727
        if err != nil {
56✔
UNCOV
4728
                log.Errorf("channel type negotiation failed: %v", err)
×
UNCOV
4729
                msg.Err <- err
×
UNCOV
4730
                return
×
UNCOV
4731
        }
×
4732

4733
        var (
56✔
4734
                zeroConf bool
56✔
4735
                scid     bool
56✔
4736
        )
56✔
4737

56✔
4738
        if chanType != nil {
60✔
4739
                // Check if the returned chanType includes either the zero-conf
4✔
4740
                // or scid-alias bits.
4✔
4741
                featureVec := lnwire.RawFeatureVector(*chanType)
4✔
4742
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
4✔
4743
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
4✔
4744

4✔
4745
                // The option-scid-alias channel type for a public channel is
4✔
4746
                // disallowed.
4✔
4747
                if scid && !msg.Private {
4✔
4748
                        err = fmt.Errorf("option-scid-alias chantype for " +
×
4749
                                "public channel")
×
4750
                        log.Error(err)
×
4751
                        msg.Err <- err
×
4752

×
4753
                        return
×
4754
                }
×
4755
        }
4756

4757
        // First, we'll query the fee estimator for a fee that should get the
4758
        // commitment transaction confirmed by the next few blocks (conf target
4759
        // of 3). We target the near blocks here to ensure that we'll be able
4760
        // to execute a timely unilateral channel closure if needed.
4761
        commitFeePerKw, err := f.cfg.FeeEstimator.EstimateFeePerKW(3)
56✔
4762
        if err != nil {
56✔
4763
                msg.Err <- err
×
4764
                return
×
4765
        }
×
4766

4767
        // For anchor channels cap the initial commit fee rate at our defined
4768
        // maximum.
4769
        if commitType.HasAnchors() &&
56✔
4770
                commitFeePerKw > f.cfg.MaxAnchorsCommitFeeRate {
60✔
4771

4✔
4772
                commitFeePerKw = f.cfg.MaxAnchorsCommitFeeRate
4✔
4773
        }
4✔
4774

4775
        var scidFeatureVal bool
56✔
4776
        if hasFeatures(
56✔
4777
                msg.Peer.LocalFeatures(), msg.Peer.RemoteFeatures(),
56✔
4778
                lnwire.ScidAliasOptional,
56✔
4779
        ) {
59✔
4780

3✔
4781
                scidFeatureVal = true
3✔
4782
        }
3✔
4783

4784
        // At this point, if we have an AuxFundingController active, we'll check
4785
        // to see if we have a special tapscript root to use in our MuSig2
4786
        // funding output.
4787
        tapscriptRoot, err := fn.MapOptionZ(
56✔
4788
                f.cfg.AuxFundingController,
56✔
4789
                func(c AuxFundingController) AuxTapscriptResult {
56✔
4790
                        return c.DeriveTapscriptRoot(chanID)
×
4791
                },
×
4792
        ).Unpack()
4793
        if err != nil {
56✔
4794
                err = fmt.Errorf("error deriving tapscript root: %w", err)
×
4795
                log.Error(err)
×
4796
                msg.Err <- err
×
4797

×
4798
                return
×
4799
        }
×
4800

4801
        req := &lnwallet.InitFundingReserveMsg{
56✔
4802
                ChainHash:         &msg.ChainHash,
56✔
4803
                PendingChanID:     chanID,
56✔
4804
                NodeID:            peerKey,
56✔
4805
                NodeAddr:          msg.Peer.Address(),
56✔
4806
                SubtractFees:      msg.SubtractFees,
56✔
4807
                LocalFundingAmt:   localAmt,
56✔
4808
                RemoteFundingAmt:  0,
56✔
4809
                FundUpToMaxAmt:    msg.FundUpToMaxAmt,
56✔
4810
                MinFundAmt:        msg.MinFundAmt,
56✔
4811
                RemoteChanReserve: chanReserve,
56✔
4812
                Outpoints:         outpoints,
56✔
4813
                CommitFeePerKw:    commitFeePerKw,
56✔
4814
                FundingFeePerKw:   msg.FundingFeePerKw,
56✔
4815
                PushMSat:          msg.PushAmt,
56✔
4816
                Flags:             channelFlags,
56✔
4817
                MinConfs:          msg.MinConfs,
56✔
4818
                CommitType:        commitType,
56✔
4819
                ChanFunder:        msg.ChanFunder,
56✔
4820
                // Unconfirmed Utxos which are marked by the sweeper subsystem
56✔
4821
                // are excluded from the coin selection because they are not
56✔
4822
                // final and can be RBFed by the sweeper subsystem.
56✔
4823
                AllowUtxoForFunding: func(u lnwallet.Utxo) bool {
113✔
4824
                        // Utxos with at least 1 confirmation are safe to use
57✔
4825
                        // for channel openings because they don't bare the risk
57✔
4826
                        // of being replaced (BIP 125 RBF).
57✔
4827
                        if u.Confirmations > 0 {
57✔
UNCOV
4828
                                return true
×
UNCOV
4829
                        }
×
4830

4831
                        // Query the sweeper storage to make sure we don't use
4832
                        // an unconfirmed utxo still in use by the sweeper
4833
                        // subsystem.
4834
                        return !f.cfg.IsSweeperOutpoint(u.OutPoint)
57✔
4835
                },
4836
                ZeroConf:         zeroConf,
4837
                OptionScidAlias:  scid,
4838
                ScidAliasFeature: scidFeatureVal,
4839
                Memo:             msg.Memo,
4840
                TapscriptRoot:    tapscriptRoot,
4841
        }
4842

4843
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
56✔
4844
        if err != nil {
56✔
UNCOV
4845
                msg.Err <- err
×
UNCOV
4846
                return
×
UNCOV
4847
        }
×
4848

4849
        if zeroConf {
58✔
4850
                // Store the alias for zero-conf channels in the underlying
2✔
4851
                // partial channel state.
2✔
4852
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
2✔
4853
                if err != nil {
2✔
4854
                        msg.Err <- err
×
4855
                        return
×
4856
                }
×
4857

4858
                reservation.AddAlias(aliasScid)
2✔
4859
        }
4860

4861
        // Set our upfront shutdown address in the existing reservation.
4862
        reservation.SetOurUpfrontShutdown(shutdown)
56✔
4863

56✔
4864
        // Now that we have successfully reserved funds for this channel in the
56✔
4865
        // wallet, we can fetch the final channel capacity. This is done at
56✔
4866
        // this point since the final capacity might change in case of
56✔
4867
        // SubtractFees=true.
56✔
4868
        capacity := reservation.Capacity()
56✔
4869

56✔
4870
        log.Infof("Target commit tx sat/kw for pendingID(%x): %v", chanID,
56✔
4871
                int64(commitFeePerKw))
56✔
4872

56✔
4873
        // If the remote CSV delay was not set in the open channel request,
56✔
4874
        // we'll use the RequiredRemoteDelay closure to compute the delay we
56✔
4875
        // require given the total amount of funds within the channel.
56✔
4876
        if remoteCsvDelay == 0 {
111✔
4877
                remoteCsvDelay = f.cfg.RequiredRemoteDelay(capacity)
55✔
4878
        }
55✔
4879

4880
        // If no minimum HTLC value was specified, use the default one.
4881
        if minHtlcIn == 0 {
111✔
4882
                minHtlcIn = f.cfg.DefaultMinHtlcIn
55✔
4883
        }
55✔
4884

4885
        // If no max value was specified, use the default one.
4886
        if maxValue == 0 {
111✔
4887
                maxValue = f.cfg.RequiredRemoteMaxValue(capacity)
55✔
4888
        }
55✔
4889

4890
        if maxHtlcs == 0 {
112✔
4891
                maxHtlcs = f.cfg.RequiredRemoteMaxHTLCs(capacity)
56✔
4892
        }
56✔
4893

4894
        // Once the reservation has been created, and indexed, queue a funding
4895
        // request to the remote peer, kicking off the funding workflow.
4896
        ourContribution := reservation.OurContribution()
56✔
4897

56✔
4898
        // Prepare the optional channel fee values from the initFundingMsg. If
56✔
4899
        // useBaseFee or useFeeRate are false the client did not provide fee
56✔
4900
        // values hence we assume default fee settings from the config.
56✔
4901
        forwardingPolicy := f.defaultForwardingPolicy(
56✔
4902
                ourContribution.ChannelStateBounds,
56✔
4903
        )
56✔
4904
        if baseFee != nil {
57✔
4905
                forwardingPolicy.BaseFee = lnwire.MilliSatoshi(*baseFee)
1✔
4906
        }
1✔
4907

4908
        if feeRate != nil {
57✔
4909
                forwardingPolicy.FeeRate = lnwire.MilliSatoshi(*feeRate)
1✔
4910
        }
1✔
4911

4912
        // Fetch our dust limit which is part of the default channel
4913
        // constraints, and log it.
4914
        ourDustLimit := ourContribution.DustLimit
56✔
4915

56✔
4916
        log.Infof("Dust limit for pendingID(%x): %v", chanID, ourDustLimit)
56✔
4917

56✔
4918
        // If the channel reserve is not specified, then we calculate an
56✔
4919
        // appropriate amount here.
56✔
4920
        if chanReserve == 0 {
108✔
4921
                chanReserve = f.cfg.RequiredRemoteChanReserve(
52✔
4922
                        capacity, ourDustLimit,
52✔
4923
                )
52✔
4924
        }
52✔
4925

4926
        // If a pending channel map for this peer isn't already created, then
4927
        // we create one, ultimately allowing us to track this pending
4928
        // reservation within the target peer.
4929
        peerIDKey := newSerializedKey(peerKey)
56✔
4930
        f.resMtx.Lock()
56✔
4931
        if _, ok := f.activeReservations[peerIDKey]; !ok {
105✔
4932
                f.activeReservations[peerIDKey] = make(pendingChannels)
49✔
4933
        }
49✔
4934

4935
        resCtx := &reservationWithCtx{
56✔
4936
                chanAmt:           capacity,
56✔
4937
                forwardingPolicy:  *forwardingPolicy,
56✔
4938
                remoteCsvDelay:    remoteCsvDelay,
56✔
4939
                remoteMinHtlc:     minHtlcIn,
56✔
4940
                remoteMaxValue:    maxValue,
56✔
4941
                remoteMaxHtlcs:    maxHtlcs,
56✔
4942
                remoteChanReserve: chanReserve,
56✔
4943
                maxLocalCsv:       maxCSV,
56✔
4944
                channelType:       chanType,
56✔
4945
                reservation:       reservation,
56✔
4946
                peer:              msg.Peer,
56✔
4947
                updates:           msg.Updates,
56✔
4948
                err:               msg.Err,
56✔
4949
        }
56✔
4950
        f.activeReservations[peerIDKey][chanID] = resCtx
56✔
4951
        f.resMtx.Unlock()
56✔
4952

56✔
4953
        // Update the timestamp once the InitFundingMsg has been handled.
56✔
4954
        defer resCtx.updateTimestamp()
56✔
4955

56✔
4956
        // Check the sanity of the selected channel constraints.
56✔
4957
        bounds := &channeldb.ChannelStateBounds{
56✔
4958
                ChanReserve:      chanReserve,
56✔
4959
                MaxPendingAmount: maxValue,
56✔
4960
                MinHTLC:          minHtlcIn,
56✔
4961
                MaxAcceptedHtlcs: maxHtlcs,
56✔
4962
        }
56✔
4963
        commitParams := &channeldb.CommitmentParams{
56✔
4964
                DustLimit: ourDustLimit,
56✔
4965
                CsvDelay:  remoteCsvDelay,
56✔
4966
        }
56✔
4967
        err = lnwallet.VerifyConstraints(
56✔
4968
                bounds, commitParams, resCtx.maxLocalCsv, capacity,
56✔
4969
        )
56✔
4970
        if err != nil {
58✔
4971
                _, reserveErr := f.cancelReservationCtx(peerKey, chanID, false)
2✔
4972
                if reserveErr != nil {
2✔
4973
                        log.Errorf("unable to cancel reservation: %v",
×
4974
                                reserveErr)
×
4975
                }
×
4976

4977
                msg.Err <- err
2✔
4978
                return
2✔
4979
        }
4980

4981
        // When opening a script enforced channel lease, include the required
4982
        // expiry TLV record in our proposal.
4983
        var leaseExpiry *lnwire.LeaseExpiry
54✔
4984
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
54✔
UNCOV
4985
                leaseExpiry = new(lnwire.LeaseExpiry)
×
UNCOV
4986
                *leaseExpiry = lnwire.LeaseExpiry(reservation.LeaseExpiry())
×
UNCOV
4987
        }
×
4988

4989
        log.Infof("Starting funding workflow with %v for pending_id(%x), "+
54✔
4990
                "committype=%v", msg.Peer.Address(), chanID, commitType)
54✔
4991

54✔
4992
        reservation.SetState(lnwallet.SentOpenChannel)
54✔
4993

54✔
4994
        fundingOpen := lnwire.OpenChannel{
54✔
4995
                ChainHash:             *f.cfg.Wallet.Cfg.NetParams.GenesisHash,
54✔
4996
                PendingChannelID:      chanID,
54✔
4997
                FundingAmount:         capacity,
54✔
4998
                PushAmount:            msg.PushAmt,
54✔
4999
                DustLimit:             ourDustLimit,
54✔
5000
                MaxValueInFlight:      maxValue,
54✔
5001
                ChannelReserve:        chanReserve,
54✔
5002
                HtlcMinimum:           minHtlcIn,
54✔
5003
                FeePerKiloWeight:      uint32(commitFeePerKw),
54✔
5004
                CsvDelay:              remoteCsvDelay,
54✔
5005
                MaxAcceptedHTLCs:      maxHtlcs,
54✔
5006
                FundingKey:            ourContribution.MultiSigKey.PubKey,
54✔
5007
                RevocationPoint:       ourContribution.RevocationBasePoint.PubKey,
54✔
5008
                PaymentPoint:          ourContribution.PaymentBasePoint.PubKey,
54✔
5009
                HtlcPoint:             ourContribution.HtlcBasePoint.PubKey,
54✔
5010
                DelayedPaymentPoint:   ourContribution.DelayBasePoint.PubKey,
54✔
5011
                FirstCommitmentPoint:  ourContribution.FirstCommitmentPoint,
54✔
5012
                ChannelFlags:          channelFlags,
54✔
5013
                UpfrontShutdownScript: shutdown,
54✔
5014
                ChannelType:           chanType,
54✔
5015
                LeaseExpiry:           leaseExpiry,
54✔
5016
        }
54✔
5017

54✔
5018
        if commitType.IsTaproot() {
56✔
5019
                fundingOpen.LocalNonce = lnwire.SomeMusig2Nonce(
2✔
5020
                        ourContribution.LocalNonce.PubNonce,
2✔
5021
                )
2✔
5022
        }
2✔
5023

5024
        if err := msg.Peer.SendMessage(true, &fundingOpen); err != nil {
54✔
5025
                e := fmt.Errorf("unable to send funding request message: %w",
×
5026
                        err)
×
5027
                log.Errorf(e.Error())
×
5028

×
5029
                // Since we were unable to send the initial message to the peer
×
5030
                // and start the funding flow, we'll cancel this reservation.
×
5031
                _, err := f.cancelReservationCtx(peerKey, chanID, false)
×
5032
                if err != nil {
×
5033
                        log.Errorf("unable to cancel reservation: %v", err)
×
5034
                }
×
5035

5036
                msg.Err <- e
×
5037
                return
×
5038
        }
5039
}
5040

5041
// handleWarningMsg processes the warning which was received from remote peer.
5042
func (f *Manager) handleWarningMsg(peer lnpeer.Peer, msg *lnwire.Warning) {
42✔
5043
        log.Warnf("received warning message from peer %x: %v",
42✔
5044
                peer.IdentityKey().SerializeCompressed(), msg.Warning())
42✔
5045
}
42✔
5046

5047
// handleErrorMsg processes the error which was received from remote peer,
5048
// depending on the type of error we should do different clean up steps and
5049
// inform the user about it.
UNCOV
5050
func (f *Manager) handleErrorMsg(peer lnpeer.Peer, msg *lnwire.Error) {
×
UNCOV
5051
        chanID := msg.ChanID
×
UNCOV
5052
        peerKey := peer.IdentityKey()
×
UNCOV
5053

×
UNCOV
5054
        // First, we'll attempt to retrieve and cancel the funding workflow
×
UNCOV
5055
        // that this error was tied to. If we're unable to do so, then we'll
×
UNCOV
5056
        // exit early as this was an unwarranted error.
×
UNCOV
5057
        resCtx, err := f.cancelReservationCtx(peerKey, chanID, true)
×
UNCOV
5058
        if err != nil {
×
5059
                log.Warnf("Received error for non-existent funding "+
×
5060
                        "flow: %v (%v)", err, msg.Error())
×
5061
                return
×
5062
        }
×
5063

5064
        // If we did indeed find the funding workflow, then we'll return the
5065
        // error back to the caller (if any), and cancel the workflow itself.
UNCOV
5066
        fundingErr := fmt.Errorf("received funding error from %x: %v",
×
UNCOV
5067
                peerKey.SerializeCompressed(), msg.Error(),
×
UNCOV
5068
        )
×
UNCOV
5069
        log.Errorf(fundingErr.Error())
×
UNCOV
5070

×
UNCOV
5071
        // If this was a PSBT funding flow, the remote likely timed out because
×
UNCOV
5072
        // we waited too long. Return a nice error message to the user in that
×
UNCOV
5073
        // case so the user knows what's the problem.
×
UNCOV
5074
        if resCtx.reservation.IsPsbt() {
×
UNCOV
5075
                fundingErr = fmt.Errorf("%w: %v", chanfunding.ErrRemoteCanceled,
×
UNCOV
5076
                        fundingErr)
×
UNCOV
5077
        }
×
5078

UNCOV
5079
        resCtx.err <- fundingErr
×
5080
}
5081

5082
// pruneZombieReservations loops through all pending reservations and fails the
5083
// funding flow for any reservations that have not been updated since the
5084
// ReservationTimeout and are not locked waiting for the funding transaction.
5085
func (f *Manager) pruneZombieReservations() {
3✔
5086
        zombieReservations := make(pendingChannels)
3✔
5087

3✔
5088
        f.resMtx.RLock()
3✔
5089
        for _, pendingReservations := range f.activeReservations {
6✔
5090
                for pendingChanID, resCtx := range pendingReservations {
6✔
5091
                        if resCtx.isLocked() {
3✔
5092
                                continue
×
5093
                        }
5094

5095
                        // We don't want to expire PSBT funding reservations.
5096
                        // These reservations are always initiated by us and the
5097
                        // remote peer is likely going to cancel them after some
5098
                        // idle time anyway. So no need for us to also prune
5099
                        // them.
5100
                        sinceLastUpdate := time.Since(resCtx.lastUpdated)
3✔
5101
                        isExpired := sinceLastUpdate > f.cfg.ReservationTimeout
3✔
5102
                        if !resCtx.reservation.IsPsbt() && isExpired {
6✔
5103
                                zombieReservations[pendingChanID] = resCtx
3✔
5104
                        }
3✔
5105
                }
5106
        }
5107
        f.resMtx.RUnlock()
3✔
5108

3✔
5109
        for pendingChanID, resCtx := range zombieReservations {
6✔
5110
                err := fmt.Errorf("reservation timed out waiting for peer "+
3✔
5111
                        "(peer_id:%x, chan_id:%x)",
3✔
5112
                        resCtx.peer.IdentityKey().SerializeCompressed(),
3✔
5113
                        pendingChanID[:])
3✔
5114
                log.Warnf(err.Error())
3✔
5115

3✔
5116
                chanID := lnwire.NewChanIDFromOutPoint(
3✔
5117
                        *resCtx.reservation.FundingOutpoint(),
3✔
5118
                )
3✔
5119

3✔
5120
                // Create channel identifier and set the channel ID.
3✔
5121
                cid := newChanIdentifier(pendingChanID)
3✔
5122
                cid.setChanID(chanID)
3✔
5123

3✔
5124
                f.failFundingFlow(resCtx.peer, cid, err)
3✔
5125
        }
3✔
5126
}
5127

5128
// cancelReservationCtx does all needed work in order to securely cancel the
5129
// reservation.
5130
func (f *Manager) cancelReservationCtx(peerKey *btcec.PublicKey,
5131
        pendingChanID PendingChanID,
5132
        byRemote bool) (*reservationWithCtx, error) {
24✔
5133

24✔
5134
        log.Infof("Cancelling funding reservation for node_key=%x, "+
24✔
5135
                "chan_id=%x", peerKey.SerializeCompressed(), pendingChanID[:])
24✔
5136

24✔
5137
        peerIDKey := newSerializedKey(peerKey)
24✔
5138
        f.resMtx.Lock()
24✔
5139
        defer f.resMtx.Unlock()
24✔
5140

24✔
5141
        nodeReservations, ok := f.activeReservations[peerIDKey]
24✔
5142
        if !ok {
32✔
5143
                // No reservations for this node.
8✔
5144
                return nil, errors.Errorf("no active reservations for peer(%x)",
8✔
5145
                        peerIDKey[:])
8✔
5146
        }
8✔
5147

5148
        ctx, ok := nodeReservations[pendingChanID]
16✔
5149
        if !ok {
18✔
5150
                return nil, errors.Errorf("unknown channel (id: %x) for "+
2✔
5151
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
2✔
5152
        }
2✔
5153

5154
        // If the reservation was a PSBT funding flow and it was canceled by the
5155
        // remote peer, then we need to thread through a different error message
5156
        // to the subroutine that's waiting for the user input so it can return
5157
        // a nice error message to the user.
5158
        if ctx.reservation.IsPsbt() && byRemote {
14✔
UNCOV
5159
                ctx.reservation.RemoteCanceled()
×
UNCOV
5160
        }
×
5161

5162
        if err := ctx.reservation.Cancel(); err != nil {
14✔
5163
                return nil, errors.Errorf("unable to cancel reservation: %v",
×
5164
                        err)
×
5165
        }
×
5166

5167
        delete(nodeReservations, pendingChanID)
14✔
5168

14✔
5169
        // If this was the last active reservation for this peer, delete the
14✔
5170
        // peer's entry altogether.
14✔
5171
        if len(nodeReservations) == 0 {
28✔
5172
                delete(f.activeReservations, peerIDKey)
14✔
5173
        }
14✔
5174
        return ctx, nil
14✔
5175
}
5176

5177
// deleteReservationCtx deletes the reservation uniquely identified by the
5178
// target public key of the peer, and the specified pending channel ID.
5179
func (f *Manager) deleteReservationCtx(peerKey *btcec.PublicKey,
5180
        pendingChanID PendingChanID) {
54✔
5181

54✔
5182
        peerIDKey := newSerializedKey(peerKey)
54✔
5183
        f.resMtx.Lock()
54✔
5184
        defer f.resMtx.Unlock()
54✔
5185

54✔
5186
        nodeReservations, ok := f.activeReservations[peerIDKey]
54✔
5187
        if !ok {
54✔
5188
                // No reservations for this node.
×
5189
                return
×
5190
        }
×
5191
        delete(nodeReservations, pendingChanID)
54✔
5192

54✔
5193
        // If this was the last active reservation for this peer, delete the
54✔
5194
        // peer's entry altogether.
54✔
5195
        if len(nodeReservations) == 0 {
101✔
5196
                delete(f.activeReservations, peerIDKey)
47✔
5197
        }
47✔
5198
}
5199

5200
// getReservationCtx returns the reservation context for a particular pending
5201
// channel ID for a target peer.
5202
func (f *Manager) getReservationCtx(peerKey *btcec.PublicKey,
5203
        pendingChanID PendingChanID) (*reservationWithCtx, error) {
88✔
5204

88✔
5205
        peerIDKey := newSerializedKey(peerKey)
88✔
5206
        f.resMtx.RLock()
88✔
5207
        resCtx, ok := f.activeReservations[peerIDKey][pendingChanID]
88✔
5208
        f.resMtx.RUnlock()
88✔
5209

88✔
5210
        if !ok {
88✔
UNCOV
5211
                return nil, errors.Errorf("unknown channel (id: %x) for "+
×
UNCOV
5212
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
×
UNCOV
5213
        }
×
5214

5215
        return resCtx, nil
88✔
5216
}
5217

5218
// IsPendingChannel returns a boolean indicating whether the channel identified
5219
// by the pendingChanID and given peer is pending, meaning it is in the process
5220
// of being funded. After the funding transaction has been confirmed, the
5221
// channel will receive a new, permanent channel ID, and will no longer be
5222
// considered pending.
5223
func (f *Manager) IsPendingChannel(pendingChanID PendingChanID,
UNCOV
5224
        peer lnpeer.Peer) bool {
×
UNCOV
5225

×
UNCOV
5226
        peerIDKey := newSerializedKey(peer.IdentityKey())
×
UNCOV
5227
        f.resMtx.RLock()
×
UNCOV
5228
        _, ok := f.activeReservations[peerIDKey][pendingChanID]
×
UNCOV
5229
        f.resMtx.RUnlock()
×
UNCOV
5230

×
UNCOV
5231
        return ok
×
UNCOV
5232
}
×
5233

5234
func copyPubKey(pub *btcec.PublicKey) *btcec.PublicKey {
375✔
5235
        var tmp btcec.JacobianPoint
375✔
5236
        pub.AsJacobian(&tmp)
375✔
5237
        tmp.ToAffine()
375✔
5238
        return btcec.NewPublicKey(&tmp.X, &tmp.Y)
375✔
5239
}
375✔
5240

5241
// defaultForwardingPolicy returns the default forwarding policy based on the
5242
// default routing policy and our local channel constraints.
5243
func (f *Manager) defaultForwardingPolicy(
5244
        bounds channeldb.ChannelStateBounds) *models.ForwardingPolicy {
102✔
5245

102✔
5246
        return &models.ForwardingPolicy{
102✔
5247
                MinHTLCOut:    bounds.MinHTLC,
102✔
5248
                MaxHTLC:       bounds.MaxPendingAmount,
102✔
5249
                BaseFee:       f.cfg.DefaultRoutingPolicy.BaseFee,
102✔
5250
                FeeRate:       f.cfg.DefaultRoutingPolicy.FeeRate,
102✔
5251
                TimeLockDelta: f.cfg.DefaultRoutingPolicy.TimeLockDelta,
102✔
5252
        }
102✔
5253
}
102✔
5254

5255
// saveInitialForwardingPolicy saves the forwarding policy for the provided
5256
// chanPoint in the channelOpeningStateBucket.
5257
func (f *Manager) saveInitialForwardingPolicy(chanID lnwire.ChannelID,
5258
        forwardingPolicy *models.ForwardingPolicy) error {
67✔
5259

67✔
5260
        return f.cfg.ChannelDB.SaveInitialForwardingPolicy(
67✔
5261
                chanID, forwardingPolicy,
67✔
5262
        )
67✔
5263
}
67✔
5264

5265
// getInitialForwardingPolicy fetches the initial forwarding policy for a given
5266
// channel id from the database which will be applied during the channel
5267
// announcement phase.
5268
func (f *Manager) getInitialForwardingPolicy(
5269
        chanID lnwire.ChannelID) (*models.ForwardingPolicy, error) {
94✔
5270

94✔
5271
        return f.cfg.ChannelDB.GetInitialForwardingPolicy(chanID)
94✔
5272
}
94✔
5273

5274
// deleteInitialForwardingPolicy removes channel fees for this chanID from
5275
// the database.
5276
func (f *Manager) deleteInitialForwardingPolicy(chanID lnwire.ChannelID) error {
24✔
5277
        return f.cfg.ChannelDB.DeleteInitialForwardingPolicy(chanID)
24✔
5278
}
24✔
5279

5280
// saveChannelOpeningState saves the channelOpeningState for the provided
5281
// chanPoint to the channelOpeningStateBucket.
5282
func (f *Manager) saveChannelOpeningState(chanPoint *wire.OutPoint,
5283
        state channelOpeningState, shortChanID *lnwire.ShortChannelID) error {
92✔
5284

92✔
5285
        var outpointBytes bytes.Buffer
92✔
5286
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
92✔
5287
                return err
×
5288
        }
×
5289

5290
        // Save state and the uint64 representation of the shortChanID
5291
        // for later use.
5292
        scratch := make([]byte, 10)
92✔
5293
        byteOrder.PutUint16(scratch[:2], uint16(state))
92✔
5294
        byteOrder.PutUint64(scratch[2:], shortChanID.ToUint64())
92✔
5295

92✔
5296
        return f.cfg.ChannelDB.SaveChannelOpeningState(
92✔
5297
                outpointBytes.Bytes(), scratch,
92✔
5298
        )
92✔
5299
}
5300

5301
// getChannelOpeningState fetches the channelOpeningState for the provided
5302
// chanPoint from the database, or returns ErrChannelNotFound if the channel
5303
// is not found.
5304
func (f *Manager) getChannelOpeningState(chanPoint *wire.OutPoint) (
5305
        channelOpeningState, *lnwire.ShortChannelID, error) {
252✔
5306

252✔
5307
        var outpointBytes bytes.Buffer
252✔
5308
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
252✔
5309
                return 0, nil, err
×
5310
        }
×
5311

5312
        value, err := f.cfg.ChannelDB.GetChannelOpeningState(
252✔
5313
                outpointBytes.Bytes(),
252✔
5314
        )
252✔
5315
        if err != nil {
299✔
5316
                return 0, nil, err
47✔
5317
        }
47✔
5318

5319
        state := channelOpeningState(byteOrder.Uint16(value[:2]))
205✔
5320
        shortChanID := lnwire.NewShortChanIDFromInt(byteOrder.Uint64(value[2:]))
205✔
5321
        return state, &shortChanID, nil
205✔
5322
}
5323

5324
// deleteChannelOpeningState removes any state for chanPoint from the database.
5325
func (f *Manager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error {
24✔
5326
        var outpointBytes bytes.Buffer
24✔
5327
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
24✔
5328
                return err
×
5329
        }
×
5330

5331
        return f.cfg.ChannelDB.DeleteChannelOpeningState(
24✔
5332
                outpointBytes.Bytes(),
24✔
5333
        )
24✔
5334
}
5335

5336
// selectShutdownScript selects the shutdown script we should send to the peer.
5337
// If we can use taproot, then we prefer that, otherwise we'll use a p2wkh
5338
// script.
5339
func (f *Manager) selectShutdownScript(taprootOK bool,
5340
) (lnwire.DeliveryAddress, error) {
×
5341

×
5342
        addrType := lnwallet.WitnessPubKey
×
5343
        if taprootOK {
×
5344
                addrType = lnwallet.TaprootPubkey
×
5345
        }
×
5346

5347
        addr, err := f.cfg.Wallet.NewAddress(
×
5348
                addrType, false, lnwallet.DefaultAccountName,
×
5349
        )
×
5350
        if err != nil {
×
5351
                return nil, err
×
5352
        }
×
5353

5354
        return txscript.PayToAddrScript(addr)
×
5355
}
5356

5357
// waitForPeerOnline blocks until the peer specified by peerPubkey comes online
5358
// and then returns the online peer.
5359
func (f *Manager) waitForPeerOnline(peerPubkey *btcec.PublicKey) (lnpeer.Peer,
5360
        error) {
104✔
5361

104✔
5362
        peerChan := make(chan lnpeer.Peer, 1)
104✔
5363

104✔
5364
        var peerKey [33]byte
104✔
5365
        copy(peerKey[:], peerPubkey.SerializeCompressed())
104✔
5366

104✔
5367
        f.cfg.NotifyWhenOnline(peerKey, peerChan)
104✔
5368

104✔
5369
        var peer lnpeer.Peer
104✔
5370
        select {
104✔
5371
        case peer = <-peerChan:
103✔
5372
        case <-f.quit:
1✔
5373
                return peer, ErrFundingManagerShuttingDown
1✔
5374
        }
5375
        return peer, nil
103✔
5376
}
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