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

lightningnetwork / lnd / 11216766535

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

Pull #9148

github

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

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

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 hits per line

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

67.94
/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/channeldb/models"
26
        "github.com/lightningnetwork/lnd/discovery"
27
        "github.com/lightningnetwork/lnd/fn"
28
        "github.com/lightningnetwork/lnd/graph"
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 {
378✔
331
        var s serializedPubKey
378✔
332
        copy(s[:], pubKey.SerializeCompressed())
378✔
333
        return s
378✔
334
}
378✔
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

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

576
        // cfg is a copy of the configuration struct that the FundingManager
577
        // was initialized with.
578
        cfg *Config
579

580
        // chanIDKey is a cryptographically random key that's used to generate
581
        // temporary channel ID's.
582
        chanIDKey [32]byte
583

584
        // chanIDNonce is a nonce that's incremented for each new funding
585
        // reservation created.
586
        chanIDNonce atomic.Uint64
587

588
        // nonceMtx is a mutex that guards the pendingMusigNonces.
589
        nonceMtx sync.RWMutex
590

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

602
        // activeReservations is a map which houses the state of all pending
603
        // funding workflows.
604
        activeReservations map[serializedPubKey]pendingChannels
605

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

613
        // resMtx guards both of the maps above to ensure that all access is
614
        // goroutine safe.
615
        resMtx sync.RWMutex
616

617
        // fundingMsgs is a channel that relays fundingMsg structs from
618
        // external sub-systems using the ProcessFundingMsg call.
619
        fundingMsgs chan *fundingMsg
620

621
        // fundingRequests is a channel used to receive channel initiation
622
        // requests from a local subsystem within the daemon.
623
        fundingRequests chan *InitFundingMsg
624

625
        localDiscoverySignals *lnutils.SyncMap[lnwire.ChannelID, chan struct{}]
626

627
        handleChannelReadyBarriers *lnutils.SyncMap[lnwire.ChannelID, struct{}]
628

629
        quit chan struct{}
630
        wg   sync.WaitGroup
631
}
632

633
// channelOpeningState represents the different states a channel can be in
634
// between the funding transaction has been confirmed and the channel is
635
// announced to the network and ready to be used.
636
type channelOpeningState uint8
637

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

644
        // channelReadySent is the opening state of a channel if the
645
        // channelReady message has successfully been sent to the other peer,
646
        // but we still haven't announced the channel to the network.
647
        channelReadySent
648

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

656
func (c channelOpeningState) String() string {
657
        switch c {
658
        case markedOpen:
659
                return "markedOpen"
UNCOV
660
        case channelReadySent:
×
UNCOV
661
                return "channelReadySent"
×
UNCOV
662
        case addedToGraph:
×
UNCOV
663
                return "addedToGraph"
×
664
        default:
×
665
                return "unknown"
×
UNCOV
666
        }
×
UNCOV
667
}
×
UNCOV
668

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

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

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

107✔
723
        for _, channel := range allChannels {
107✔
UNCOV
724
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
×
UNCOV
725

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

10✔
735
                        f.localDiscoverySignals.Store(
1✔
736
                                chanID, make(chan struct{}),
1✔
737
                        )
1✔
738

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

1✔
747
                                f.rebroadcastFundingTx(channel)
1✔
748
                        }
1✔
749
                } else if channel.ChanType.IsSingleFunder() &&
2✔
750
                        channel.ChanType.HasFundingTx() &&
1✔
751
                        channel.IsZeroConf() && channel.IsInitiator &&
1✔
752
                        !channel.ZeroConfConfirmed() {
1✔
753

8✔
754
                        // Rebroadcast the funding transaction for unconfirmed
8✔
755
                        // zero-conf channels if we have the funding tx and are
8✔
756
                        // also the initiator.
10✔
757
                        f.rebroadcastFundingTx(channel)
2✔
758
                }
2✔
759

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

768
        f.wg.Add(1) // TODO(roasbeef): tune
9✔
769
        go f.reservationCoordinator()
9✔
770

771
        return nil
772
}
107✔
773

107✔
774
// Stop signals all helper goroutines to execute a graceful shutdown. This
107✔
775
// method will block until all goroutines have exited.
107✔
776
func (f *Manager) Stop() error {
777
        f.stopped.Do(func() {
778
                log.Info("Funding manager shutting down...")
779
                defer log.Debug("Funding manager shutdown complete")
780

104✔
781
                close(f.quit)
207✔
782
                f.wg.Wait()
103✔
783
        })
103✔
784

103✔
785
        return nil
103✔
786
}
103✔
787

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

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

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

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

×
UNCOV
818
// PendingChanID is a type that represents a pending channel ID. This might be
×
UNCOV
819
// selected by the caller, but if not, will be automatically selected.
×
820
type PendingChanID = [32]byte
821

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

828
        var nonceBytes [8]byte
56✔
829
        binary.LittleEndian.PutUint64(nonceBytes[:], nextNonce)
56✔
830

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

56✔
841
        return nextChanID
56✔
842
}
56✔
843

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

850
        f.resMtx.Lock()
UNCOV
851
        defer f.resMtx.Unlock()
×
UNCOV
852

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

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

×
871
                resCtx.err <- fmt.Errorf("peer disconnected")
×
872
                delete(nodeReservations, pendingID)
×
UNCOV
873
        }
×
874

UNCOV
875
        // Finally, we'll delete the node itself from the set of reservations.
×
876
        delete(f.activeReservations, nodePub)
×
877
}
878

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

890
        // chanID is the channel ID created by the funder once the
891
        // `accept_channel` message is received. For fundee, it's received from
892
        // the `funding_created` message.
893
        chanID lnwire.ChannelID
894

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

903
// newChanIdentifier creates a new chanIdentifier.
904
func newChanIdentifier(tempChanID lnwire.ChannelID) *chanIdentifier {
905
        return &chanIdentifier{
906
                tempChanID: tempChanID,
907
        }
908
}
144✔
909

144✔
910
// setChanID updates the `chanIdentifier` with the active channel ID.
144✔
911
func (c *chanIdentifier) setChanID(chanID lnwire.ChannelID) {
144✔
912
        c.chanID = chanID
144✔
913
        c.chanIDSet = true
914
}
915

88✔
916
// hasChanID returns true if the active channel ID has been set.
88✔
917
func (c *chanIdentifier) hasChanID() bool {
88✔
918
        return c.chanIDSet
88✔
919
}
920

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

931
        log.Debugf("Failing funding flow for pending_id=%v: %v",
932
                cid.tempChanID, fundingErr)
933

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

×
UNCOV
947
        ctx, err := f.cancelReservationCtx(
×
UNCOV
948
                peer.IdentityKey(), cid.tempChanID, false,
×
949
        )
950
        if err != nil {
951
                log.Errorf("unable to cancel reservation: %v", err)
21✔
952
        }
21✔
953

21✔
954
        // In case the case where the reservation existed, send the funding
30✔
955
        // error on the error channel.
9✔
956
        if ctx != nil {
9✔
957
                ctx.err <- fundingErr
958
        }
959

960
        // We only send the exact error if it is part of out whitelisted set of
33✔
961
        // errors (lnwire.FundingError or lnwallet.ReservationError).
12✔
962
        var msg lnwire.ErrorData
12✔
963
        switch e := fundingErr.(type) {
964
        // Let the actual error message be sent to the remote for the
965
        // whitelisted types.
966
        case lnwallet.ReservationError:
21✔
967
                msg = lnwire.ErrorData(e.Error())
21✔
968
        case lnwire.FundingError:
969
                msg = lnwire.ErrorData(e.Error())
970
        case chanacceptor.ChanAcceptError:
5✔
971
                msg = lnwire.ErrorData(e.Error())
5✔
972

4✔
973
        // For all other error types we just send a generic error.
4✔
UNCOV
974
        default:
×
UNCOV
975
                msg = lnwire.ErrorData("funding failed due to internal error")
×
976
        }
977

978
        errMsg := &lnwire.Error{
12✔
979
                ChanID: cid.tempChanID,
12✔
980
                Data:   msg,
981
        }
982

21✔
983
        log.Debugf("Sending funding error to peer (%x): %v",
21✔
984
                peer.IdentityKey().SerializeCompressed(), spew.Sdump(errMsg))
21✔
985
        if err := peer.SendMessage(false, errMsg); err != nil {
21✔
986
                log.Errorf("unable to send error message to peer %v", err)
21✔
987
        }
21✔
988
}
21✔
989

21✔
UNCOV
990
// sendWarning sends a new warning message to the target peer, targeting the
×
UNCOV
991
// specified cid with the passed funding error.
×
992
func (f *Manager) sendWarning(peer lnpeer.Peer, cid *chanIdentifier,
993
        fundingErr error) {
994

995
        msg := fundingErr.Error()
996

997
        errMsg := &lnwire.Warning{
×
998
                ChanID: cid.tempChanID,
×
999
                Data:   lnwire.WarningData(msg),
×
1000
        }
×
1001

×
1002
        log.Debugf("Sending funding warning to peer (%x): %v",
×
1003
                peer.IdentityKey().SerializeCompressed(),
×
1004
                spew.Sdump(errMsg),
×
1005
        )
×
1006

×
1007
        if err := peer.SendMessage(false, errMsg); err != nil {
×
1008
                log.Errorf("unable to send error message to peer %v", err)
×
1009
        }
×
UNCOV
1010
}
×
UNCOV
1011

×
UNCOV
1012
// reservationCoordinator is the primary goroutine tasked with progressing the
×
UNCOV
1013
// funding workflow between the wallet, and any outside peers or local callers.
×
1014
//
1015
// NOTE: This MUST be run as a goroutine.
1016
func (f *Manager) reservationCoordinator() {
1017
        defer f.wg.Done()
1018

1019
        zombieSweepTicker := time.NewTicker(f.cfg.ZombieSweeperInterval)
1020
        defer zombieSweepTicker.Stop()
107✔
1021

107✔
1022
        for {
107✔
1023
                select {
107✔
1024
                case fmsg := <-f.fundingMsgs:
107✔
1025
                        switch msg := fmsg.msg.(type) {
107✔
1026
                        case *lnwire.OpenChannel:
479✔
1027
                                f.fundeeProcessOpenChannel(fmsg.peer, msg)
372✔
1028

209✔
1029
                        case *lnwire.AcceptChannel:
209✔
1030
                                f.funderProcessAcceptChannel(fmsg.peer, msg)
53✔
1031

53✔
1032
                        case *lnwire.FundingCreated:
1033
                                f.fundeeProcessFundingCreated(fmsg.peer, msg)
32✔
1034

32✔
1035
                        case *lnwire.FundingSigned:
1036
                                f.funderProcessFundingSigned(fmsg.peer, msg)
27✔
1037

27✔
1038
                        case *lnwire.ChannelReady:
1039
                                f.wg.Add(1)
27✔
1040
                                go f.handleChannelReady(fmsg.peer, msg)
27✔
1041

1042
                        case *lnwire.Warning:
28✔
1043
                                f.handleWarningMsg(fmsg.peer, msg)
28✔
1044

28✔
1045
                        case *lnwire.Error:
1046
                                f.handleErrorMsg(fmsg.peer, msg)
42✔
1047
                        }
42✔
1048
                case req := <-f.fundingRequests:
UNCOV
1049
                        f.handleInitFundingMsg(req)
×
UNCOV
1050

×
1051
                case <-zombieSweepTicker.C:
1052
                        f.pruneZombieReservations()
56✔
1053

56✔
1054
                case <-f.quit:
UNCOV
1055
                        return
×
UNCOV
1056
                }
×
1057
        }
1058
}
103✔
1059

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

1072
        defer f.wg.Done()
1073

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

21✔
1086
        var chanOpts []lnwallet.ChannelOpt
21✔
1087
        f.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
21✔
1088
                chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
1089
        })
1090
        f.cfg.AuxSigner.WhenSome(func(s lnwallet.AuxSigner) {
42✔
1091
                chanOpts = append(chanOpts, lnwallet.WithAuxSigner(s))
84✔
1092
        })
42✔
1093

42✔
1094
        // We create the state-machine object which wraps the database state.
84✔
1095
        lnChannel, err := lnwallet.NewLightningChannel(
42✔
1096
                nil, channel, nil, chanOpts...,
42✔
1097
        )
42✔
UNCOV
1098
        if err != nil {
×
1099
                log.Errorf("Unable to create LightningChannel(%v): %v",
×
1100
                        channel.FundingOutpoint, err)
1101
                return
1102
        }
42✔
1103

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

25✔
1126
                // If we did find the channel in the opening state database, we
148✔
UNCOV
1127
                // have seen the funding transaction being confirmed, but there
×
UNCOV
1128
                // are still steps left of the setup procedure. We continue the
×
UNCOV
1129
                // procedure where we left off.
×
UNCOV
1130
                err = f.stateStep(
×
UNCOV
1131
                        channel, lnChannel, shortChanID, pendingChanID,
×
1132
                        channelState, updateChan,
1133
                )
1134
                if err != nil {
1135
                        log.Errorf("Unable to advance state(%v): %v",
1136
                                channel.FundingOutpoint, err)
1137
                        return
123✔
1138
                }
123✔
1139
        }
123✔
1140
}
123✔
1141

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

1152
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
1153
        log.Debugf("Channel(%v) with ShortChanID %v has opening state %v",
1154
                chanID, shortChanID, channelState)
1155

1156
        switch channelState {
1157
        // The funding transaction was confirmed, but we did not successfully
123✔
1158
        // send the channelReady message to the peer, so let's do that now.
123✔
1159
        case markedOpen:
123✔
1160
                err := f.sendChannelReady(channel, lnChannel)
123✔
1161
                if err != nil {
123✔
1162
                        return fmt.Errorf("failed sending channelReady: %w",
123✔
1163
                                err)
123✔
1164
                }
1165

1166
                // As the channelReady message is now sent to the peer, the
35✔
1167
                // channel is moved to the next state of the state machine. It
35✔
1168
                // will be moved to the last state (actually deleted from the
36✔
1169
                // database) after the channel is finally announced.
1✔
1170
                err = f.saveChannelOpeningState(
1✔
1171
                        &channel.FundingOutpoint, channelReadySent,
1✔
1172
                        shortChanID,
1173
                )
1174
                if err != nil {
1175
                        return fmt.Errorf("error setting channel state to"+
1176
                                " channelReadySent: %w", err)
1177
                }
34✔
1178

34✔
1179
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
34✔
1180
                        "sent ChannelReady", chanID, shortChanID)
34✔
1181

34✔
UNCOV
1182
                return nil
×
UNCOV
1183

×
UNCOV
1184
        // channelReady was sent to peer, but the channel was not added to the
×
1185
        // graph and the channel announcement was not sent.
1186
        case channelReadySent:
34✔
1187
                // We must wait until we've received the peer's channel_ready
34✔
1188
                // before sending a channel_update according to BOLT#07.
34✔
1189
                received, err := f.receivedChannelReady(
34✔
1190
                        channel.IdentityPub, chanID,
1191
                )
1192
                if err != nil {
1193
                        return fmt.Errorf("failed to check if channel_ready "+
60✔
1194
                                "was received: %v", err)
60✔
1195
                }
60✔
1196

60✔
1197
                if !received {
60✔
1198
                        // We haven't received ChannelReady, so we'll continue
60✔
1199
                        // to the next iteration of the loop after sleeping for
60✔
UNCOV
1200
                        // checkPeerChannelReadyInterval.
×
UNCOV
1201
                        select {
×
UNCOV
1202
                        case <-time.After(checkPeerChannelReadyInterval):
×
1203
                        case <-f.quit:
1204
                                return ErrFundingManagerShuttingDown
96✔
1205
                        }
36✔
1206

36✔
1207
                        return nil
36✔
1208
                }
36✔
1209

24✔
1210
                return f.handleChannelReadyReceived(
12✔
1211
                        channel, shortChanID, pendingChanID, updateChan,
12✔
1212
                )
1213

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

6✔
1227
                        // Update the local shortChanID variable such that
6✔
1228
                        // annAfterSixConfs uses the confirmed SCID.
6✔
1229
                        confirmedScid := channel.ZeroConfRealScid()
8✔
1230
                        shortChanID = &confirmedScid
2✔
1231
                }
2✔
1232

2✔
1233
                err := f.annAfterSixConfs(channel, shortChanID)
1234
                if err != nil {
1235
                        return fmt.Errorf("error sending channel "+
1236
                                "announcement: %v", err)
4✔
1237
                }
4✔
1238

1239
                // We delete the channel opening state from our internal
1240
                // database as the opening process has succeeded. We can do
26✔
1241
                // this because we assume the AuthenticatedGossiper queues the
28✔
1242
                // announcement messages, and persists them in case of a daemon
2✔
1243
                // shutdown.
2✔
1244
                err = f.deleteChannelOpeningState(&channel.FundingOutpoint)
2✔
1245
                if err != nil {
1246
                        return fmt.Errorf("error deleting channel state: %w",
1247
                                err)
1248
                }
1249

1250
                // After the fee parameters have been stored in the
1251
                // announcement we can delete them from the database. For
24✔
1252
                // private channels we do not announce the channel policy to
24✔
UNCOV
1253
                // the network but still need to delete them from the database.
×
UNCOV
1254
                err = f.deleteInitialForwardingPolicy(chanID)
×
UNCOV
1255
                if err != nil {
×
1256
                        log.Infof("Could not delete initial policy for chanId "+
1257
                                "%x", chanID)
1258
                }
1259

1260
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
1261
                        "announced", chanID, shortChanID)
24✔
1262

24✔
UNCOV
1263
                return nil
×
UNCOV
1264
        }
×
UNCOV
1265

×
1266
        return fmt.Errorf("undefined channelState: %v", channelState)
1267
}
24✔
1268

24✔
1269
// advancePendingChannelState waits for a pending channel's funding tx to
24✔
1270
// confirm, and marks it open in the database when that happens.
24✔
1271
func (f *Manager) advancePendingChannelState(channel *channeldb.OpenChannel,
1272
        pendingChanID PendingChanID) error {
UNCOV
1273

×
1274
        if channel.IsZeroConf() {
1275
                // Persist the alias to the alias database.
1276
                baseScid := channel.ShortChannelID
1277
                err := f.cfg.AliasManager.AddLocalAlias(
1278
                        baseScid, baseScid, true, false,
1279
                )
55✔
1280
                if err != nil {
55✔
1281
                        return fmt.Errorf("error adding local alias to "+
59✔
1282
                                "store: %v", err)
4✔
1283
                }
4✔
1284

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

4✔
1298
                // The ShortChannelID is already set since it's an alias, but
4✔
1299
                // we still need to mark the channel as no longer pending.
4✔
1300
                err = channel.MarkAsOpen(channel.ShortChannelID)
4✔
UNCOV
1301
                if err != nil {
×
1302
                        return fmt.Errorf("error setting zero-conf channel's "+
×
1303
                                "pending flag to false: %v", err)
×
1304
                }
1305

1306
                // Inform the ChannelNotifier that the channel has transitioned
1307
                // from pending open to open.
4✔
1308
                f.cfg.NotifyOpenChannelEvent(channel.FundingOutpoint)
4✔
UNCOV
1309

×
UNCOV
1310
                // Find and close the discoverySignal for this channel such
×
UNCOV
1311
                // that ChannelReady messages will be processed.
×
1312
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
1313
                discoverySignal, ok := f.localDiscoverySignals.Load(chanID)
1314
                if ok {
1315
                        close(discoverySignal)
4✔
1316
                }
4✔
1317

4✔
1318
                return nil
4✔
1319
        }
4✔
1320

4✔
1321
        confChannel, err := f.waitForFundingWithTimeout(channel)
8✔
1322
        if err == ErrConfirmationTimeout {
4✔
1323
                return f.fundingTimeout(channel, pendingChanID)
4✔
1324
        } else if err != nil {
1325
                return fmt.Errorf("error waiting for funding "+
4✔
1326
                        "confirmation for ChannelPoint(%v): %v",
1327
                        channel.FundingOutpoint, err)
1328
        }
51✔
1329

53✔
1330
        if blockchain.IsCoinBaseTx(confChannel.fundingTx) {
2✔
1331
                // If it's a coinbase transaction, we need to wait for it to
70✔
1332
                // mature. We wait out an additional MinAcceptDepth on top of
19✔
1333
                // the coinbase maturity as an extra margin of safety.
19✔
1334
                maturity := f.cfg.Wallet.Cfg.NetParams.CoinbaseMaturity
19✔
1335
                numCoinbaseConfs := uint32(maturity)
19✔
1336

1337
                if channel.NumConfsRequired > maturity {
32✔
1338
                        numCoinbaseConfs = uint32(channel.NumConfsRequired)
2✔
1339
                }
2✔
1340

2✔
1341
                txid := &channel.FundingOutpoint.Hash
2✔
1342
                fundingScript, err := makeFundingScript(channel)
2✔
1343
                if err != nil {
2✔
1344
                        log.Errorf("unable to create funding script for "+
2✔
1345
                                "ChannelPoint(%v): %v",
×
1346
                                channel.FundingOutpoint, err)
×
1347

1348
                        return err
2✔
1349
                }
2✔
1350

2✔
UNCOV
1351
                confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
×
UNCOV
1352
                        txid, fundingScript, numCoinbaseConfs,
×
UNCOV
1353
                        channel.BroadcastHeight(),
×
UNCOV
1354
                )
×
UNCOV
1355
                if err != nil {
×
1356
                        log.Errorf("Unable to register for confirmation of "+
×
1357
                                "ChannelPoint(%v): %v",
1358
                                channel.FundingOutpoint, err)
2✔
1359

2✔
1360
                        return err
2✔
1361
                }
2✔
1362

2✔
UNCOV
1363
                select {
×
UNCOV
1364
                case _, ok := <-confNtfn.Confirmed:
×
UNCOV
1365
                        if !ok {
×
1366
                                return fmt.Errorf("ChainNotifier shutting "+
×
1367
                                        "down, can't complete funding flow "+
×
1368
                                        "for ChannelPoint(%v)",
×
1369
                                        channel.FundingOutpoint)
1370
                        }
2✔
1371

2✔
1372
                case <-f.quit:
2✔
1373
                        return ErrFundingManagerShuttingDown
×
UNCOV
1374
                }
×
UNCOV
1375
        }
×
UNCOV
1376

×
UNCOV
1377
        // Success, funding transaction was confirmed.
×
1378
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
UNCOV
1379
        log.Debugf("ChannelID(%v) is now fully confirmed! "+
×
UNCOV
1380
                "(shortChanID=%v)", chanID, confChannel.shortChanID)
×
1381

1382
        err = f.handleFundingConfirmation(channel, confChannel)
1383
        if err != nil {
1384
                return fmt.Errorf("unable to handle funding "+
1385
                        "confirmation for ChannelPoint(%v): %v",
30✔
1386
                        channel.FundingOutpoint, err)
30✔
1387
        }
30✔
1388

30✔
1389
        return nil
30✔
1390
}
30✔
UNCOV
1391

×
UNCOV
1392
// ProcessFundingMsg sends a message to the internal fundingManager goroutine,
×
UNCOV
1393
// allowing it to handle the lnwire.Message.
×
UNCOV
1394
func (f *Manager) ProcessFundingMsg(msg lnwire.Message, peer lnpeer.Peer) {
×
1395
        select {
1396
        case f.fundingMsgs <- &fundingMsg{msg, peer}:
30✔
1397
        case <-f.quit:
1398
                return
1399
        }
1400
}
1401

210✔
1402
// fundeeProcessOpenChannel creates an initial 'ChannelReservation' within the
210✔
1403
// wallet, then responds to the source peer with an accept channel message
210✔
UNCOV
1404
// progressing the funding workflow.
×
UNCOV
1405
//
×
1406
// TODO(roasbeef): add error chan to all, let channelManager handle
1407
// error+propagate.
1408
//
1409
//nolint:funlen
1410
func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
1411
        msg *lnwire.OpenChannel) {
1412

1413
        // Check number of pending channels to be smaller than maximum allowed
1414
        // number and send ErrorGeneric to remote peer if condition is
1415
        // violated.
1416
        peerPubKey := peer.IdentityKey()
1417
        peerIDKey := newSerializedKey(peerPubKey)
1418

53✔
1419
        amt := msg.FundingAmount
53✔
1420

53✔
1421
        // We get all pending channels for this peer. This is the list of the
53✔
1422
        // active reservations and the channels pending open in the database.
53✔
1423
        f.resMtx.RLock()
53✔
1424
        reservations := f.activeReservations[peerIDKey]
53✔
1425

53✔
1426
        // We don't count reservations that were created from a canned funding
53✔
1427
        // shim. The user has registered the shim and therefore expects this
53✔
1428
        // channel to arrive.
53✔
1429
        numPending := 0
53✔
1430
        for _, res := range reservations {
53✔
1431
                if !res.reservation.IsCannedShim() {
53✔
1432
                        numPending++
53✔
1433
                }
53✔
1434
        }
53✔
1435
        f.resMtx.RUnlock()
53✔
1436

53✔
1437
        // Create the channel identifier.
65✔
1438
        cid := newChanIdentifier(msg.PendingChannelID)
24✔
1439

12✔
1440
        // Also count the channels that are already pending. There we don't know
12✔
1441
        // the underlying intent anymore, unfortunately.
1442
        channels, err := f.cfg.ChannelDB.FetchOpenChannels(peerPubKey)
53✔
1443
        if err != nil {
53✔
1444
                f.failFundingFlow(peer, cid, err)
53✔
1445
                return
53✔
1446
        }
53✔
1447

53✔
1448
        for _, c := range channels {
53✔
1449
                // Pending channels that have a non-zero thaw height were also
53✔
1450
                // created through a canned funding shim. Those also don't
53✔
UNCOV
1451
                // count towards the DoS protection limit.
×
UNCOV
1452
                //
×
UNCOV
1453
                // TODO(guggero): Properly store the funding type (wallet, shim,
×
1454
                // PSBT) on the channel so we don't need to use the thaw height.
1455
                if c.IsPending && c.ThawHeight == 0 {
65✔
1456
                        numPending++
12✔
1457
                }
12✔
1458
        }
12✔
1459

12✔
1460
        // TODO(roasbeef): modify to only accept a _single_ pending channel per
12✔
1461
        // block unless white listed
12✔
1462
        if numPending >= f.cfg.MaxPendingChannels {
20✔
1463
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
8✔
1464

8✔
1465
                return
1466
        }
1467

1468
        // Ensure that the pendingChansLimit is respected.
1469
        pendingChans, err := f.cfg.ChannelDB.FetchPendingChannels()
57✔
1470
        if err != nil {
4✔
1471
                f.failFundingFlow(peer, cid, err)
4✔
1472
                return
4✔
1473
        }
4✔
1474

1475
        if len(pendingChans) > pendingChansLimit {
1476
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
49✔
1477
                return
49✔
1478
        }
×
UNCOV
1479

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

×
UNCOV
1493
        // Ensure that the remote party respects our maximum channel size.
×
UNCOV
1494
        if amt > f.cfg.MaxChanSize {
×
UNCOV
1495
                f.failFundingFlow(
×
UNCOV
1496
                        peer, cid,
×
UNCOV
1497
                        lnwallet.ErrChanTooLarge(amt, f.cfg.MaxChanSize),
×
1498
                )
1499
                return
1500
        }
1501

51✔
1502
        // We'll, also ensure that the remote party isn't attempting to propose
2✔
1503
        // a channel that's below our current min channel size.
2✔
1504
        if amt < f.cfg.MinChanSize {
2✔
1505
                f.failFundingFlow(
2✔
1506
                        peer, cid,
2✔
1507
                        lnwallet.ErrChanTooSmall(amt, f.cfg.MinChanSize),
2✔
1508
                )
1509
                return
1510
        }
1511

47✔
UNCOV
1512
        // If request specifies non-zero push amount and 'rejectpush' is set,
×
UNCOV
1513
        // signal an error.
×
UNCOV
1514
        if f.cfg.RejectPush && msg.PushAmount > 0 {
×
UNCOV
1515
                f.failFundingFlow(peer, cid, lnwallet.ErrNonZeroPushAmount())
×
UNCOV
1516
                return
×
UNCOV
1517
        }
×
1518

1519
        // Send the OpenChannel request to the ChannelAcceptor to determine
1520
        // whether this node will accept the channel.
1521
        chanReq := &chanacceptor.ChannelAcceptRequest{
48✔
1522
                Node:        peer.IdentityKey(),
1✔
1523
                OpenChanMsg: msg,
1✔
1524
        }
1✔
1525

1526
        // Query our channel acceptor to determine whether we should reject
1527
        // the channel.
1528
        acceptorResp := f.cfg.OpenChannelPredicate.Accept(chanReq)
46✔
1529
        if acceptorResp.RejectChannel() {
46✔
1530
                f.failFundingFlow(peer, cid, acceptorResp.ChanAcceptError)
46✔
1531
                return
46✔
1532
        }
46✔
1533

46✔
1534
        log.Infof("Recv'd fundingRequest(amt=%v, push=%v, delay=%v, "+
46✔
1535
                "pendingId=%x) from peer(%x)", amt, msg.PushAmount,
46✔
1536
                msg.CsvDelay, msg.PendingChannelID,
46✔
UNCOV
1537
                peer.IdentityKey().SerializeCompressed())
×
UNCOV
1538

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

46✔
1560
        var scidFeatureVal bool
46✔
UNCOV
1561
        if hasFeatures(
×
UNCOV
1562
                peer.LocalFeatures(), peer.RemoteFeatures(),
×
UNCOV
1563
                lnwire.ScidAliasOptional,
×
UNCOV
1564
        ) {
×
UNCOV
1565

×
1566
                scidFeatureVal = true
1567
        }
46✔
1568

46✔
1569
        var (
46✔
1570
                zeroConf bool
46✔
1571
                scid     bool
49✔
1572
        )
3✔
1573

3✔
1574
        // Only echo back a channel type in AcceptChannel if we actually used
3✔
1575
        // explicit negotiation above.
1576
        if chanType != nil {
46✔
1577
                // Check if the channel type includes the zero-conf or
46✔
1578
                // scid-alias bits.
46✔
1579
                featureVec := lnwire.RawFeatureVector(*chanType)
46✔
1580
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
46✔
1581
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
46✔
1582

46✔
1583
                // If the zero-conf channel type was negotiated, ensure that
50✔
1584
                // the acceptor allows it.
4✔
1585
                if zeroConf && !acceptorResp.ZeroConf {
4✔
1586
                        // Fail the funding flow.
4✔
1587
                        flowErr := fmt.Errorf("channel acceptor blocked " +
4✔
1588
                                "zero-conf channel negotiation")
4✔
1589
                        log.Errorf("Cancelling funding flow for %v based on "+
4✔
1590
                                "channel acceptor response: %v", cid, flowErr)
4✔
1591
                        f.failFundingFlow(peer, cid, flowErr)
4✔
1592
                        return
4✔
1593
                }
×
UNCOV
1594

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

×
UNCOV
1612
                        // Set zeroConf to true to enable the zero-conf flow.
×
1613
                        zeroConf = true
×
UNCOV
1614
                }
×
UNCOV
1615
        }
×
UNCOV
1616

×
UNCOV
1617
        public := msg.ChannelFlags&lnwire.FFAnnounceChannel != 0
×
1618
        switch {
1619
        // Sending the option-scid-alias channel type for a public channel is
UNCOV
1620
        // disallowed.
×
1621
        case public && scid:
1622
                err = fmt.Errorf("option-scid-alias chantype for public " +
1623
                        "channel")
1624
                log.Errorf("Cancelling funding flow for public channel %v "+
46✔
1625
                        "with scid-alias: %v", cid, err)
46✔
1626
                f.failFundingFlow(peer, cid, err)
1627

1628
                return
×
UNCOV
1629

×
UNCOV
1630
        // The current variant of taproot channels can only be used with
×
UNCOV
1631
        // unadvertised channels for now.
×
1632
        case commitType.IsTaproot() && public:
×
1633
                err = fmt.Errorf("taproot channel type for public channel")
×
1634
                log.Errorf("Cancelling funding flow for public taproot "+
×
1635
                        "channel %v: %v", cid, err)
×
1636
                f.failFundingFlow(peer, cid, err)
1637

1638
                return
UNCOV
1639
        }
×
UNCOV
1640

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

×
1655
                return
×
1656
        }
1657

46✔
UNCOV
1658
        req := &lnwallet.InitFundingReserveMsg{
×
UNCOV
1659
                ChainHash:        &msg.ChainHash,
×
UNCOV
1660
                PendingChanID:    msg.PendingChannelID,
×
UNCOV
1661
                NodeID:           peer.IdentityKey(),
×
UNCOV
1662
                NodeAddr:         peer.Address(),
×
UNCOV
1663
                LocalFundingAmt:  0,
×
1664
                RemoteFundingAmt: amt,
1665
                CommitFeePerKw:   chainfee.SatPerKWeight(msg.FeePerKiloWeight),
46✔
1666
                FundingFeePerKw:  0,
46✔
1667
                PushMSat:         msg.PushAmount,
46✔
1668
                Flags:            msg.ChannelFlags,
46✔
1669
                MinConfs:         1,
46✔
1670
                CommitType:       commitType,
46✔
1671
                ZeroConf:         zeroConf,
46✔
1672
                OptionScidAlias:  scid,
46✔
1673
                ScidAliasFeature: scidFeatureVal,
46✔
1674
                TapscriptRoot:    tapscriptRoot,
46✔
1675
        }
46✔
1676

46✔
1677
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
46✔
1678
        if err != nil {
46✔
1679
                log.Errorf("Unable to initialize reservation: %v", err)
46✔
1680
                f.failFundingFlow(peer, cid, err)
46✔
1681
                return
46✔
1682
        }
46✔
1683

46✔
1684
        log.Debugf("Initialized channel reservation: zeroConf=%v, psbt=%v, "+
46✔
1685
                "cannedShim=%v", reservation.IsZeroConf(),
46✔
UNCOV
1686
                reservation.IsPsbt(), reservation.IsCannedShim())
×
UNCOV
1687

×
UNCOV
1688
        if zeroConf {
×
UNCOV
1689
                // Store an alias for zero-conf channels. Other option-scid
×
1690
                // channels will do this at a later point.
1691
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
46✔
1692
                if err != nil {
46✔
1693
                        log.Errorf("Unable to request alias: %v", err)
46✔
1694
                        f.failFundingFlow(peer, cid, err)
46✔
1695
                        return
48✔
1696
                }
2✔
1697

2✔
1698
                reservation.AddAlias(aliasScid)
2✔
1699
        }
2✔
UNCOV
1700

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

1712
        // We'll ignore the min_depth calculated above if this is a zero-conf
1713
        // channel.
1714
        if zeroConf {
46✔
1715
                numConfsReq = 0
46✔
UNCOV
1716
        }
×
UNCOV
1717

×
1718
        reservation.SetNumConfsRequired(numConfsReq)
1719

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

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

×
UNCOV
1758
        // If a script enforced channel lease is being proposed, we'll need to
×
UNCOV
1759
        // validate its custom TLV records.
×
UNCOV
1760
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
×
UNCOV
1761
                if msg.LeaseExpiry == nil {
×
1762
                        err := errors.New("missing lease expiry")
×
1763
                        f.failFundingFlow(peer, cid, err)
46✔
1764
                        return
46✔
1765
                }
46✔
1766

46✔
1767
                // If we had a shim registered for this channel prior to
46✔
UNCOV
1768
                // receiving its corresponding OpenChannel message, then we'll
×
UNCOV
1769
                // validate the proposed LeaseExpiry against what was registered
×
UNCOV
1770
                // in our shim.
×
UNCOV
1771
                if reservation.LeaseExpiry() != 0 {
×
UNCOV
1772
                        if uint32(*msg.LeaseExpiry) !=
×
1773
                                reservation.LeaseExpiry() {
1774

1775
                                err := errors.New("lease expiry mismatch")
1776
                                f.failFundingFlow(peer, cid, err)
1777
                                return
1778
                        }
×
UNCOV
1779
                }
×
UNCOV
1780
        }
×
UNCOV
1781

×
UNCOV
1782
        log.Infof("Requiring %v confirmations for pendingChan(%x): "+
×
UNCOV
1783
                "amt=%v, push_amt=%v, committype=%v, upfrontShutdown=%x",
×
UNCOV
1784
                numConfsReq, msg.PendingChannelID, amt, msg.PushAmount,
×
UNCOV
1785
                commitType, msg.UpfrontShutdownScript)
×
1786

1787
        // Generate our required constraints for the remote party, using the
1788
        // values provided by the channel acceptor if they are non-zero.
1789
        remoteCsvDelay := f.cfg.RequiredRemoteDelay(amt)
46✔
1790
        if acceptorResp.CSVDelay != 0 {
46✔
1791
                remoteCsvDelay = acceptorResp.CSVDelay
46✔
1792
        }
46✔
1793

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

1806
        chanReserve := f.cfg.RequiredRemoteChanReserve(amt, maxDustLimit)
1807
        if acceptorResp.Reserve != 0 {
1808
                chanReserve = acceptorResp.Reserve
46✔
1809
        }
46✔
UNCOV
1810

×
UNCOV
1811
        remoteMaxValue := f.cfg.RequiredRemoteMaxValue(amt)
×
1812
        if acceptorResp.InFlightTotal != 0 {
1813
                remoteMaxValue = acceptorResp.InFlightTotal
46✔
1814
        }
46✔
UNCOV
1815

×
UNCOV
1816
        maxHtlcs := f.cfg.RequiredRemoteMaxHTLCs(amt)
×
1817
        if acceptorResp.HtlcLimit != 0 {
1818
                maxHtlcs = acceptorResp.HtlcLimit
46✔
1819
        }
46✔
UNCOV
1820

×
UNCOV
1821
        // Default to our default minimum hltc value, replacing it with the
×
1822
        // channel acceptor's value if it is set.
1823
        minHtlc := f.cfg.DefaultMinHtlcIn
46✔
1824
        if acceptorResp.MinHtlcIn != 0 {
46✔
1825
                minHtlc = acceptorResp.MinHtlcIn
×
1826
        }
×
1827

1828
        // If we are handling a FundingOpen request then we need to specify the
1829
        // default channel fees since they are not provided by the responder
1830
        // interactively.
46✔
1831
        ourContribution := reservation.OurContribution()
46✔
UNCOV
1832
        forwardingPolicy := f.defaultForwardingPolicy(
×
UNCOV
1833
                ourContribution.ChannelStateBounds,
×
1834
        )
1835

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

46✔
1860
        // Update the timestamp once the fundingOpenMsg has been handled.
46✔
1861
        defer resCtx.updateTimestamp()
46✔
1862

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

46✔
1891
        // With our parameters set, we'll now process their contribution so we
46✔
1892
        // can move the funding workflow ahead.
46✔
1893
        remoteContribution := &lnwallet.ChannelContribution{
46✔
1894
                FundingAmount:        amt,
46✔
1895
                FirstCommitmentPoint: msg.FirstCommitmentPoint,
46✔
1896
                ChannelConfig:        &cfg,
46✔
1897
                UpfrontShutdown:      msg.UpfrontShutdownScript,
46✔
1898
        }
46✔
1899

46✔
1900
        if resCtx.reservation.IsTaproot() {
46✔
1901
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
46✔
1902
                if err != nil {
46✔
1903
                        log.Error(errNoLocalNonce)
46✔
1904

46✔
1905
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
46✔
1906

46✔
1907
                        return
48✔
1908
                }
2✔
1909

2✔
UNCOV
1910
                remoteContribution.LocalNonce = &musig2.Nonces{
×
UNCOV
1911
                        PubNonce: localNonce,
×
UNCOV
1912
                }
×
UNCOV
1913
        }
×
UNCOV
1914

×
UNCOV
1915
        err = reservation.ProcessSingleContribution(remoteContribution)
×
1916
        if err != nil {
1917
                log.Errorf("unable to add contribution reservation: %v", err)
2✔
1918
                f.failFundingFlow(peer, cid, err)
2✔
1919
                return
2✔
1920
        }
1921

1922
        log.Infof("Sending fundingResp for pending_id(%x)",
46✔
1923
                msg.PendingChannelID)
52✔
1924
        bounds := remoteContribution.ChannelConfig.ChannelStateBounds
6✔
1925
        log.Debugf("Remote party accepted channel state space bounds: %v",
6✔
1926
                lnutils.SpewLogClosure(bounds))
6✔
1927
        params := remoteContribution.ChannelConfig.CommitmentParams
6✔
1928
        log.Debugf("Remote party accepted commitment rendering params: %v",
1929
                lnutils.SpewLogClosure(params))
40✔
1930

40✔
1931
        reservation.SetState(lnwallet.SentAcceptChannel)
40✔
1932

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

40✔
1955
        if commitType.IsTaproot() {
40✔
1956
                fundingAccept.LocalNonce = lnwire.SomeMusig2Nonce(
40✔
1957
                        ourContribution.LocalNonce.PubNonce,
40✔
1958
                )
40✔
1959
        }
40✔
1960

40✔
1961
        if err := peer.SendMessage(true, &fundingAccept); err != nil {
40✔
1962
                log.Errorf("unable to send funding response to peer: %v", err)
42✔
1963
                f.failFundingFlow(peer, cid, err)
2✔
1964
                return
2✔
1965
        }
2✔
1966
}
2✔
1967

1968
// funderProcessAcceptChannel processes a response to the workflow initiation
40✔
UNCOV
1969
// sent by the remote peer. This message then queues a message with the funding
×
UNCOV
1970
// outpoint, and a commitment signature to the remote peer.
×
UNCOV
1971
//
×
UNCOV
1972
//nolint:funlen
×
1973
func (f *Manager) funderProcessAcceptChannel(peer lnpeer.Peer,
1974
        msg *lnwire.AcceptChannel) {
1975

1976
        pendingChanID := msg.PendingChannelID
1977
        peerKey := peer.IdentityKey()
1978
        var peerKeyBytes []byte
1979
        if peerKey != nil {
1980
                peerKeyBytes = peerKey.SerializeCompressed()
1981
        }
32✔
1982

32✔
1983
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
32✔
1984
        if err != nil {
32✔
1985
                log.Warnf("Can't find reservation (peerKey:%x, chan_id:%v)",
32✔
1986
                        peerKeyBytes, pendingChanID)
64✔
1987
                return
32✔
1988
        }
32✔
1989

1990
        // Update the timestamp once the fundingAcceptMsg has been handled.
32✔
1991
        defer resCtx.updateTimestamp()
32✔
UNCOV
1992

×
UNCOV
1993
        if resCtx.reservation.State() != lnwallet.SentOpenChannel {
×
1994
                return
×
1995
        }
×
1996

1997
        log.Infof("Recv'd fundingResponse for pending_id(%x)",
1998
                pendingChanID[:])
32✔
1999

32✔
2000
        // Create the channel identifier.
32✔
UNCOV
2001
        cid := newChanIdentifier(msg.PendingChannelID)
×
UNCOV
2002

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

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

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

×
2050
                _, negotiatedCommitType, err := negotiateCommitmentType(
×
2051
                        msg.ChannelType, peer.LocalFeatures(),
×
2052
                        peer.RemoteFeatures(),
×
2053
                )
×
2054
                if err != nil {
×
2055
                        err := errors.New("received unexpected channel type")
×
2056
                        f.failFundingFlow(peer, cid, err)
×
2057
                        return
×
2058
                }
×
UNCOV
2059

×
2060
                if implicitCommitType != negotiatedCommitType {
×
2061
                        err := errors.New("negotiated unexpected channel type")
×
2062
                        f.failFundingFlow(peer, cid, err)
×
2063
                        return
×
2064
                }
×
UNCOV
2065
        }
×
2066

UNCOV
2067
        // The required number of confirmations should not be greater than the
×
UNCOV
2068
        // maximum number of confirmations required by the ChainNotifier to
×
UNCOV
2069
        // properly dispatch confirmations.
×
UNCOV
2070
        if msg.MinAcceptDepth > chainntnfs.MaxNumConfs {
×
UNCOV
2071
                err := lnwallet.ErrNumConfsTooLarge(
×
2072
                        msg.MinAcceptDepth, chainntnfs.MaxNumConfs,
2073
                )
2074
                log.Warnf("Unacceptable channel constraints: %v", err)
2075
                f.failFundingFlow(peer, cid, err)
2076
                return
2077
        }
32✔
2078

1✔
2079
        // Check that zero-conf channels have minimum depth set to 0.
1✔
2080
        if resCtx.reservation.IsZeroConf() && msg.MinAcceptDepth != 0 {
1✔
2081
                err = fmt.Errorf("zero-conf channel has min_depth non-zero")
1✔
2082
                log.Warn(err)
1✔
2083
                f.failFundingFlow(peer, cid, err)
1✔
2084
                return
1✔
2085
        }
2086

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

2096
                minDepth = 1
30✔
2097
        }
30✔
UNCOV
2098

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

30✔
2122
        cfg := channeldb.ChannelConfig{
30✔
2123
                ChannelStateBounds: channeldb.ChannelStateBounds{
31✔
2124
                        MaxPendingAmount: resCtx.remoteMaxValue,
1✔
2125
                        ChanReserve:      resCtx.remoteChanReserve,
1✔
2126
                        MinHTLC:          resCtx.remoteMinHtlc,
1✔
2127
                        MaxAcceptedHtlcs: resCtx.remoteMaxHtlcs,
1✔
2128
                },
2129
                CommitmentParams: channeldb.CommitmentParams{
29✔
2130
                        DustLimit: msg.DustLimit,
29✔
2131
                        CsvDelay:  resCtx.remoteCsvDelay,
29✔
2132
                },
29✔
2133
                MultiSigKey: keychain.KeyDescriptor{
29✔
2134
                        PubKey: copyPubKey(msg.FundingKey),
29✔
2135
                },
29✔
2136
                RevocationBasePoint: keychain.KeyDescriptor{
29✔
2137
                        PubKey: copyPubKey(msg.RevocationPoint),
29✔
2138
                },
29✔
2139
                PaymentBasePoint: keychain.KeyDescriptor{
29✔
2140
                        PubKey: copyPubKey(msg.PaymentPoint),
29✔
2141
                },
29✔
2142
                DelayBasePoint: keychain.KeyDescriptor{
29✔
2143
                        PubKey: copyPubKey(msg.DelayedPaymentPoint),
29✔
2144
                },
29✔
2145
                HtlcBasePoint: keychain.KeyDescriptor{
29✔
2146
                        PubKey: copyPubKey(msg.HtlcPoint),
29✔
2147
                },
29✔
2148
        }
29✔
2149

29✔
2150
        // The remote node has responded with their portion of the channel
29✔
2151
        // contribution. At this point, we can process their contribution which
29✔
2152
        // allows us to construct and sign both the commitment transaction, and
29✔
2153
        // the funding transaction.
29✔
2154
        remoteContribution := &lnwallet.ChannelContribution{
29✔
2155
                FirstCommitmentPoint: msg.FirstCommitmentPoint,
29✔
2156
                ChannelConfig:        &cfg,
29✔
2157
                UpfrontShutdown:      msg.UpfrontShutdownScript,
29✔
2158
        }
29✔
2159

29✔
2160
        if resCtx.reservation.IsTaproot() {
29✔
2161
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
29✔
2162
                if err != nil {
29✔
2163
                        log.Error(errNoLocalNonce)
29✔
2164

29✔
2165
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
29✔
2166

29✔
2167
                        return
31✔
2168
                }
2✔
2169

2✔
UNCOV
2170
                remoteContribution.LocalNonce = &musig2.Nonces{
×
UNCOV
2171
                        PubNonce: localNonce,
×
UNCOV
2172
                }
×
UNCOV
2173
        }
×
UNCOV
2174

×
UNCOV
2175
        err = resCtx.reservation.ProcessContribution(remoteContribution)
×
2176

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

×
2219
        log.Infof("pendingChan(%x): remote party proposes num_confs=%v, "+
29✔
UNCOV
2220
                "csv_delay=%v", pendingChanID[:], msg.MinAcceptDepth,
×
UNCOV
2221
                msg.CsvDelay)
×
UNCOV
2222
        bounds = remoteContribution.ChannelConfig.ChannelStateBounds
×
UNCOV
2223
        log.Debugf("Remote party accepted channel state space bounds: %v",
×
UNCOV
2224
                lnutils.SpewLogClosure(bounds))
×
2225
        commitParams = remoteContribution.ChannelConfig.CommitmentParams
2226
        log.Debugf("Remote party accepted commitment rendering params: %v",
29✔
2227
                lnutils.SpewLogClosure(commitParams))
29✔
2228

29✔
2229
        // If the user requested funding through a PSBT, we cannot directly
29✔
2230
        // continue now and need to wait for the fully funded and signed PSBT
29✔
2231
        // to arrive. To not block any other channels from opening, we wait in
29✔
2232
        // a separate goroutine.
29✔
2233
        if psbtIntent != nil {
29✔
2234
                f.wg.Add(1)
29✔
2235
                go func() {
29✔
2236
                        defer f.wg.Done()
29✔
2237

29✔
2238
                        f.waitForPsbt(psbtIntent, resCtx, cid)
29✔
2239
                }()
29✔
2240

29✔
UNCOV
2241
                // With the new goroutine spawned, we can now exit to unblock
×
UNCOV
2242
                // the main event loop.
×
UNCOV
2243
                return
×
UNCOV
2244
        }
×
UNCOV
2245

×
UNCOV
2246
        // In a normal, non-PSBT funding flow, we can jump directly to the next
×
2247
        // step where we expect our contribution to be finalized.
2248
        f.continueFundingAccept(resCtx, cid)
2249
}
UNCOV
2250

×
2251
// waitForPsbt blocks until either a signed PSBT arrives, an error occurs or
2252
// the funding manager shuts down. In the case of a valid PSBT, the funding flow
2253
// is continued.
2254
//
2255
// NOTE: This method must be called as a goroutine.
29✔
2256
func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
2257
        resCtx *reservationWithCtx, cid *chanIdentifier) {
2258

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

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

×
UNCOV
2282
                // If the remote canceled the funding reservation, we don't need
×
2283
                // to send another fail message. But we want to inform the user
2284
                // about what happened.
UNCOV
2285
                case chanfunding.ErrRemoteCanceled:
×
UNCOV
2286
                        log.Infof("Remote canceled, aborting PSBT flow "+
×
UNCOV
2287
                                "for peer_key=%x, pending_chan_id=%x",
×
2288
                                peerKey.SerializeCompressed(), cid.tempChanID)
2289
                        return
2290

2291
                // Nil error means the flow continues normally now.
UNCOV
2292
                case nil:
×
UNCOV
2293

×
UNCOV
2294
                // For any other error, we'll fail the funding flow.
×
2295
                default:
×
2296
                        failFlow("error waiting for PSBT flow", err)
×
2297
                        return
2298
                }
UNCOV
2299

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

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

2333
                // We are now ready to continue the funding flow.
UNCOV
2334
                f.continueFundingAccept(resCtx, cid)
×
UNCOV
2335

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

×
UNCOV
2347
// continueFundingAccept continues the channel funding flow once our
×
UNCOV
2348
// contribution is finalized, the channel output is known and the funding
×
UNCOV
2349
// transaction is signed.
×
UNCOV
2350
func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
×
2351
        cid *chanIdentifier) {
2352

2353
        // Now that we have their contribution, we can extract, then send over
2354
        // both the funding out point and our signature for their version of
2355
        // the commitment transaction to the remote peer.
2356
        outPoint := resCtx.reservation.FundingOutpoint()
2357
        _, sig := resCtx.reservation.OurSignatures()
2358

29✔
2359
        // A new channel has almost finished the funding process. In order to
29✔
2360
        // properly synchronize with the writeHandler goroutine, we add a new
29✔
2361
        // channel to the barriers map which will be closed once the channel is
29✔
2362
        // fully open.
29✔
2363
        channelID := lnwire.NewChanIDFromOutPoint(*outPoint)
29✔
2364
        log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
29✔
2365

29✔
2366
        // The next message that advances the funding flow will reference the
29✔
2367
        // channel via its permanent channel ID, so we'll set up this mapping
29✔
2368
        // so we can retrieve the reservation context once we get the
29✔
2369
        // FundingSigned message.
29✔
2370
        f.resMtx.Lock()
29✔
2371
        f.signedReservations[channelID] = cid.tempChanID
29✔
2372
        f.resMtx.Unlock()
29✔
2373

29✔
2374
        log.Infof("Generated ChannelPoint(%v) for pending_id(%x)", outPoint,
29✔
2375
                cid.tempChanID[:])
29✔
2376

29✔
2377
        // Before sending FundingCreated sent, we notify Brontide to keep track
29✔
2378
        // of this pending open channel.
29✔
2379
        err := resCtx.peer.AddPendingChannel(channelID, f.quit)
29✔
2380
        if err != nil {
29✔
2381
                pubKey := resCtx.peer.IdentityKey().SerializeCompressed()
29✔
2382
                log.Errorf("Unable to add pending channel %v with peer %x: %v",
29✔
2383
                        channelID, pubKey, err)
29✔
2384
        }
29✔
2385

29✔
2386
        // Once Brontide is aware of this channel, we need to set it in
29✔
2387
        // chanIdentifier so this channel will be removed from Brontide if the
29✔
UNCOV
2388
        // funding flow fails.
×
UNCOV
2389
        cid.setChanID(channelID)
×
UNCOV
2390

×
UNCOV
2391
        // Send the FundingCreated msg.
×
2392
        fundingCreated := &lnwire.FundingCreated{
2393
                PendingChannelID: cid.tempChanID,
2394
                FundingPoint:     *outPoint,
2395
        }
2396

29✔
2397
        // If this is a taproot channel, then we'll need to populate the musig2
29✔
2398
        // partial sig field instead of the regular commit sig field.
29✔
2399
        if resCtx.reservation.IsTaproot() {
29✔
2400
                partialSig, ok := sig.(*lnwallet.MusigPartialSig)
29✔
2401
                if !ok {
29✔
2402
                        err := fmt.Errorf("expected musig partial sig, got %T",
29✔
2403
                                sig)
29✔
2404
                        log.Error(err)
29✔
2405
                        f.failFundingFlow(resCtx.peer, cid, err)
29✔
2406

31✔
2407
                        return
2✔
2408
                }
2✔
UNCOV
2409

×
UNCOV
2410
                fundingCreated.PartialSig = lnwire.MaybePartialSigWithNonce(
×
UNCOV
2411
                        partialSig.ToWireSig(),
×
UNCOV
2412
                )
×
UNCOV
2413
        } else {
×
UNCOV
2414
                fundingCreated.CommitSig, err = lnwire.NewSigFromSignature(sig)
×
UNCOV
2415
                if err != nil {
×
2416
                        log.Errorf("Unable to parse signature: %v", err)
2417
                        f.failFundingFlow(resCtx.peer, cid, err)
2✔
2418
                        return
2✔
2419
                }
2✔
2420
        }
27✔
2421

27✔
2422
        resCtx.reservation.SetState(lnwallet.SentFundingCreated)
27✔
UNCOV
2423

×
UNCOV
2424
        if err := resCtx.peer.SendMessage(true, fundingCreated); err != nil {
×
2425
                log.Errorf("Unable to send funding complete message: %v", err)
×
2426
                f.failFundingFlow(resCtx.peer, cid, err)
×
2427
                return
2428
        }
2429
}
29✔
2430

29✔
2431
// fundeeProcessFundingCreated progresses the funding workflow when the daemon
29✔
UNCOV
2432
// is on the responding side of a single funder workflow. Once this message has
×
UNCOV
2433
// been processed, a signature is sent to the remote peer allowing it to
×
UNCOV
2434
// broadcast the funding transaction, progressing the workflow into the final
×
UNCOV
2435
// stage.
×
2436
//
2437
//nolint:funlen
2438
func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
2439
        msg *lnwire.FundingCreated) {
2440

2441
        peerKey := peer.IdentityKey()
2442
        pendingChanID := msg.PendingChannelID
2443

2444
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
2445
        if err != nil {
2446
                log.Warnf("can't find reservation (peer_id:%v, chan_id:%x)",
27✔
2447
                        peerKey, pendingChanID[:])
27✔
2448
                return
27✔
2449
        }
27✔
2450

27✔
2451
        // The channel initiator has responded with the funding outpoint of the
27✔
2452
        // final funding transaction, as well as a signature for our version of
27✔
UNCOV
2453
        // the commitment transaction. So at this point, we can validate the
×
UNCOV
2454
        // initiator's commitment transaction, then send our own if it's valid.
×
UNCOV
2455
        fundingOut := msg.FundingPoint
×
UNCOV
2456
        log.Infof("completing pending_id(%x) with ChannelPoint(%v)",
×
2457
                pendingChanID[:], fundingOut)
2458

2459
        if resCtx.reservation.State() != lnwallet.SentAcceptChannel {
2460
                return
2461
        }
2462

27✔
2463
        // Create the channel identifier without setting the active channel ID.
27✔
2464
        cid := newChanIdentifier(pendingChanID)
27✔
2465

27✔
2466
        // For taproot channels, the commit signature is actually the partial
27✔
UNCOV
2467
        // signature. Otherwise, we can convert the ECDSA commit signature into
×
UNCOV
2468
        // our internal input.Signature type.
×
2469
        var commitSig input.Signature
2470
        if resCtx.reservation.IsTaproot() {
2471
                partialSig, err := msg.PartialSig.UnwrapOrErrV(errNoPartialSig)
27✔
2472
                if err != nil {
27✔
2473
                        f.failFundingFlow(peer, cid, err)
27✔
2474

27✔
2475
                        return
27✔
2476
                }
27✔
2477

29✔
2478
                commitSig = new(lnwallet.MusigPartialSig).FromWireSig(
2✔
2479
                        &partialSig,
2✔
UNCOV
2480
                )
×
UNCOV
2481
        } else {
×
UNCOV
2482
                commitSig, err = msg.CommitSig.ToSignature()
×
UNCOV
2483
                if err != nil {
×
2484
                        log.Errorf("unable to parse signature: %v", err)
2485
                        f.failFundingFlow(peer, cid, err)
2✔
2486
                        return
2✔
2487
                }
2✔
2488
        }
25✔
2489

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

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

27✔
2527
        // Get forwarding policy before deleting the reservation context.
27✔
2528
        forwardingPolicy := resCtx.forwardingPolicy
27✔
UNCOV
2529

×
UNCOV
2530
        // The channel is marked IsPending in the database, and can be removed
×
UNCOV
2531
        // from the set of active reservations.
×
UNCOV
2532
        f.deleteReservationCtx(peerKey, cid.tempChanID)
×
2533

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

×
2551
                // Close the channel with us as the initiator because we are
×
2552
                // deciding to exit the funding flow due to an internal error.
×
2553
                if err := completeChan.CloseChannel(
×
2554
                        closeInfo, channeldb.ChanStatusLocalCloseInitiator,
×
2555
                ); err != nil {
×
2556
                        log.Errorf("Failed closing channel %v: %v",
×
2557
                                completeChan.FundingOutpoint, err)
×
2558
                }
×
UNCOV
2559
        }
×
UNCOV
2560

×
UNCOV
2561
        // A new channel has almost finished the funding process. In order to
×
UNCOV
2562
        // properly synchronize with the writeHandler goroutine, we add a new
×
UNCOV
2563
        // channel to the barriers map which will be closed once the channel is
×
UNCOV
2564
        // fully open.
×
UNCOV
2565
        channelID := lnwire.NewChanIDFromOutPoint(fundingOut)
×
2566
        log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
2567

2568
        fundingSigned := &lnwire.FundingSigned{}
2569

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

2✔
2582
                        return
2✔
2583
                }
×
UNCOV
2584

×
UNCOV
2585
                fundingSigned.PartialSig = lnwire.MaybePartialSigWithNonce(
×
UNCOV
2586
                        partialSig.ToWireSig(),
×
UNCOV
2587
                )
×
UNCOV
2588
        } else {
×
UNCOV
2589
                fundingSigned.CommitSig, err = lnwire.NewSigFromSignature(sig)
×
UNCOV
2590
                if err != nil {
×
2591
                        log.Errorf("unable to parse signature: %v", err)
2592
                        f.failFundingFlow(peer, cid, err)
2✔
2593
                        deleteFromDatabase()
2✔
2594

2✔
2595
                        return
25✔
2596
                }
25✔
2597
        }
25✔
UNCOV
2598

×
UNCOV
2599
        // Before sending FundingSigned, we notify Brontide first to keep track
×
UNCOV
2600
        // of this pending open channel.
×
UNCOV
2601
        if err := peer.AddPendingChannel(channelID, f.quit); err != nil {
×
2602
                pubKey := peer.IdentityKey().SerializeCompressed()
×
2603
                log.Errorf("Unable to add pending channel %v with peer %x: %v",
×
2604
                        cid.chanID, pubKey, err)
2605
        }
2606

2607
        // Once Brontide is aware of this channel, we need to set it in
2608
        // chanIdentifier so this channel will be removed from Brontide if the
27✔
UNCOV
2609
        // funding flow fails.
×
UNCOV
2610
        cid.setChanID(channelID)
×
UNCOV
2611

×
UNCOV
2612
        fundingSigned.ChanID = cid.chanID
×
2613

2614
        log.Infof("sending FundingSigned for pending_id(%x) over "+
2615
                "ChannelPoint(%v)", pendingChanID[:], fundingOut)
2616

2617
        // With their signature for our version of the commitment transaction
27✔
2618
        // verified, we can now send over our signature to the remote peer.
27✔
2619
        if err := peer.SendMessage(true, fundingSigned); err != nil {
27✔
2620
                log.Errorf("unable to send FundingSigned message: %v", err)
27✔
2621
                f.failFundingFlow(peer, cid, err)
27✔
2622
                deleteFromDatabase()
27✔
2623
                return
27✔
2624
        }
27✔
2625

27✔
2626
        // With a permanent channel id established we can save the respective
27✔
UNCOV
2627
        // forwarding policy in the database. In the channel announcement phase
×
UNCOV
2628
        // this forwarding policy is retrieved and applied.
×
UNCOV
2629
        err = f.saveInitialForwardingPolicy(cid.chanID, &forwardingPolicy)
×
UNCOV
2630
        if err != nil {
×
2631
                log.Errorf("Unable to store the forwarding policy: %v", err)
×
2632
        }
2633

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

2642
        // Create an entry in the local discovery map so we can ensure that we
2643
        // process the channel confirmation fully before we receive a
2644
        // channel_ready message.
27✔
UNCOV
2645
        f.localDiscoverySignals.Store(cid.chanID, make(chan struct{}))
×
UNCOV
2646

×
UNCOV
2647
        // Inform the ChannelNotifier that the channel has entered
×
2648
        // pending open state.
2649
        f.cfg.NotifyPendingOpenChannelEvent(fundingOut, completeChan)
2650

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

27✔
2671
// funderProcessFundingSigned processes the final message received in a single
27✔
2672
// funder workflow. Once this message is processed, the funding transaction is
27✔
2673
// broadcast. Once the funding transaction reaches a sufficient number of
27✔
2674
// confirmations, a message is sent to the responding peer along with a compact
27✔
2675
// encoding of the location of the channel within the blockchain.
27✔
2676
func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
2677
        msg *lnwire.FundingSigned) {
2678

2679
        // As the funding signed message will reference the reservation by its
2680
        // permanent channel ID, we'll need to perform an intermediate look up
2681
        // before we can obtain the reservation.
2682
        f.resMtx.Lock()
2683
        pendingChanID, ok := f.signedReservations[msg.ChanID]
2684
        delete(f.signedReservations, msg.ChanID)
27✔
2685
        f.resMtx.Unlock()
27✔
2686

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

27✔
2698
        // If the pending channel ID is not found, fail the funding flow.
27✔
2699
        if !ok {
27✔
2700
                // NOTE: we directly overwrite the pending channel ID here for
27✔
2701
                // this rare case since we don't have a valid pending channel
27✔
2702
                // ID.
27✔
2703
                cid.tempChanID = msg.ChanID
27✔
2704

27✔
2705
                err := fmt.Errorf("unable to find signed reservation for "+
27✔
2706
                        "chan_id=%x", msg.ChanID)
27✔
2707
                log.Warnf(err.Error())
×
2708
                f.failFundingFlow(peer, cid, err)
×
2709
                return
×
2710
        }
×
UNCOV
2711

×
UNCOV
2712
        peerKey := peer.IdentityKey()
×
UNCOV
2713
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
×
UNCOV
2714
        if err != nil {
×
2715
                log.Warnf("Unable to find reservation (peer_id:%v, "+
×
2716
                        "chan_id:%x)", peerKey, pendingChanID[:])
×
2717
                // TODO: add ErrChanNotFound?
×
2718
                f.failFundingFlow(peer, cid, err)
2719
                return
27✔
2720
        }
27✔
2721

27✔
UNCOV
2722
        if resCtx.reservation.State() != lnwallet.SentFundingCreated {
×
2723
                err := fmt.Errorf("unable to find reservation for chan_id=%x",
×
2724
                        msg.ChanID)
×
2725
                f.failFundingFlow(peer, cid, err)
×
2726

×
2727
                return
×
2728
        }
2729

27✔
UNCOV
2730
        // Create an entry in the local discovery map so we can ensure that we
×
UNCOV
2731
        // process the channel confirmation fully before we receive a
×
UNCOV
2732
        // channel_ready message.
×
UNCOV
2733
        fundingPoint := resCtx.reservation.FundingOutpoint()
×
UNCOV
2734
        permChanID := lnwire.NewChanIDFromOutPoint(*fundingPoint)
×
UNCOV
2735
        f.localDiscoverySignals.Store(permChanID, make(chan struct{}))
×
2736

2737
        // We have to store the forwardingPolicy before the reservation context
2738
        // is deleted. The policy will then be read and applied in
2739
        // newChanAnnouncement.
2740
        err = f.saveInitialForwardingPolicy(
27✔
2741
                permChanID, &resCtx.forwardingPolicy,
27✔
2742
        )
27✔
2743
        if err != nil {
27✔
2744
                log.Errorf("Unable to store the forwarding policy: %v", err)
27✔
2745
        }
27✔
2746

27✔
2747
        // For taproot channels, the commit signature is actually the partial
27✔
2748
        // signature. Otherwise, we can convert the ECDSA commit signature into
27✔
2749
        // our internal input.Signature type.
27✔
2750
        var commitSig input.Signature
27✔
UNCOV
2751
        if resCtx.reservation.IsTaproot() {
×
UNCOV
2752
                partialSig, err := msg.PartialSig.UnwrapOrErrV(errNoPartialSig)
×
2753
                if err != nil {
2754
                        f.failFundingFlow(peer, cid, err)
2755

2756
                        return
2757
                }
27✔
2758

29✔
2759
                commitSig = new(lnwallet.MusigPartialSig).FromWireSig(
2✔
2760
                        &partialSig,
2✔
UNCOV
2761
                )
×
UNCOV
2762
        } else {
×
UNCOV
2763
                commitSig, err = msg.CommitSig.ToSignature()
×
UNCOV
2764
                if err != nil {
×
2765
                        log.Errorf("unable to parse signature: %v", err)
2766
                        f.failFundingFlow(peer, cid, err)
2✔
2767
                        return
2✔
2768
                }
2✔
2769
        }
25✔
2770

25✔
2771
        completeChan, err := resCtx.reservation.CompleteReservation(
25✔
UNCOV
2772
                nil, commitSig,
×
UNCOV
2773
        )
×
UNCOV
2774
        if err != nil {
×
2775
                log.Errorf("Unable to complete reservation sign "+
×
2776
                        "complete: %v", err)
2777
                f.failFundingFlow(peer, cid, err)
2778
                return
27✔
2779
        }
27✔
2780

27✔
2781
        // The channel is now marked IsPending in the database, and we can
27✔
UNCOV
2782
        // delete it from our set of active reservations.
×
UNCOV
2783
        f.deleteReservationCtx(peerKey, pendingChanID)
×
UNCOV
2784

×
UNCOV
2785
        // Broadcast the finalized funding transaction to the network, but only
×
UNCOV
2786
        // if we actually have the funding transaction.
×
2787
        if completeChan.ChanType.HasFundingTx() {
2788
                fundingTx := completeChan.FundingTxn
2789
                var fundingTxBuf bytes.Buffer
2790
                if err := fundingTx.Serialize(&fundingTxBuf); err != nil {
27✔
2791
                        log.Errorf("Unable to serialize funding "+
27✔
2792
                                "transaction %v: %v", fundingTx.TxHash(), err)
27✔
2793

27✔
2794
                        // Clear the buffer of any bytes that were written
53✔
2795
                        // before the serialization error to prevent logging an
26✔
2796
                        // incomplete transaction.
26✔
2797
                        fundingTxBuf.Reset()
26✔
2798
                }
×
UNCOV
2799

×
UNCOV
2800
                log.Infof("Broadcasting funding tx for ChannelPoint(%v): %x",
×
UNCOV
2801
                        completeChan.FundingOutpoint, fundingTxBuf.Bytes())
×
UNCOV
2802

×
UNCOV
2803
                // Set a nil short channel ID at this stage because we do not
×
UNCOV
2804
                // know it until our funding tx confirms.
×
UNCOV
2805
                label := labels.MakeLabel(
×
2806
                        labels.LabelTypeChannelOpen, nil,
2807
                )
26✔
2808

26✔
2809
                err = f.cfg.PublishTransaction(fundingTx, label)
26✔
2810
                if err != nil {
26✔
2811
                        log.Errorf("Unable to broadcast funding tx %x for "+
26✔
2812
                                "ChannelPoint(%v): %v", fundingTxBuf.Bytes(),
26✔
2813
                                completeChan.FundingOutpoint, err)
26✔
2814

26✔
2815
                        // We failed to broadcast the funding transaction, but
26✔
2816
                        // watch the channel regardless, in case the
26✔
2817
                        // transaction made it to the network. We will retry
26✔
2818
                        // broadcast at startup.
×
2819
                        //
×
2820
                        // TODO(halseth): retry more often? Handle with CPFP?
×
2821
                        // Just delete from the DB?
×
2822
                }
×
UNCOV
2823
        }
×
UNCOV
2824

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

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

2849
        log.Infof("Finalizing pending_id(%x) over ChannelPoint(%v), "+
2850
                "waiting for channel open on-chain", pendingChanID[:],
2851
                fundingPoint)
27✔
UNCOV
2852

×
UNCOV
2853
        // Send an update to the upstream client that the negotiation process
×
UNCOV
2854
        // is over.
×
2855
        upd := &lnrpc.OpenStatusUpdate{
2856
                Update: &lnrpc.OpenStatusUpdate_ChanPending{
27✔
2857
                        ChanPending: &lnrpc.PendingUpdate{
27✔
2858
                                Txid:        fundingPoint.Hash[:],
27✔
2859
                                OutputIndex: fundingPoint.Index,
27✔
2860
                        },
27✔
2861
                },
27✔
2862
                PendingChanId: pendingChanID[:],
27✔
2863
        }
27✔
2864

27✔
2865
        select {
27✔
2866
        case resCtx.updates <- upd:
27✔
2867
                // Inform the ChannelNotifier that the channel has entered
27✔
2868
                // pending open state.
27✔
2869
                f.cfg.NotifyPendingOpenChannelEvent(*fundingPoint, completeChan)
27✔
2870
        case <-f.quit:
27✔
2871
                return
27✔
2872
        }
27✔
2873

27✔
2874
        // At this point we have broadcast the funding transaction and done all
27✔
2875
        // necessary processing.
27✔
2876
        f.wg.Add(1)
27✔
UNCOV
2877
        go f.advanceFundingState(completeChan, pendingChanID, resCtx.updates)
×
UNCOV
2878
}
×
2879

2880
// confirmedChannel wraps a confirmed funding transaction, as well as the short
2881
// channel ID which identifies that channel into a single struct. We'll use
2882
// this to pass around the final state of a channel after it has been
2883
// confirmed.
27✔
2884
type confirmedChannel struct {
27✔
2885
        // shortChanID expresses where in the block the funding transaction was
2886
        // located.
2887
        shortChanID lnwire.ShortChannelID
2888

2889
        // fundingTx is the funding transaction that created the channel.
2890
        fundingTx *wire.MsgTx
2891
}
2892

2893
// fundingTimeout is called when callers of waitForFundingWithTimeout receive
2894
// an ErrConfirmationTimeout. It is used to clean-up channel state and mark the
2895
// channel as closed. The error is only returned for the responder of the
2896
// channel flow.
2897
func (f *Manager) fundingTimeout(c *channeldb.OpenChannel,
2898
        pendingID PendingChanID) error {
2899

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

2✔
2916
        // Close the channel with us as the initiator because we are timing the
2✔
2917
        // channel out.
2✔
2918
        if err := c.CloseChannel(
2✔
2919
                closeInfo, channeldb.ChanStatusLocalCloseInitiator,
2✔
2920
        ); err != nil {
2✔
2921
                return fmt.Errorf("failed closing channel %v: %w",
2✔
2922
                        c.FundingOutpoint, err)
2✔
2923
        }
2✔
2924

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

2✔
UNCOV
2928
        // When the peer comes online, we'll notify it that we are now
×
UNCOV
2929
        // considering the channel flow canceled.
×
UNCOV
2930
        f.wg.Add(1)
×
2931
        go func() {
2932
                defer f.wg.Done()
2✔
2933

2✔
2934
                peer, err := f.waitForPeerOnline(c.IdentityPub)
2✔
2935
                switch err {
2✔
2936
                // We're already shutting down, so we can just return.
2✔
2937
                case ErrFundingManagerShuttingDown:
2✔
2938
                        return
4✔
2939

2✔
2940
                // nil error means we continue on.
2✔
2941
                case nil:
2✔
2942

2✔
2943
                // For unexpected errors, we print the error and still try to
UNCOV
2944
                // fail the funding flow.
×
2945
                default:
×
2946
                        log.Errorf("Unexpected error while waiting for peer "+
2947
                                "to come online: %v", err)
2948
                }
2✔
2949

2950
                // Create channel identifier and set the channel ID.
2951
                cid := newChanIdentifier(pendingID)
UNCOV
2952
                cid.setChanID(lnwire.NewChanIDFromOutPoint(c.FundingOutpoint))
×
UNCOV
2953

×
UNCOV
2954
                // TODO(halseth): should this send be made
×
2955
                // reliable?
2956

2957
                // The reservation won't exist at this point, but we'll send an
2958
                // Error message over anyways with ChanID set to pendingID.
2✔
2959
                f.failFundingFlow(peer, cid, timeoutErr)
2✔
2960
        }()
2✔
2961

2✔
2962
        return timeoutErr
2✔
2963
}
2✔
2964

2✔
2965
// waitForFundingWithTimeout is a wrapper around waitForFundingConfirmation and
2✔
2966
// waitForTimeout that will return ErrConfirmationTimeout if we are not the
2✔
2967
// channel initiator and the MaxWaitNumBlocksFundingConf has passed from the
2968
// funding broadcast height. In case of confirmation, the short channel ID of
2969
// the channel and the funding transaction will be returned.
2✔
2970
func (f *Manager) waitForFundingWithTimeout(
2971
        ch *channeldb.OpenChannel) (*confirmedChannel, error) {
2972

2973
        confChan := make(chan *confirmedChannel)
2974
        timeoutChan := make(chan error, 1)
2975
        cancelChan := make(chan struct{})
2976

2977
        f.wg.Add(1)
2978
        go f.waitForFundingConfirmation(ch, cancelChan, confChan)
57✔
2979

57✔
2980
        // If we are not the initiator, we have no money at stake and will
57✔
2981
        // timeout waiting for the funding transaction to confirm after a
57✔
2982
        // while.
57✔
2983
        if !ch.IsInitiator && !ch.IsZeroConf() {
57✔
2984
                f.wg.Add(1)
57✔
2985
                go f.waitForTimeout(ch, cancelChan, timeoutChan)
57✔
2986
        }
57✔
2987
        defer close(cancelChan)
57✔
2988

57✔
2989
        select {
57✔
2990
        case err := <-timeoutChan:
82✔
2991
                if err != nil {
25✔
2992
                        return nil, err
25✔
2993
                }
25✔
2994
                return nil, ErrConfirmationTimeout
57✔
2995

57✔
2996
        case <-f.quit:
57✔
2997
                // The fundingManager is shutting down, and will resume wait on
2✔
2998
                // startup.
2✔
UNCOV
2999
                return nil, ErrFundingManagerShuttingDown
×
UNCOV
3000

×
3001
        case confirmedChannel, ok := <-confChan:
2✔
3002
                if !ok {
3003
                        return nil, fmt.Errorf("waiting for funding" +
21✔
3004
                                "confirmation failed")
21✔
3005
                }
21✔
3006
                return confirmedChannel, nil
21✔
3007
        }
3008
}
34✔
3009

34✔
UNCOV
3010
// makeFundingScript re-creates the funding script for the funding transaction
×
UNCOV
3011
// of the target channel.
×
UNCOV
3012
func makeFundingScript(channel *channeldb.OpenChannel) ([]byte, error) {
×
3013
        localKey := channel.LocalChanCfg.MultiSigKey.PubKey
34✔
3014
        remoteKey := channel.RemoteChanCfg.MultiSigKey.PubKey
3015

3016
        if channel.ChanType.IsTaproot() {
3017
                pkScript, _, err := input.GenTaprootFundingScript(
3018
                        localKey, remoteKey, int64(channel.Capacity),
3019
                        channel.TapscriptRoot,
77✔
3020
                )
77✔
3021
                if err != nil {
77✔
3022
                        return nil, err
77✔
3023
                }
82✔
3024

5✔
3025
                return pkScript, nil
5✔
3026
        }
5✔
3027

5✔
3028
        multiSigScript, err := input.GenMultiSigScript(
5✔
UNCOV
3029
                localKey.SerializeCompressed(),
×
UNCOV
3030
                remoteKey.SerializeCompressed(),
×
3031
        )
3032
        if err != nil {
5✔
3033
                return nil, err
3034
        }
3035

72✔
3036
        return input.WitnessScriptHash(multiSigScript)
72✔
3037
}
72✔
3038

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

3052
        defer f.wg.Done()
3053
        defer close(confChan)
3054

3055
        // Register with the ChainNotifier for a notification once the funding
3056
        // transaction reaches `numConfs` confirmations.
3057
        txid := completeChan.FundingOutpoint.Hash
57✔
3058
        fundingScript, err := makeFundingScript(completeChan)
57✔
3059
        if err != nil {
57✔
3060
                log.Errorf("unable to create funding script for "+
57✔
3061
                        "ChannelPoint(%v): %v", completeChan.FundingOutpoint,
57✔
3062
                        err)
57✔
3063
                return
57✔
3064
        }
57✔
3065
        numConfs := uint32(completeChan.NumConfsRequired)
57✔
3066

57✔
UNCOV
3067
        // If the underlying channel is a zero-conf channel, we'll set numConfs
×
UNCOV
3068
        // to 6, since it will be zero here.
×
UNCOV
3069
        if completeChan.IsZeroConf() {
×
UNCOV
3070
                numConfs = 6
×
UNCOV
3071
        }
×
3072

57✔
3073
        confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
57✔
3074
                &txid, fundingScript, numConfs,
57✔
3075
                completeChan.BroadcastHeight(),
57✔
3076
        )
63✔
3077
        if err != nil {
6✔
3078
                log.Errorf("Unable to register for confirmation of "+
6✔
3079
                        "ChannelPoint(%v): %v", completeChan.FundingOutpoint,
3080
                        err)
57✔
3081
                return
57✔
3082
        }
57✔
3083

57✔
3084
        log.Infof("Waiting for funding tx (%v) to reach %v confirmations",
57✔
UNCOV
3085
                txid, numConfs)
×
UNCOV
3086

×
UNCOV
3087
        var confDetails *chainntnfs.TxConfirmation
×
UNCOV
3088
        var ok bool
×
UNCOV
3089

×
3090
        // Wait until the specified number of confirmations has been reached,
3091
        // we get a cancel signal, or the wallet signals a shutdown.
57✔
3092
        select {
57✔
3093
        case confDetails, ok = <-confNtfn.Confirmed:
57✔
3094
                // fallthrough
57✔
3095

57✔
3096
        case <-cancelChan:
57✔
3097
                log.Warnf("canceled waiting for funding confirmation, "+
57✔
3098
                        "stopping funding flow for ChannelPoint(%v)",
57✔
3099
                        completeChan.FundingOutpoint)
57✔
3100
                return
34✔
3101

3102
        case <-f.quit:
3103
                log.Warnf("fundingManager shutting down, stopping funding "+
2✔
3104
                        "flow for ChannelPoint(%v)",
2✔
3105
                        completeChan.FundingOutpoint)
2✔
3106
                return
2✔
3107
        }
2✔
3108

3109
        if !ok {
21✔
3110
                log.Warnf("ChainNotifier shutting down, cannot complete "+
21✔
3111
                        "funding flow for ChannelPoint(%v)",
21✔
3112
                        completeChan.FundingOutpoint)
21✔
3113
                return
21✔
3114
        }
3115

3116
        fundingPoint := completeChan.FundingOutpoint
34✔
UNCOV
3117
        log.Infof("ChannelPoint(%v) is now active: ChannelID(%v)",
×
UNCOV
3118
                fundingPoint, lnwire.NewChanIDFromOutPoint(fundingPoint))
×
UNCOV
3119

×
UNCOV
3120
        // With the block height and the transaction index known, we can
×
UNCOV
3121
        // construct the compact chanID which is used on the network to unique
×
3122
        // identify channels.
3123
        shortChanID := lnwire.ShortChannelID{
34✔
3124
                BlockHeight: confDetails.BlockHeight,
34✔
3125
                TxIndex:     confDetails.TxIndex,
34✔
3126
                TxPosition:  uint16(fundingPoint.Index),
34✔
3127
        }
34✔
3128

34✔
3129
        select {
34✔
3130
        case confChan <- &confirmedChannel{
34✔
3131
                shortChanID: shortChanID,
34✔
3132
                fundingTx:   confDetails.Tx,
34✔
3133
        }:
34✔
3134
        case <-f.quit:
34✔
3135
                return
34✔
3136
        }
34✔
3137
}
3138

3139
// waitForTimeout will close the timeout channel if MaxWaitNumBlocksFundingConf
3140
// has passed from the broadcast height of the given channel. In case of error,
34✔
UNCOV
3141
// the error is sent on timeoutChan. The wait can be canceled by closing the
×
UNCOV
3142
// cancelChan.
×
3143
//
3144
// NOTE: timeoutChan MUST be buffered.
3145
// NOTE: This MUST be run as a goroutine.
3146
func (f *Manager) waitForTimeout(completeChan *channeldb.OpenChannel,
3147
        cancelChan <-chan struct{}, timeoutChan chan<- error) {
3148

3149
        defer f.wg.Done()
3150

3151
        epochClient, err := f.cfg.Notifier.RegisterBlockEpochNtfn(nil)
3152
        if err != nil {
3153
                timeoutChan <- fmt.Errorf("unable to register for epoch "+
3154
                        "notification: %v", err)
25✔
3155
                return
25✔
3156
        }
25✔
3157

25✔
3158
        defer epochClient.Cancel()
25✔
3159

25✔
UNCOV
3160
        // On block maxHeight we will cancel the funding confirmation wait.
×
UNCOV
3161
        broadcastHeight := completeChan.BroadcastHeight()
×
UNCOV
3162
        maxHeight := broadcastHeight + MaxWaitNumBlocksFundingConf
×
UNCOV
3163
        for {
×
3164
                select {
3165
                case epoch, ok := <-epochClient.Epochs:
25✔
3166
                        if !ok {
25✔
3167
                                timeoutChan <- fmt.Errorf("epoch client " +
25✔
3168
                                        "shutting down")
25✔
3169
                                return
25✔
3170
                        }
52✔
3171

27✔
3172
                        // Close the timeout channel and exit if the block is
4✔
3173
                        // above the max height.
4✔
UNCOV
3174
                        if uint32(epoch.Height) >= maxHeight {
×
UNCOV
3175
                                log.Warnf("Waited for %v blocks without "+
×
UNCOV
3176
                                        "seeing funding transaction confirmed,"+
×
UNCOV
3177
                                        " cancelling.",
×
3178
                                        MaxWaitNumBlocksFundingConf)
3179

3180
                                // Notify the caller of the timeout.
3181
                                close(timeoutChan)
6✔
3182
                                return
2✔
3183
                        }
2✔
3184

2✔
3185
                        // TODO: If we are the channel initiator implement
2✔
3186
                        // a method for recovering the funds from the funding
2✔
3187
                        // transaction
2✔
3188

2✔
3189
                case <-cancelChan:
2✔
3190
                        return
2✔
3191

3192
                case <-f.quit:
3193
                        // The fundingManager is shutting down, will resume
3194
                        // waiting for the funding transaction on startup.
3195
                        return
3196
                }
15✔
3197
        }
15✔
3198
}
3199

8✔
3200
// makeLabelForTx updates the label for the confirmed funding transaction. If
8✔
3201
// we opened the channel, and lnd's wallet published our funding tx (which is
8✔
3202
// not the case for some channels) then we update our transaction label with
8✔
3203
// our short channel ID, which is known now that our funding transaction has
3204
// confirmed. We do not label transactions we did not publish, because our
3205
// wallet has no knowledge of them.
3206
func (f *Manager) makeLabelForTx(c *channeldb.OpenChannel) {
3207
        if c.IsInitiator && c.ChanType.HasFundingTx() {
3208
                shortChanID := c.ShortChanID()
3209

3210
                // For zero-conf channels, we'll use the actually-confirmed
3211
                // short channel id.
3212
                if c.IsZeroConf() {
3213
                        shortChanID = c.ZeroConfRealScid()
34✔
3214
                }
50✔
3215

16✔
3216
                label := labels.MakeLabel(
16✔
3217
                        labels.LabelTypeChannelOpen, &shortChanID,
16✔
3218
                )
16✔
3219

18✔
3220
                err := f.cfg.UpdateLabel(c.FundingOutpoint.Hash, label)
2✔
3221
                if err != nil {
2✔
3222
                        log.Errorf("unable to update label: %v", err)
3223
                }
16✔
3224
        }
16✔
3225
}
16✔
3226

16✔
3227
// handleFundingConfirmation marks a channel as open in the database, and set
16✔
3228
// the channelOpeningState markedOpen. In addition it will report the now
16✔
UNCOV
3229
// decided short channel ID to the switch, and close the local discovery signal
×
UNCOV
3230
// for this channel.
×
3231
func (f *Manager) handleFundingConfirmation(
3232
        completeChan *channeldb.OpenChannel,
3233
        confChannel *confirmedChannel) error {
3234

3235
        fundingPoint := completeChan.FundingOutpoint
3236
        chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
3237

3238
        // TODO(roasbeef): ideally persistent state update for chan above
3239
        // should be abstracted
3240

30✔
3241
        // Now that that the channel has been fully confirmed, we'll request
30✔
3242
        // that the wallet fully verify this channel to ensure that it can be
30✔
3243
        // used.
30✔
3244
        err := f.cfg.Wallet.ValidateChannel(completeChan, confChannel.fundingTx)
30✔
3245
        if err != nil {
30✔
3246
                // TODO(roasbeef): delete chan state?
30✔
3247
                return fmt.Errorf("unable to validate channel: %w", err)
30✔
3248
        }
30✔
3249

30✔
3250
        // Now that the channel has been validated, we'll persist an alias for
30✔
3251
        // this channel if the option-scid-alias feature-bit was negotiated.
30✔
3252
        if completeChan.NegotiatedAliasFeature() {
30✔
UNCOV
3253
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
×
UNCOV
3254
                if err != nil {
×
3255
                        return fmt.Errorf("unable to request alias: %w", err)
×
3256
                }
3257

3258
                err = f.cfg.AliasManager.AddLocalAlias(
3259
                        aliasScid, confChannel.shortChanID, true, false,
32✔
3260
                )
2✔
3261
                if err != nil {
2✔
3262
                        return fmt.Errorf("unable to request alias: %w", err)
×
3263
                }
×
3264
        }
3265

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

30✔
3280
        // Now that the channel has been fully confirmed and we successfully
30✔
3281
        // saved the opening state, we'll mark it as open within the database.
30✔
3282
        err = completeChan.MarkAsOpen(confChannel.shortChanID)
30✔
UNCOV
3283
        if err != nil {
×
3284
                return fmt.Errorf("error setting channel pending flag to "+
×
3285
                        "false:        %v", err)
×
3286
        }
3287

3288
        // Update the confirmed funding transaction label.
3289
        f.makeLabelForTx(completeChan)
30✔
3290

30✔
UNCOV
3291
        // Inform the ChannelNotifier that the channel has transitioned from
×
UNCOV
3292
        // pending open to open.
×
UNCOV
3293
        f.cfg.NotifyOpenChannelEvent(completeChan.FundingOutpoint)
×
3294

3295
        // Close the discoverySignal channel, indicating to a separate
3296
        // goroutine that the channel now is marked as open in the database
30✔
3297
        // and that it is acceptable to process channel_ready messages
30✔
3298
        // from the peer.
30✔
3299
        if discoverySignal, ok := f.localDiscoverySignals.Load(chanID); ok {
30✔
3300
                close(discoverySignal)
30✔
3301
        }
30✔
3302

30✔
3303
        return nil
30✔
3304
}
30✔
3305

30✔
3306
// sendChannelReady creates and sends the channelReady message.
60✔
3307
// This should be called after the funding transaction has been confirmed,
30✔
3308
// and the channelState is 'markedOpen'.
30✔
3309
func (f *Manager) sendChannelReady(completeChan *channeldb.OpenChannel,
3310
        channel *lnwallet.LightningChannel) error {
30✔
3311

3312
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
3313

3314
        var peerKey [33]byte
3315
        copy(peerKey[:], completeChan.IdentityPub.SerializeCompressed())
3316

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

35✔
3327
        // If this is a taproot channel, then we also need to send along our
35✔
3328
        // set of musig2 nonces as well.
35✔
3329
        if completeChan.ChanType.IsTaproot() {
35✔
UNCOV
3330
                log.Infof("ChanID(%v): generating musig2 nonces...",
×
UNCOV
3331
                        chanID)
×
3332

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

4✔
3347
                        // Now that we've generated the nonce for this channel,
4✔
3348
                        // we'll store it in the set of pending nonces.
4✔
3349
                        localNonce = newNonce
4✔
UNCOV
3350
                        f.pendingMusigNonces[chanID] = localNonce
×
UNCOV
3351
                }
×
UNCOV
3352
                f.nonceMtx.Unlock()
×
3353

3354
                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce(
3355
                        localNonce.PubNonce,
3356
                )
4✔
3357
        }
4✔
3358

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

41✔
3372
                // We can use a pointer to aliases since GetAliases returns a
6✔
3373
                // copy of the alias slice.
6✔
3374
                channelReadyMsg.AliasScid = &aliases[0]
6✔
3375
        }
6✔
UNCOV
3376

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

3394
                localAlias := peer.LocalFeatures().HasFeature(
3395
                        lnwire.ScidAliasOptional,
70✔
3396
                )
35✔
3397
                remoteAlias := peer.RemoteFeatures().HasFeature(
36✔
3398
                        lnwire.ScidAliasOptional,
1✔
3399
                )
1✔
3400

3401
                // We could also refresh the channel state instead of checking
34✔
3402
                // whether the feature was negotiated, but this saves us a
34✔
3403
                // database read.
34✔
3404
                if channelReadyMsg.AliasScid == nil && localAlias &&
34✔
3405
                        remoteAlias {
34✔
3406

34✔
3407
                        // If an alias was not assigned above and the scid
34✔
3408
                        // alias feature was negotiated, check if we already
34✔
3409
                        // have an alias stored in case handleChannelReady was
34✔
3410
                        // called before this. If an alias exists, use that in
34✔
3411
                        // channel_ready. Otherwise, request and store an
34✔
3412
                        // alias and use that.
34✔
3413
                        aliases := f.cfg.AliasManager.GetAliases(
×
3414
                                completeChan.ShortChannelID,
×
3415
                        )
×
3416
                        if len(aliases) == 0 {
×
3417
                                // No aliases were found.
×
3418
                                alias, err := f.cfg.AliasManager.RequestAlias()
×
3419
                                if err != nil {
×
3420
                                        return err
×
3421
                                }
×
UNCOV
3422

×
3423
                                err = f.cfg.AliasManager.AddLocalAlias(
×
3424
                                        alias, completeChan.ShortChannelID,
×
3425
                                        false, false,
×
3426
                                )
×
3427
                                if err != nil {
×
3428
                                        return err
×
3429
                                }
UNCOV
3430

×
3431
                                channelReadyMsg.AliasScid = &alias
×
3432
                        } else {
×
3433
                                channelReadyMsg.AliasScid = &aliases[0]
×
3434
                        }
×
UNCOV
3435
                }
×
UNCOV
3436

×
3437
                log.Infof("Peer(%x) is online, sending ChannelReady "+
UNCOV
3438
                        "for ChannelID(%v)", peerKey, chanID)
×
UNCOV
3439

×
UNCOV
3440
                if err := peer.SendMessage(true, channelReadyMsg); err == nil {
×
UNCOV
3441
                        // Sending succeeded, we can break out and continue the
×
3442
                        // funding flow.
3443
                        break
3444
                }
34✔
3445

34✔
3446
                log.Warnf("Unable to send channelReady to peer %x: %v. "+
34✔
3447
                        "Will retry when online", peerKey, err)
68✔
3448
        }
34✔
3449

34✔
3450
        return nil
34✔
3451
}
3452

UNCOV
3453
// receivedChannelReady checks whether or not we've received a ChannelReady
×
UNCOV
3454
// from the remote peer. If we have, RemoteNextRevocation will be set.
×
3455
func (f *Manager) receivedChannelReady(node *btcec.PublicKey,
3456
        chanID lnwire.ChannelID) (bool, error) {
3457

34✔
3458
        // If the funding manager has exited, return an error to stop looping.
3459
        // Note that the peer may appear as online while the funding manager
3460
        // has stopped due to the shutdown order in the server.
3461
        select {
3462
        case <-f.quit:
3463
                return false, ErrFundingManagerShuttingDown
60✔
3464
        default:
60✔
3465
        }
60✔
3466

60✔
3467
        // Avoid a tight loop if peer is offline.
60✔
3468
        if _, err := f.waitForPeerOnline(node); err != nil {
60✔
3469
                log.Errorf("Wait for peer online failed: %v", err)
×
3470
                return false, err
×
3471
        }
60✔
3472

3473
        // If we cannot find the channel, then we haven't processed the
3474
        // remote's channelReady message.
3475
        channel, err := f.cfg.FindChannel(node, chanID)
60✔
UNCOV
3476
        if err != nil {
×
3477
                log.Errorf("Unable to locate ChannelID(%v) to determine if "+
×
3478
                        "ChannelReady was received", chanID)
×
3479
                return false, err
3480
        }
3481

3482
        // If we haven't insert the next revocation point, we haven't finished
60✔
3483
        // processing the channel ready message.
60✔
UNCOV
3484
        if channel.RemoteNextRevocation == nil {
×
UNCOV
3485
                return false, nil
×
UNCOV
3486
        }
×
UNCOV
3487

×
3488
        // Finally, the barrier signal is removed once we finish
3489
        // `handleChannelReady`. If we can still find the signal, we haven't
3490
        // finished processing it yet.
3491
        _, loaded := f.handleChannelReadyBarriers.Load(chanID)
96✔
3492

36✔
3493
        return !loaded, nil
36✔
3494
}
3495

3496
// extractAnnounceParams extracts the various channel announcement and update
3497
// parameters that will be needed to construct a ChannelAnnouncement and a
3498
// ChannelUpdate.
24✔
3499
func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) (
24✔
3500
        lnwire.MilliSatoshi, lnwire.MilliSatoshi) {
24✔
3501

3502
        // We'll obtain the min HTLC value we can forward in our direction, as
3503
        // we'll use this value within our ChannelUpdate. This constraint is
3504
        // originally set by the remote node, as it will be the one that will
3505
        // need to determine the smallest HTLC it deems economically relevant.
3506
        fwdMinHTLC := c.LocalChanCfg.MinHTLC
3507

26✔
3508
        // We don't necessarily want to go as low as the remote party allows.
26✔
3509
        // Check it against our default forwarding policy.
26✔
3510
        if fwdMinHTLC < f.cfg.DefaultRoutingPolicy.MinHTLCOut {
26✔
3511
                fwdMinHTLC = f.cfg.DefaultRoutingPolicy.MinHTLCOut
26✔
3512
        }
26✔
3513

26✔
3514
        // We'll obtain the max HTLC value we can forward in our direction, as
26✔
3515
        // we'll use this value within our ChannelUpdate. This value must be <=
26✔
3516
        // channel capacity and <= the maximum in-flight msats set by the peer.
26✔
3517
        fwdMaxHTLC := c.LocalChanCfg.MaxPendingAmount
26✔
UNCOV
3518
        capacityMSat := lnwire.NewMSatFromSatoshis(c.Capacity)
×
UNCOV
3519
        if fwdMaxHTLC > capacityMSat {
×
3520
                fwdMaxHTLC = capacityMSat
3521
        }
3522

3523
        return fwdMinHTLC, fwdMaxHTLC
3524
}
26✔
3525

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

3539
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
3540

3541
        fwdMinHTLC, fwdMaxHTLC := f.extractAnnounceParams(completeChan)
3542

3543
        ann, err := f.newChanAnnouncement(
3544
                f.cfg.IDKey, completeChan.IdentityPub,
26✔
3545
                &completeChan.LocalChanCfg.MultiSigKey,
26✔
3546
                completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
26✔
3547
                chanID, fwdMinHTLC, fwdMaxHTLC, ourPolicy,
26✔
3548
                completeChan.ChanType,
26✔
3549
        )
26✔
3550
        if err != nil {
26✔
3551
                return fmt.Errorf("error generating channel "+
26✔
3552
                        "announcement: %v", err)
26✔
3553
        }
26✔
3554

26✔
3555
        // Send ChannelAnnouncement and ChannelUpdate to the gossiper to add
26✔
3556
        // to the Router's topology.
26✔
3557
        errChan := f.cfg.SendAnnouncement(
26✔
UNCOV
3558
                ann.chanAnn, discovery.ChannelCapacity(completeChan.Capacity),
×
UNCOV
3559
                discovery.ChannelPoint(completeChan.FundingOutpoint),
×
UNCOV
3560
                discovery.TapscriptRoot(completeChan.TapscriptRoot),
×
3561
        )
3562
        select {
3563
        case err := <-errChan:
3564
                if err != nil {
26✔
3565
                        if graph.IsError(err, graph.ErrOutdated,
26✔
3566
                                graph.ErrIgnored) {
26✔
3567

26✔
3568
                                log.Debugf("Graph rejected "+
26✔
3569
                                        "ChannelAnnouncement: %v", err)
26✔
3570
                        } else {
26✔
3571
                                return fmt.Errorf("error sending channel "+
26✔
3572
                                        "announcement: %v", err)
×
3573
                        }
×
UNCOV
3574
                }
×
3575
        case <-f.quit:
×
3576
                return ErrFundingManagerShuttingDown
×
UNCOV
3577
        }
×
UNCOV
3578

×
UNCOV
3579
        errChan = f.cfg.SendAnnouncement(
×
UNCOV
3580
                ann.chanUpdateAnn, discovery.RemoteAlias(peerAlias),
×
3581
        )
UNCOV
3582
        select {
×
UNCOV
3583
        case err := <-errChan:
×
3584
                if err != nil {
3585
                        if graph.IsError(err, graph.ErrOutdated,
3586
                                graph.ErrIgnored) {
26✔
3587

26✔
3588
                                log.Debugf("Graph rejected "+
26✔
3589
                                        "ChannelUpdate: %v", err)
26✔
3590
                        } else {
26✔
3591
                                return fmt.Errorf("error sending channel "+
26✔
3592
                                        "update: %v", err)
×
3593
                        }
×
UNCOV
3594
                }
×
3595
        case <-f.quit:
×
3596
                return ErrFundingManagerShuttingDown
×
UNCOV
3597
        }
×
UNCOV
3598

×
UNCOV
3599
        return nil
×
UNCOV
3600
}
×
3601

UNCOV
3602
// annAfterSixConfs broadcasts the necessary channel announcement messages to
×
UNCOV
3603
// the network after 6 confs. Should be called after the channelReady message
×
3604
// is sent and the channel is added to the graph (channelState is
3605
// 'addedToGraph') and the channel is ready to be used. This is the last
3606
// step in the channel opening process, and the opening state will be deleted
26✔
3607
// from the database if successful.
3608
func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
3609
        shortChanID *lnwire.ShortChannelID) error {
3610

3611
        // If this channel is not meant to be announced to the greater network,
3612
        // we'll only send our NodeAnnouncement to our counterparty to ensure we
3613
        // don't leak any of our information.
3614
        announceChan := completeChan.ChannelFlags&lnwire.FFAnnounceChannel != 0
3615
        if !announceChan {
3616
                log.Debugf("Will not announce private channel %v.",
26✔
3617
                        shortChanID.ToUint64())
26✔
3618

26✔
3619
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
26✔
3620
                if err != nil {
26✔
3621
                        return err
26✔
3622
                }
34✔
3623

8✔
3624
                nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
8✔
3625
                if err != nil {
8✔
3626
                        return fmt.Errorf("unable to retrieve current node "+
8✔
3627
                                "announcement: %v", err)
8✔
3628
                }
×
UNCOV
3629

×
3630
                chanID := lnwire.NewChanIDFromOutPoint(
3631
                        completeChan.FundingOutpoint,
8✔
3632
                )
8✔
UNCOV
3633
                pubKey := peer.PubKey()
×
UNCOV
3634
                log.Debugf("Sending our NodeAnnouncement for "+
×
UNCOV
3635
                        "ChannelID(%v) to %x", chanID, pubKey)
×
3636

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

18✔
3657
                fundingScript, err := makeFundingScript(completeChan)
18✔
3658
                if err != nil {
18✔
3659
                        return fmt.Errorf("unable to create funding script "+
18✔
3660
                                "for ChannelPoint(%v): %v",
18✔
3661
                                completeChan.FundingOutpoint, err)
18✔
3662
                }
18✔
3663

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

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

16✔
UNCOV
3688
                case <-f.quit:
×
UNCOV
3689
                        return fmt.Errorf("%v, stopping funding flow for "+
×
UNCOV
3690
                                "ChannelPoint(%v)",
×
UNCOV
3691
                                ErrFundingManagerShuttingDown,
×
UNCOV
3692
                                completeChan.FundingOutpoint)
×
3693
                }
3694

3695
                fundingPoint := completeChan.FundingOutpoint
2✔
3696
                chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
2✔
3697

2✔
3698
                log.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
2✔
3699
                        &fundingPoint, shortChanID)
2✔
3700

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

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

UNCOV
3726
                        err = f.addToGraph(
×
UNCOV
3727
                                completeChan, &baseScid, nil, ourPolicy,
×
UNCOV
3728
                        )
×
UNCOV
3729
                        if err != nil {
×
3730
                                return fmt.Errorf("failed to re-add to "+
×
3731
                                        "graph: %v", err)
×
3732
                        }
UNCOV
3733
                }
×
UNCOV
3734

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

16✔
3748
                log.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
16✔
3749
                        "sent to gossiper", &fundingPoint, shortChanID)
16✔
3750
        }
16✔
UNCOV
3751

×
UNCOV
3752
        return nil
×
UNCOV
3753
}
×
3754

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

6✔
3769
        // We'll need to refresh the channel state so that things are properly
6✔
3770
        // populated when validating the channel state. Otherwise, a panic may
8✔
3771
        // occur due to inconsistency in the OpenChannel struct.
2✔
3772
        err = c.Refresh()
2✔
3773
        if err != nil {
2✔
3774
                return fmt.Errorf("unable to refresh channel state: %w", err)
2✔
3775
        }
3776

3777
        // Now that we have the confirmed transaction and the proper SCID,
3778
        // we'll call ValidateChannel to ensure the confirmed tx is properly
3779
        // formatted.
4✔
3780
        err = f.cfg.Wallet.ValidateChannel(c, confChan.fundingTx)
4✔
UNCOV
3781
        if err != nil {
×
3782
                return fmt.Errorf("unable to validate zero-conf channel: "+
×
3783
                        "%v", err)
3784
        }
3785

3786
        // Once we know the confirmed ShortChannelID, we'll need to save it to
3787
        // the database and refresh the OpenChannel struct with it.
4✔
3788
        err = c.MarkRealScid(confChan.shortChanID)
4✔
UNCOV
3789
        if err != nil {
×
3790
                return fmt.Errorf("unable to set confirmed SCID for zero "+
×
3791
                        "channel: %v", err)
×
3792
        }
3793

3794
        // Six confirmations have been reached. If this channel is public,
3795
        // we'll delete some of the alias mappings the gossiper uses.
4✔
3796
        isPublic := c.ChannelFlags&lnwire.FFAnnounceChannel != 0
4✔
UNCOV
3797
        if isPublic {
×
UNCOV
3798
                err = f.cfg.AliasManager.DeleteSixConfs(c.ShortChannelID)
×
UNCOV
3799
                if err != nil {
×
3800
                        return fmt.Errorf("unable to delete base alias after "+
3801
                                "six confirmations: %v", err)
3802
                }
3803

4✔
3804
                // TODO: Make this atomic!
6✔
3805
                ourPolicy, err := f.cfg.DeleteAliasEdge(c.ShortChanID())
2✔
3806
                if err != nil {
2✔
3807
                        return fmt.Errorf("unable to delete alias edge from "+
×
3808
                                "graph: %v", err)
×
3809
                }
×
3810

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

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

×
UNCOV
3837
        // Update the confirmed transaction's label.
×
UNCOV
3838
        f.makeLabelForTx(c)
×
UNCOV
3839

×
UNCOV
3840
        return nil
×
UNCOV
3841
}
×
UNCOV
3842

×
3843
// genFirstStateMusigNonce generates a nonces for the "first" local state. This
3844
// is the verification nonce for the state created for us after the initial
3845
// commitment transaction signed as part of the funding flow.
4✔
3846
func genFirstStateMusigNonce(channel *channeldb.OpenChannel,
4✔
3847
) (*musig2.Nonces, error) {
4✔
3848

3849
        musig2ShaChain, err := channeldb.DeriveMusig2Shachain(
3850
                channel.RevocationProducer,
3851
        )
3852
        if err != nil {
3853
                return nil, fmt.Errorf("unable to generate musig channel "+
3854
                        "nonces: %v", err)
4✔
3855
        }
4✔
3856

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

4✔
3869
        return verNonce, nil
4✔
3870
}
4✔
3871

4✔
UNCOV
3872
// handleChannelReady finalizes the channel funding process and enables the
×
UNCOV
3873
// channel to enter normal operating mode.
×
UNCOV
3874
func (f *Manager) handleChannelReady(peer lnpeer.Peer, //nolint:funlen
×
3875
        msg *lnwire.ChannelReady) {
3876

4✔
3877
        defer f.wg.Done()
3878

3879
        // If we are in development mode, we'll wait for specified duration
3880
        // before processing the channel ready message.
3881
        if f.cfg.Dev != nil {
3882
                duration := f.cfg.Dev.ProcessChannelReadyWait
28✔
3883
                log.Warnf("Channel(%v): sleeping %v before processing "+
28✔
3884
                        "channel_ready", msg.ChanID, duration)
28✔
3885

28✔
3886
                select {
28✔
3887
                case <-time.After(duration):
28✔
3888
                        log.Warnf("Channel(%v): slept %v before processing "+
28✔
UNCOV
3889
                                "channel_ready", msg.ChanID, duration)
×
3890
                case <-f.quit:
×
3891
                        log.Warnf("Channel(%v): quit sleeping", msg.ChanID)
×
3892
                        return
×
UNCOV
3893
                }
×
UNCOV
3894
        }
×
UNCOV
3895

×
UNCOV
3896
        log.Debugf("Received ChannelReady for ChannelID(%v) from "+
×
UNCOV
3897
                "peer %x", msg.ChanID,
×
UNCOV
3898
                peer.IdentityKey().SerializeCompressed())
×
UNCOV
3899

×
3900
        // We now load or create a new channel barrier for this channel.
3901
        _, loaded := f.handleChannelReadyBarriers.LoadOrStore(
3902
                msg.ChanID, struct{}{},
3903
        )
28✔
3904

28✔
3905
        // If we are currently in the process of handling a channel_ready
28✔
3906
        // message for this channel, ignore.
28✔
3907
        if loaded {
28✔
3908
                log.Infof("Already handling channelReady for "+
28✔
3909
                        "ChannelID(%v), ignoring.", msg.ChanID)
28✔
3910
                return
28✔
3911
        }
28✔
3912

28✔
3913
        // If not already handling channelReady for this channel, then the
28✔
3914
        // `LoadOrStore` has set up a barrier, and it will be removed once this
29✔
3915
        // function exits.
1✔
3916
        defer f.handleChannelReadyBarriers.Delete(msg.ChanID)
1✔
3917

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

25✔
3932
                // With the signal received, we can now safely delete the entry
25✔
3933
                // from the map.
25✔
3934
                f.localDiscoverySignals.Delete(msg.ChanID)
UNCOV
3935
        }
×
UNCOV
3936

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

27✔
3949
        // If this is a taproot channel, then we can generate the set of nonces
27✔
3950
        // the remote party needs to send the next remote commitment here.
27✔
UNCOV
3951
        var firstVerNonce *musig2.Nonces
×
UNCOV
3952
        if channel.ChanType.IsTaproot() {
×
UNCOV
3953
                firstVerNonce, err = genFirstStateMusigNonce(channel)
×
UNCOV
3954
                if err != nil {
×
3955
                        log.Error(err)
3956
                        return
3957
                }
3958
        }
27✔
3959

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

6✔
3977
                // We'll store the AliasScid so that invoice creation can use
6✔
UNCOV
3978
                // it.
×
UNCOV
3979
                err = f.cfg.AliasManager.PutPeerAlias(chanID, *msg.AliasScid)
×
UNCOV
3980
                if err != nil {
×
3981
                        log.Errorf("unable to store peer's alias: %v", err)
×
3982
                        return
×
3983
                }
3984

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

×
4002
                        err = f.cfg.AliasManager.AddLocalAlias(
×
4003
                                alias, channel.ShortChannelID, false, false,
×
4004
                        )
×
4005
                        if err != nil {
×
4006
                                log.Errorf("unable to add local alias: %v",
×
4007
                                        err)
×
4008
                                return
4009
                        }
×
UNCOV
4010

×
4011
                        secondPoint, err := channel.SecondCommitmentPoint()
×
4012
                        if err != nil {
×
4013
                                log.Errorf("unable to fetch second "+
×
4014
                                        "commitment point: %v", err)
×
4015
                                return
×
4016
                        }
×
4017

4018
                        channelReadyMsg := lnwire.NewChannelReady(
×
4019
                                chanID, secondPoint,
×
4020
                        )
×
4021
                        channelReadyMsg.AliasScid = &alias
×
4022

×
4023
                        if firstVerNonce != nil {
×
4024
                                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce( //nolint:lll
4025
                                        firstVerNonce.PubNonce,
×
4026
                                )
×
4027
                        }
×
UNCOV
4028

×
4029
                        err = peer.SendMessage(true, channelReadyMsg)
×
4030
                        if err != nil {
×
4031
                                log.Errorf("unable to send channel_ready: %v",
×
4032
                                        err)
×
4033
                                return
×
4034
                        }
×
4035
                }
UNCOV
4036
        }
×
UNCOV
4037

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

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

4✔
UNCOV
4068
                log.Infof("ChanID(%v): applying local+remote musig2 nonces",
×
UNCOV
4069
                        chanID)
×
UNCOV
4070

×
UNCOV
4071
                remoteNonce, err := msg.NextLocalNonce.UnwrapOrErrV(
×
UNCOV
4072
                        errNoLocalNonce,
×
4073
                )
4✔
4074
                if err != nil {
4✔
4075
                        cid := newChanIdentifier(msg.ChanID)
4✔
4076
                        f.sendWarning(peer, cid, err)
4✔
4077

4✔
4078
                        return
4✔
4079
                }
4✔
4080

4✔
4081
                chanOpts = append(
4✔
UNCOV
4082
                        chanOpts,
×
UNCOV
4083
                        lnwallet.WithLocalMusigNonces(localNonce),
×
UNCOV
4084
                        lnwallet.WithRemoteMusigNonces(&musig2.Nonces{
×
UNCOV
4085
                                PubNonce: remoteNonce,
×
UNCOV
4086
                        }),
×
4087
                )
4088

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

×
4106
                        return
×
4107
                }
×
4108
        }
4109

4✔
UNCOV
4110
        // The channel_ready message contains the next commitment point we'll
×
UNCOV
4111
        // need to create the next commitment state for the remote party. So
×
UNCOV
4112
        // we'll insert that into the channel now before passing it along to
×
UNCOV
4113
        // other sub-systems.
×
UNCOV
4114
        err = channel.InsertNextRevocation(msg.NextPerCommitmentPoint)
×
4115
        if err != nil {
4116
                log.Errorf("unable to insert next commitment point: %v", err)
4117
                return
4118
        }
4119

4120
        // Before we can add the channel to the peer, we'll need to ensure that
4121
        // we have an initial forwarding policy set.
26✔
4122
        if err := f.ensureInitialForwardingPolicy(chanID, channel); err != nil {
26✔
4123
                log.Errorf("Unable to ensure initial forwarding policy: %v",
×
4124
                        err)
×
4125
        }
×
4126

4127
        err = peer.AddNewChannel(&lnpeer.NewChannel{
4128
                OpenChannel: channel,
4129
                ChanOpts:    chanOpts,
26✔
UNCOV
4130
        }, f.quit)
×
UNCOV
4131
        if err != nil {
×
4132
                log.Errorf("Unable to add new channel %v with peer %x: %v",
×
4133
                        channel.FundingOutpoint,
4134
                        peer.IdentityKey().SerializeCompressed(), err,
26✔
4135
                )
26✔
4136
        }
26✔
4137
}
26✔
4138

26✔
UNCOV
4139
// handleChannelReadyReceived is called once the remote's channelReady message
×
UNCOV
4140
// is received and processed. At this stage, we must have sent out our
×
UNCOV
4141
// channelReady message, once the remote's channelReady is processed, the
×
UNCOV
4142
// channel is now active, thus we change its state to `addedToGraph` to
×
UNCOV
4143
// let the channel start handling routing.
×
4144
func (f *Manager) handleChannelReadyReceived(channel *channeldb.OpenChannel,
4145
        scid *lnwire.ShortChannelID, pendingChanID PendingChanID,
4146
        updateChan chan<- *lnrpc.OpenStatusUpdate) error {
4147

4148
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
4149

4150
        // Since we've sent+received funding locked at this point, we
4151
        // can clean up the pending musig2 nonce state.
4152
        f.nonceMtx.Lock()
4153
        delete(f.pendingMusigNonces, chanID)
24✔
4154
        f.nonceMtx.Unlock()
24✔
4155

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

4✔
4171
                peerAlias = &foundAlias
4✔
4172
        }
4✔
4173

4✔
4174
        err := f.addToGraph(channel, scid, peerAlias, nil)
4✔
UNCOV
4175
        if err != nil {
×
4176
                return fmt.Errorf("failed adding to graph: %w", err)
×
4177
        }
4178

4✔
4179
        // As the channel is now added to the ChannelRouter's topology, the
4180
        // channel is moved to the next state of the state machine. It will be
4181
        // moved to the last state (actually deleted from the database) after
24✔
4182
        // the channel is finally announced.
24✔
UNCOV
4183
        err = f.saveChannelOpeningState(
×
UNCOV
4184
                &channel.FundingOutpoint, addedToGraph, scid,
×
4185
        )
4186
        if err != nil {
4187
                return fmt.Errorf("error setting channel state to"+
4188
                        " addedToGraph: %w", err)
4189
        }
4190

24✔
4191
        log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
24✔
4192
                "added to graph", chanID, scid)
24✔
4193

24✔
UNCOV
4194
        err = fn.MapOptionZ(
×
UNCOV
4195
                f.cfg.AuxFundingController,
×
UNCOV
4196
                func(controller AuxFundingController) error {
×
4197
                        return controller.ChannelReady(
4198
                                lnwallet.NewAuxChanState(channel),
24✔
4199
                        )
24✔
4200
                },
24✔
4201
        )
24✔
4202
        if err != nil {
24✔
4203
                return fmt.Errorf("failed notifying aux funding controller "+
24✔
4204
                        "about channel ready: %w", err)
×
4205
        }
×
UNCOV
4206

×
UNCOV
4207
        // Give the caller a final update notifying them that the channel is
×
4208
        fundingPoint := channel.FundingOutpoint
4209
        cp := &lnrpc.ChannelPoint{
24✔
UNCOV
4210
                FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
×
UNCOV
4211
                        FundingTxidBytes: fundingPoint.Hash[:],
×
UNCOV
4212
                },
×
4213
                OutputIndex: fundingPoint.Index,
4214
        }
4215

24✔
4216
        if updateChan != nil {
24✔
4217
                upd := &lnrpc.OpenStatusUpdate{
24✔
4218
                        Update: &lnrpc.OpenStatusUpdate_ChanOpen{
24✔
4219
                                ChanOpen: &lnrpc.ChannelOpenUpdate{
24✔
4220
                                        ChannelPoint: cp,
24✔
4221
                                },
24✔
4222
                        },
24✔
4223
                        PendingChanId: pendingChanID[:],
34✔
4224
                }
10✔
4225

10✔
4226
                select {
10✔
4227
                case updateChan <- upd:
10✔
4228
                case <-f.quit:
10✔
4229
                        return ErrFundingManagerShuttingDown
10✔
4230
                }
10✔
4231
        }
10✔
4232

10✔
4233
        return nil
10✔
4234
}
10✔
UNCOV
4235

×
UNCOV
4236
// ensureInitialForwardingPolicy ensures that we have an initial forwarding
×
4237
// policy set for the given channel. If we don't, we'll fall back to the default
4238
// values.
4239
func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID,
4240
        channel *channeldb.OpenChannel) error {
24✔
4241

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

26✔
4252
                forwardingPolicy = f.defaultForwardingPolicy(
26✔
4253
                        channel.LocalChanCfg.ChannelStateBounds,
26✔
4254
                )
26✔
4255
                needDBUpdate = true
26✔
4256
        }
×
UNCOV
4257

×
UNCOV
4258
        // We only started storing the actual values for MinHTLCOut and MaxHTLC
×
UNCOV
4259
        // after 0.16.x, so if a channel was opened with such a version and is
×
UNCOV
4260
        // still pending while updating to this version, we'll need to set the
×
UNCOV
4261
        // values to the default values.
×
UNCOV
4262
        if forwardingPolicy.MinHTLCOut == 0 {
×
UNCOV
4263
                forwardingPolicy.MinHTLCOut = channel.LocalChanCfg.MinHTLC
×
4264
                needDBUpdate = true
4265
        }
4266
        if forwardingPolicy.MaxHTLC == 0 {
4267
                forwardingPolicy.MaxHTLC = channel.LocalChanCfg.MaxPendingAmount
4268
                needDBUpdate = true
4269
        }
39✔
4270

13✔
4271
        // And finally, if we found that the values currently stored aren't
13✔
4272
        // sufficient for the link, we'll update the database.
13✔
4273
        if needDBUpdate {
39✔
4274
                err := f.saveInitialForwardingPolicy(chanID, forwardingPolicy)
13✔
4275
                if err != nil {
13✔
4276
                        return fmt.Errorf("unable to update initial "+
13✔
4277
                                "forwarding policy: %v", err)
4278
                }
4279
        }
4280

39✔
4281
        return nil
13✔
4282
}
13✔
UNCOV
4283

×
UNCOV
4284
// chanAnnouncement encapsulates the two authenticated announcements that we
×
UNCOV
4285
// send out to the network after a new channel has been created locally.
×
4286
type chanAnnouncement struct {
4287
        chanAnn       *lnwire.ChannelAnnouncement1
4288
        chanUpdateAnn *lnwire.ChannelUpdate1
26✔
4289
        chanProof     *lnwire.AnnounceSignatures1
4290
}
4291

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

4307
        chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
4308

4309
        // The unconditional section of the announcement is the ShortChannelID
4310
        // itself which compactly encodes the location of the funding output
4311
        // within the blockchain.
4312
        chanAnn := &lnwire.ChannelAnnouncement1{
42✔
4313
                ShortChannelID: shortChanID,
42✔
4314
                Features:       lnwire.NewRawFeatureVector(),
42✔
4315
                ChainHash:      chainHash,
42✔
4316
        }
42✔
4317

42✔
4318
        // If this is a taproot channel, then we'll set a special bit in the
42✔
4319
        // feature vector to indicate to the routing layer that this needs a
42✔
4320
        // slightly different type of validation.
42✔
4321
        //
42✔
4322
        // TODO(roasbeef): temp, remove after gossip 1.5
42✔
4323
        if chanType.IsTaproot() {
42✔
4324
                log.Debugf("Applying taproot feature bit to "+
42✔
4325
                        "ChannelAnnouncement for %v", chanID)
42✔
4326

42✔
4327
                chanAnn.Features.Set(
42✔
4328
                        lnwire.SimpleTaprootChannelsRequiredStaging,
42✔
4329
                )
42✔
4330
        }
46✔
4331

4✔
4332
        // The chanFlags field indicates which directed edge of the channel is
4✔
4333
        // being updated within the ChannelUpdateAnnouncement announcement
4✔
4334
        // below. A value of zero means it's the edge of the "first" node and 1
4✔
4335
        // being the other node.
4✔
4336
        var chanFlags lnwire.ChanUpdateChanFlags
4✔
4337

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

21✔
4356
                // If we're the first node then update the chanFlags to
21✔
4357
                // indicate the "direction" of the update.
21✔
4358
                chanFlags = 0
21✔
4359
        } else {
21✔
4360
                copy(chanAnn.NodeID1[:], remotePubKey.SerializeCompressed())
21✔
4361
                copy(chanAnn.NodeID2[:], localPubKey.SerializeCompressed())
21✔
4362
                copy(
21✔
4363
                        chanAnn.BitcoinKey1[:],
21✔
4364
                        remoteFundingKey.SerializeCompressed(),
21✔
4365
                )
21✔
4366
                copy(
42✔
4367
                        chanAnn.BitcoinKey2[:],
21✔
4368
                        localFundingKey.PubKey.SerializeCompressed(),
21✔
4369
                )
21✔
4370

21✔
4371
                // If we're the second node then update the chanFlags to
21✔
4372
                // indicate the "direction" of the update.
21✔
4373
                chanFlags = 1
21✔
4374
        }
21✔
4375

21✔
4376
        // Our channel update message flags will signal that we support the
21✔
4377
        // max_htlc field.
21✔
4378
        msgFlags := lnwire.ChanUpdateRequiredMaxHtlc
21✔
4379

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

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

42✔
4405
        switch {
42✔
4406
        case ourPolicy != nil:
42✔
4407
                // If ourPolicy is non-nil, modify the default parameters of the
42✔
UNCOV
4408
                // ChannelUpdate.
×
UNCOV
4409
                chanUpdateAnn.MessageFlags = ourPolicy.MessageFlags
×
UNCOV
4410
                chanUpdateAnn.ChannelFlags = ourPolicy.ChannelFlags
×
4411
                chanUpdateAnn.TimeLockDelta = ourPolicy.TimeLockDelta
4412
                chanUpdateAnn.HtlcMinimumMsat = ourPolicy.MinHTLC
42✔
UNCOV
4413
                chanUpdateAnn.HtlcMaximumMsat = ourPolicy.MaxHTLC
×
UNCOV
4414
                chanUpdateAnn.BaseFee = uint32(ourPolicy.FeeBaseMSat)
×
UNCOV
4415
                chanUpdateAnn.FeeRate = uint32(
×
UNCOV
4416
                        ourPolicy.FeeProportionalMillionths,
×
UNCOV
4417
                )
×
UNCOV
4418

×
UNCOV
4419
        case storedFwdingPolicy != nil:
×
UNCOV
4420
                chanUpdateAnn.BaseFee = uint32(storedFwdingPolicy.BaseFee)
×
UNCOV
4421
                chanUpdateAnn.FeeRate = uint32(storedFwdingPolicy.FeeRate)
×
UNCOV
4422

×
4423
        default:
×
4424
                log.Infof("No channel forwarding policy specified for channel "+
×
4425
                        "announcement of ChannelID(%v). "+
4426
                        "Assuming default fee parameters.", chanID)
42✔
4427
                chanUpdateAnn.BaseFee = uint32(
42✔
4428
                        f.cfg.DefaultRoutingPolicy.BaseFee,
42✔
4429
                )
4430
                chanUpdateAnn.FeeRate = uint32(
×
4431
                        f.cfg.DefaultRoutingPolicy.FeeRate,
×
4432
                )
×
UNCOV
4433
        }
×
UNCOV
4434

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

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

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

42✔
UNCOV
4494
        return &chanAnnouncement{
×
UNCOV
4495
                chanAnn:       chanAnn,
×
4496
                chanUpdateAnn: chanUpdateAnn,
42✔
4497
                chanProof:     proof,
42✔
UNCOV
4498
        }, nil
×
UNCOV
4499
}
×
4500

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

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

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

4540
                                log.Debugf("Graph rejected "+
16✔
4541
                                        "AnnounceSignatures: %v", err)
16✔
4542
                        } else {
16✔
4543
                                log.Errorf("Unable to send channel "+
16✔
UNCOV
4544
                                        "proof: %v", err)
×
UNCOV
4545
                                return err
×
UNCOV
4546
                        }
×
UNCOV
4547
                }
×
UNCOV
4548

×
4549
        case <-f.quit:
×
4550
                return ErrFundingManagerShuttingDown
×
UNCOV
4551
        }
×
UNCOV
4552

×
UNCOV
4553
        // Now that the channel is announced to the network, we will also
×
4554
        // obtain and send a node announcement. This is done since a node
4555
        // announcement is only accepted after a channel is known for that
UNCOV
4556
        // particular node, and this might be our first channel.
×
UNCOV
4557
        nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
×
4558
        if err != nil {
4559
                log.Errorf("can't generate node announcement: %v", err)
4560
                return err
4561
        }
4562

4563
        errChan = f.cfg.SendAnnouncement(&nodeAnn)
4564
        select {
16✔
4565
        case err := <-errChan:
16✔
UNCOV
4566
                if err != nil {
×
UNCOV
4567
                        if graph.IsError(err, graph.ErrOutdated,
×
UNCOV
4568
                                graph.ErrIgnored) {
×
4569

4570
                                log.Debugf("Graph rejected "+
16✔
4571
                                        "NodeAnnouncement: %v", err)
16✔
4572
                        } else {
16✔
4573
                                log.Errorf("Unable to send node "+
16✔
4574
                                        "announcement: %v", err)
×
4575
                                return err
×
4576
                        }
×
UNCOV
4577
                }
×
UNCOV
4578

×
4579
        case <-f.quit:
×
4580
                return ErrFundingManagerShuttingDown
×
UNCOV
4581
        }
×
UNCOV
4582

×
UNCOV
4583
        return nil
×
4584
}
4585

UNCOV
4586
// InitFundingWorkflow sends a message to the funding manager instructing it
×
UNCOV
4587
// to initiate a single funder workflow with the source peer.
×
4588
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
4589
        f.fundingRequests <- msg
4590
}
16✔
4591

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

4604
        // Check whether the remote peer supports upfront shutdown scripts.
4605
        remoteUpfrontShutdown := peer.RemoteFeatures().HasFeature(
4606
                lnwire.UpfrontShutdownScriptOptional,
4607
        )
4608

4609
        // If the peer does not support upfront shutdown scripts, and one has been
108✔
4610
        // provided, return an error because the feature is not supported.
108✔
4611
        if !remoteUpfrontShutdown && len(script) != 0 {
108✔
4612
                return nil, errUpfrontShutdownScriptNotSupported
108✔
4613
        }
108✔
4614

108✔
4615
        // If the peer does not support upfront shutdown, return an empty address.
108✔
4616
        if !remoteUpfrontShutdown {
108✔
4617
                return nil, nil
108✔
4618
        }
109✔
4619

1✔
4620
        // If the user has provided an script and the peer supports the feature,
1✔
4621
        // return it. Note that user set scripts override the enable upfront
4622
        // shutdown flag.
4623
        if len(script) > 0 {
210✔
4624
                return script, nil
103✔
4625
        }
103✔
4626

4627
        // If we do not have setting of upfront shutdown script enabled, return
4628
        // an empty script.
4629
        if !enableUpfrontShutdown {
4630
                return nil, nil
6✔
4631
        }
2✔
4632

2✔
4633
        // We can safely send a taproot address iff, both sides have negotiated
4634
        // the shutdown-any-segwit feature.
4635
        taprootOK := peer.RemoteFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) &&
4636
                peer.LocalFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional)
3✔
4637

1✔
4638
        return getScript(taprootOK)
1✔
4639
}
4640

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

56✔
4659
        // If no maximum CSV delay was set for this channel, we use our default
56✔
4660
        // value.
56✔
4661
        if maxCSV == 0 {
56✔
4662
                maxCSV = f.cfg.MaxLocalCSVDelay
56✔
4663
        }
56✔
4664

56✔
4665
        log.Infof("Initiating fundingRequest(local_amt=%v "+
56✔
4666
                "(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
56✔
4667
                "min_confs=%v)", localAmt, msg.SubtractFees, msg.PushAmt,
56✔
4668
                msg.ChainHash, peerKey.SerializeCompressed(), msg.MinConfs)
112✔
4669

56✔
4670
        // We set the channel flags to indicate whether we want this channel to
56✔
4671
        // be announced to the network.
4672
        var channelFlags lnwire.FundingFlag
56✔
4673
        if !msg.Private {
56✔
4674
                // This channel will be announced.
56✔
4675
                channelFlags = lnwire.FFAnnounceChannel
56✔
4676
        }
56✔
4677

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

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

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

56✔
4726
        var (
56✔
4727
                zeroConf bool
56✔
UNCOV
4728
                scid     bool
×
UNCOV
4729
        )
×
UNCOV
4730

×
UNCOV
4731
        if chanType != nil {
×
4732
                // Check if the returned chanType includes either the zero-conf
4733
                // or scid-alias bits.
56✔
4734
                featureVec := lnwire.RawFeatureVector(*chanType)
56✔
4735
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
56✔
4736
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
56✔
4737

56✔
4738
                // The option-scid-alias channel type for a public channel is
60✔
4739
                // disallowed.
4✔
4740
                if scid && !msg.Private {
4✔
4741
                        err = fmt.Errorf("option-scid-alias chantype for " +
4✔
4742
                                "public channel")
4✔
4743
                        log.Error(err)
4✔
4744
                        msg.Err <- err
4✔
4745

4✔
4746
                        return
4✔
4747
                }
4✔
UNCOV
4748
        }
×
UNCOV
4749

×
UNCOV
4750
        // First, we'll query the fee estimator for a fee that should get the
×
UNCOV
4751
        // commitment transaction confirmed by the next few blocks (conf target
×
UNCOV
4752
        // of 3). We target the near blocks here to ensure that we'll be able
×
UNCOV
4753
        // to execute a timely unilateral channel closure if needed.
×
UNCOV
4754
        commitFeePerKw, err := f.cfg.FeeEstimator.EstimateFeePerKW(3)
×
4755
        if err != nil {
4756
                msg.Err <- err
4757
                return
4758
        }
4759

4760
        // For anchor channels cap the initial commit fee rate at our defined
4761
        // maximum.
56✔
4762
        if commitType.HasAnchors() &&
56✔
UNCOV
4763
                commitFeePerKw > f.cfg.MaxAnchorsCommitFeeRate {
×
UNCOV
4764

×
UNCOV
4765
                commitFeePerKw = f.cfg.MaxAnchorsCommitFeeRate
×
4766
        }
4767

4768
        var scidFeatureVal bool
4769
        if hasFeatures(
56✔
4770
                msg.Peer.LocalFeatures(), msg.Peer.RemoteFeatures(),
60✔
4771
                lnwire.ScidAliasOptional,
4✔
4772
        ) {
4✔
4773

4✔
4774
                scidFeatureVal = true
4775
        }
56✔
4776

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

×
4791
                return
×
4792
        }
4793

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

113✔
4824
                        // Query the sweeper storage to make sure we don't use
57✔
4825
                        // an unconfirmed utxo still in use by the sweeper
57✔
4826
                        // subsystem.
57✔
4827
                        return !f.cfg.IsSweeperOutpoint(u.OutPoint)
57✔
UNCOV
4828
                },
×
UNCOV
4829
                ZeroConf:         zeroConf,
×
4830
                OptionScidAlias:  scid,
4831
                ScidAliasFeature: scidFeatureVal,
4832
                Memo:             msg.Memo,
4833
                TapscriptRoot:    tapscriptRoot,
4834
        }
57✔
4835

4836
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
4837
        if err != nil {
4838
                msg.Err <- err
4839
                return
4840
        }
4841

4842
        if zeroConf {
4843
                // Store the alias for zero-conf channels in the underlying
56✔
4844
                // partial channel state.
56✔
UNCOV
4845
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
×
UNCOV
4846
                if err != nil {
×
4847
                        msg.Err <- err
×
4848
                        return
4849
                }
58✔
4850

2✔
4851
                reservation.AddAlias(aliasScid)
2✔
4852
        }
2✔
4853

2✔
UNCOV
4854
        // Set our upfront shutdown address in the existing reservation.
×
UNCOV
4855
        reservation.SetOurUpfrontShutdown(shutdown)
×
UNCOV
4856

×
4857
        // Now that we have successfully reserved funds for this channel in the
4858
        // wallet, we can fetch the final channel capacity. This is done at
2✔
4859
        // this point since the final capacity might change in case of
4860
        // SubtractFees=true.
4861
        capacity := reservation.Capacity()
4862

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

56✔
4866
        // If the remote CSV delay was not set in the open channel request,
56✔
4867
        // we'll use the RequiredRemoteDelay closure to compute the delay we
56✔
4868
        // require given the total amount of funds within the channel.
56✔
4869
        if remoteCsvDelay == 0 {
56✔
4870
                remoteCsvDelay = f.cfg.RequiredRemoteDelay(capacity)
56✔
4871
        }
56✔
4872

56✔
4873
        // If no minimum HTLC value was specified, use the default one.
56✔
4874
        if minHtlcIn == 0 {
56✔
4875
                minHtlcIn = f.cfg.DefaultMinHtlcIn
56✔
4876
        }
111✔
4877

55✔
4878
        // If no max value was specified, use the default one.
55✔
4879
        if maxValue == 0 {
4880
                maxValue = f.cfg.RequiredRemoteMaxValue(capacity)
4881
        }
111✔
4882

55✔
4883
        if maxHtlcs == 0 {
55✔
4884
                maxHtlcs = f.cfg.RequiredRemoteMaxHTLCs(capacity)
4885
        }
4886

111✔
4887
        // Once the reservation has been created, and indexed, queue a funding
55✔
4888
        // request to the remote peer, kicking off the funding workflow.
55✔
4889
        ourContribution := reservation.OurContribution()
4890

112✔
4891
        // Prepare the optional channel fee values from the initFundingMsg. If
56✔
4892
        // useBaseFee or useFeeRate are false the client did not provide fee
56✔
4893
        // values hence we assume default fee settings from the config.
4894
        forwardingPolicy := f.defaultForwardingPolicy(
4895
                ourContribution.ChannelStateBounds,
4896
        )
56✔
4897
        if baseFee != nil {
56✔
4898
                forwardingPolicy.BaseFee = lnwire.MilliSatoshi(*baseFee)
56✔
4899
        }
56✔
4900

56✔
4901
        if feeRate != nil {
56✔
4902
                forwardingPolicy.FeeRate = lnwire.MilliSatoshi(*feeRate)
56✔
4903
        }
56✔
4904

57✔
4905
        // Fetch our dust limit which is part of the default channel
1✔
4906
        // constraints, and log it.
1✔
4907
        ourDustLimit := ourContribution.DustLimit
4908

57✔
4909
        log.Infof("Dust limit for pendingID(%x): %v", chanID, ourDustLimit)
1✔
4910

1✔
4911
        // If the channel reserve is not specified, then we calculate an
4912
        // appropriate amount here.
4913
        if chanReserve == 0 {
4914
                chanReserve = f.cfg.RequiredRemoteChanReserve(
56✔
4915
                        capacity, ourDustLimit,
56✔
4916
                )
56✔
4917
        }
56✔
4918

56✔
4919
        // If a pending channel map for this peer isn't already created, then
56✔
4920
        // we create one, ultimately allowing us to track this pending
108✔
4921
        // reservation within the target peer.
52✔
4922
        peerIDKey := newSerializedKey(peerKey)
52✔
4923
        f.resMtx.Lock()
52✔
4924
        if _, ok := f.activeReservations[peerIDKey]; !ok {
52✔
4925
                f.activeReservations[peerIDKey] = make(pendingChannels)
4926
        }
4927

4928
        resCtx := &reservationWithCtx{
4929
                chanAmt:           capacity,
56✔
4930
                forwardingPolicy:  *forwardingPolicy,
56✔
4931
                remoteCsvDelay:    remoteCsvDelay,
105✔
4932
                remoteMinHtlc:     minHtlcIn,
49✔
4933
                remoteMaxValue:    maxValue,
49✔
4934
                remoteMaxHtlcs:    maxHtlcs,
4935
                remoteChanReserve: chanReserve,
56✔
4936
                maxLocalCsv:       maxCSV,
56✔
4937
                channelType:       chanType,
56✔
4938
                reservation:       reservation,
56✔
4939
                peer:              msg.Peer,
56✔
4940
                updates:           msg.Updates,
56✔
4941
                err:               msg.Err,
56✔
4942
        }
56✔
4943
        f.activeReservations[peerIDKey][chanID] = resCtx
56✔
4944
        f.resMtx.Unlock()
56✔
4945

56✔
4946
        // Update the timestamp once the InitFundingMsg has been handled.
56✔
4947
        defer resCtx.updateTimestamp()
56✔
4948

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

56✔
4970
                msg.Err <- err
58✔
4971
                return
2✔
4972
        }
2✔
UNCOV
4973

×
UNCOV
4974
        // When opening a script enforced channel lease, include the required
×
UNCOV
4975
        // expiry TLV record in our proposal.
×
4976
        var leaseExpiry *lnwire.LeaseExpiry
4977
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
2✔
4978
                leaseExpiry = new(lnwire.LeaseExpiry)
2✔
4979
                *leaseExpiry = lnwire.LeaseExpiry(reservation.LeaseExpiry())
4980
        }
4981

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

54✔
UNCOV
4985
        reservation.SetState(lnwallet.SentOpenChannel)
×
UNCOV
4986

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

54✔
5011
        if commitType.IsTaproot() {
54✔
5012
                fundingOpen.LocalNonce = lnwire.SomeMusig2Nonce(
54✔
5013
                        ourContribution.LocalNonce.PubNonce,
54✔
5014
                )
54✔
5015
        }
54✔
5016

54✔
5017
        if err := msg.Peer.SendMessage(true, &fundingOpen); err != nil {
54✔
5018
                e := fmt.Errorf("unable to send funding request message: %w",
56✔
5019
                        err)
2✔
5020
                log.Errorf(e.Error())
2✔
5021

2✔
5022
                // Since we were unable to send the initial message to the peer
2✔
5023
                // and start the funding flow, we'll cancel this reservation.
5024
                _, err := f.cancelReservationCtx(peerKey, chanID, false)
54✔
5025
                if err != nil {
×
5026
                        log.Errorf("unable to cancel reservation: %v", err)
×
5027
                }
×
UNCOV
5028

×
5029
                msg.Err <- e
×
5030
                return
×
UNCOV
5031
        }
×
UNCOV
5032
}
×
UNCOV
5033

×
UNCOV
5034
// handleWarningMsg processes the warning which was received from remote peer.
×
5035
func (f *Manager) handleWarningMsg(peer lnpeer.Peer, msg *lnwire.Warning) {
UNCOV
5036
        log.Warnf("received warning message from peer %x: %v",
×
UNCOV
5037
                peer.IdentityKey().SerializeCompressed(), msg.Warning())
×
5038
}
5039

5040
// handleErrorMsg processes the error which was received from remote peer,
5041
// depending on the type of error we should do different clean up steps and
5042
// inform the user about it.
42✔
5043
func (f *Manager) handleErrorMsg(peer lnpeer.Peer, msg *lnwire.Error) {
42✔
5044
        chanID := msg.ChanID
42✔
5045
        peerKey := peer.IdentityKey()
42✔
5046

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

×
UNCOV
5057
        // If we did indeed find the funding workflow, then we'll return the
×
UNCOV
5058
        // error back to the caller (if any), and cancel the workflow itself.
×
UNCOV
5059
        fundingErr := fmt.Errorf("received funding error from %x: %v",
×
UNCOV
5060
                peerKey.SerializeCompressed(), msg.Error(),
×
UNCOV
5061
        )
×
UNCOV
5062
        log.Errorf(fundingErr.Error())
×
5063

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

×
UNCOV
5072
        resCtx.err <- fundingErr
×
UNCOV
5073
}
×
UNCOV
5074

×
UNCOV
5075
// pruneZombieReservations loops through all pending reservations and fails the
×
UNCOV
5076
// funding flow for any reservations that have not been updated since the
×
UNCOV
5077
// ReservationTimeout and are not locked waiting for the funding transaction.
×
5078
func (f *Manager) pruneZombieReservations() {
UNCOV
5079
        zombieReservations := make(pendingChannels)
×
5080

5081
        f.resMtx.RLock()
5082
        for _, pendingReservations := range f.activeReservations {
5083
                for pendingChanID, resCtx := range pendingReservations {
5084
                        if resCtx.isLocked() {
5085
                                continue
3✔
5086
                        }
3✔
5087

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

3✔
5102
        for pendingChanID, resCtx := range zombieReservations {
6✔
5103
                err := fmt.Errorf("reservation timed out waiting for peer "+
3✔
5104
                        "(peer_id:%x, chan_id:%x)",
3✔
5105
                        resCtx.peer.IdentityKey().SerializeCompressed(),
5106
                        pendingChanID[:])
5107
                log.Warnf(err.Error())
3✔
5108

3✔
5109
                chanID := lnwire.NewChanIDFromOutPoint(
6✔
5110
                        *resCtx.reservation.FundingOutpoint(),
3✔
5111
                )
3✔
5112

3✔
5113
                // Create channel identifier and set the channel ID.
3✔
5114
                cid := newChanIdentifier(pendingChanID)
3✔
5115
                cid.setChanID(chanID)
3✔
5116

3✔
5117
                f.failFundingFlow(resCtx.peer, cid, err)
3✔
5118
        }
3✔
5119
}
3✔
5120

3✔
5121
// cancelReservationCtx does all needed work in order to securely cancel the
3✔
5122
// reservation.
3✔
5123
func (f *Manager) cancelReservationCtx(peerKey *btcec.PublicKey,
3✔
5124
        pendingChanID PendingChanID,
3✔
5125
        byRemote bool) (*reservationWithCtx, error) {
3✔
5126

5127
        log.Infof("Cancelling funding reservation for node_key=%x, "+
5128
                "chan_id=%x", peerKey.SerializeCompressed(), pendingChanID[:])
5129

5130
        peerIDKey := newSerializedKey(peerKey)
5131
        f.resMtx.Lock()
5132
        defer f.resMtx.Unlock()
23✔
5133

23✔
5134
        nodeReservations, ok := f.activeReservations[peerIDKey]
23✔
5135
        if !ok {
23✔
5136
                // No reservations for this node.
23✔
5137
                return nil, errors.Errorf("no active reservations for peer(%x)",
23✔
5138
                        peerIDKey[:])
23✔
5139
        }
23✔
5140

23✔
5141
        ctx, ok := nodeReservations[pendingChanID]
23✔
5142
        if !ok {
30✔
5143
                return nil, errors.Errorf("unknown channel (id: %x) for "+
7✔
5144
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
7✔
5145
        }
7✔
5146

7✔
5147
        // If the reservation was a PSBT funding flow and it was canceled by the
5148
        // remote peer, then we need to thread through a different error message
16✔
5149
        // to the subroutine that's waiting for the user input so it can return
18✔
5150
        // a nice error message to the user.
2✔
5151
        if ctx.reservation.IsPsbt() && byRemote {
2✔
5152
                ctx.reservation.RemoteCanceled()
2✔
5153
        }
5154

5155
        if err := ctx.reservation.Cancel(); err != nil {
5156
                return nil, errors.Errorf("unable to cancel reservation: %v",
5157
                        err)
5158
        }
14✔
UNCOV
5159

×
UNCOV
5160
        delete(nodeReservations, pendingChanID)
×
5161

5162
        // If this was the last active reservation for this peer, delete the
14✔
UNCOV
5163
        // peer's entry altogether.
×
UNCOV
5164
        if len(nodeReservations) == 0 {
×
UNCOV
5165
                delete(f.activeReservations, peerIDKey)
×
5166
        }
5167
        return ctx, nil
14✔
5168
}
14✔
5169

14✔
5170
// deleteReservationCtx deletes the reservation uniquely identified by the
14✔
5171
// target public key of the peer, and the specified pending channel ID.
28✔
5172
func (f *Manager) deleteReservationCtx(peerKey *btcec.PublicKey,
14✔
5173
        pendingChanID PendingChanID) {
14✔
5174

14✔
5175
        peerIDKey := newSerializedKey(peerKey)
5176
        f.resMtx.Lock()
5177
        defer f.resMtx.Unlock()
5178

5179
        nodeReservations, ok := f.activeReservations[peerIDKey]
5180
        if !ok {
54✔
5181
                // No reservations for this node.
54✔
5182
                return
54✔
5183
        }
54✔
5184
        delete(nodeReservations, pendingChanID)
54✔
5185

54✔
5186
        // If this was the last active reservation for this peer, delete the
54✔
5187
        // peer's entry altogether.
54✔
UNCOV
5188
        if len(nodeReservations) == 0 {
×
UNCOV
5189
                delete(f.activeReservations, peerIDKey)
×
UNCOV
5190
        }
×
5191
}
54✔
5192

54✔
5193
// getReservationCtx returns the reservation context for a particular pending
54✔
5194
// channel ID for a target peer.
54✔
5195
func (f *Manager) getReservationCtx(peerKey *btcec.PublicKey,
101✔
5196
        pendingChanID PendingChanID) (*reservationWithCtx, error) {
47✔
5197

47✔
5198
        peerIDKey := newSerializedKey(peerKey)
5199
        f.resMtx.RLock()
5200
        resCtx, ok := f.activeReservations[peerIDKey][pendingChanID]
5201
        f.resMtx.RUnlock()
5202

5203
        if !ok {
88✔
5204
                return nil, errors.Errorf("unknown channel (id: %x) for "+
88✔
5205
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
88✔
5206
        }
88✔
5207

88✔
5208
        return resCtx, nil
88✔
5209
}
88✔
5210

88✔
UNCOV
5211
// IsPendingChannel returns a boolean indicating whether the channel identified
×
UNCOV
5212
// by the pendingChanID and given peer is pending, meaning it is in the process
×
UNCOV
5213
// of being funded. After the funding transaction has been confirmed, the
×
5214
// channel will receive a new, permanent channel ID, and will no longer be
5215
// considered pending.
88✔
5216
func (f *Manager) IsPendingChannel(pendingChanID PendingChanID,
5217
        peer lnpeer.Peer) bool {
5218

5219
        peerIDKey := newSerializedKey(peer.IdentityKey())
5220
        f.resMtx.RLock()
5221
        _, ok := f.activeReservations[peerIDKey][pendingChanID]
5222
        f.resMtx.RUnlock()
5223

UNCOV
5224
        return ok
×
UNCOV
5225
}
×
UNCOV
5226

×
UNCOV
5227
func copyPubKey(pub *btcec.PublicKey) *btcec.PublicKey {
×
UNCOV
5228
        var tmp btcec.JacobianPoint
×
UNCOV
5229
        pub.AsJacobian(&tmp)
×
UNCOV
5230
        tmp.ToAffine()
×
UNCOV
5231
        return btcec.NewPublicKey(&tmp.X, &tmp.Y)
×
UNCOV
5232
}
×
5233

5234
// defaultForwardingPolicy returns the default forwarding policy based on the
375✔
5235
// default routing policy and our local channel constraints.
375✔
5236
func (f *Manager) defaultForwardingPolicy(
375✔
5237
        bounds channeldb.ChannelStateBounds) *models.ForwardingPolicy {
375✔
5238

375✔
5239
        return &models.ForwardingPolicy{
375✔
5240
                MinHTLCOut:    bounds.MinHTLC,
5241
                MaxHTLC:       bounds.MaxPendingAmount,
5242
                BaseFee:       f.cfg.DefaultRoutingPolicy.BaseFee,
5243
                FeeRate:       f.cfg.DefaultRoutingPolicy.FeeRate,
5244
                TimeLockDelta: f.cfg.DefaultRoutingPolicy.TimeLockDelta,
102✔
5245
        }
102✔
5246
}
102✔
5247

102✔
5248
// saveInitialForwardingPolicy saves the forwarding policy for the provided
102✔
5249
// chanPoint in the channelOpeningStateBucket.
102✔
5250
func (f *Manager) saveInitialForwardingPolicy(chanID lnwire.ChannelID,
102✔
5251
        forwardingPolicy *models.ForwardingPolicy) error {
102✔
5252

102✔
5253
        return f.cfg.ChannelDB.SaveInitialForwardingPolicy(
102✔
5254
                chanID, forwardingPolicy,
5255
        )
5256
}
5257

5258
// getInitialForwardingPolicy fetches the initial forwarding policy for a given
67✔
5259
// channel id from the database which will be applied during the channel
67✔
5260
// announcement phase.
67✔
5261
func (f *Manager) getInitialForwardingPolicy(
67✔
5262
        chanID lnwire.ChannelID) (*models.ForwardingPolicy, error) {
67✔
5263

67✔
5264
        return f.cfg.ChannelDB.GetInitialForwardingPolicy(chanID)
5265
}
5266

5267
// deleteInitialForwardingPolicy removes channel fees for this chanID from
5268
// the database.
5269
func (f *Manager) deleteInitialForwardingPolicy(chanID lnwire.ChannelID) error {
94✔
5270
        return f.cfg.ChannelDB.DeleteInitialForwardingPolicy(chanID)
94✔
5271
}
94✔
5272

94✔
5273
// saveChannelOpeningState saves the channelOpeningState for the provided
5274
// chanPoint to the channelOpeningStateBucket.
5275
func (f *Manager) saveChannelOpeningState(chanPoint *wire.OutPoint,
5276
        state channelOpeningState, shortChanID *lnwire.ShortChannelID) error {
24✔
5277

24✔
5278
        var outpointBytes bytes.Buffer
24✔
5279
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
5280
                return err
5281
        }
5282

5283
        // Save state and the uint64 representation of the shortChanID
92✔
5284
        // for later use.
92✔
5285
        scratch := make([]byte, 10)
92✔
5286
        byteOrder.PutUint16(scratch[:2], uint16(state))
92✔
UNCOV
5287
        byteOrder.PutUint64(scratch[2:], shortChanID.ToUint64())
×
UNCOV
5288

×
5289
        return f.cfg.ChannelDB.SaveChannelOpeningState(
5290
                outpointBytes.Bytes(), scratch,
5291
        )
5292
}
92✔
5293

92✔
5294
// getChannelOpeningState fetches the channelOpeningState for the provided
92✔
5295
// chanPoint from the database, or returns ErrChannelNotFound if the channel
92✔
5296
// is not found.
92✔
5297
func (f *Manager) getChannelOpeningState(chanPoint *wire.OutPoint) (
92✔
5298
        channelOpeningState, *lnwire.ShortChannelID, error) {
92✔
5299

5300
        var outpointBytes bytes.Buffer
5301
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
5302
                return 0, nil, err
5303
        }
5304

5305
        value, err := f.cfg.ChannelDB.GetChannelOpeningState(
252✔
5306
                outpointBytes.Bytes(),
252✔
5307
        )
252✔
5308
        if err != nil {
252✔
UNCOV
5309
                return 0, nil, err
×
UNCOV
5310
        }
×
5311

5312
        state := channelOpeningState(byteOrder.Uint16(value[:2]))
252✔
5313
        shortChanID := lnwire.NewShortChanIDFromInt(byteOrder.Uint64(value[2:]))
252✔
5314
        return state, &shortChanID, nil
252✔
5315
}
299✔
5316

47✔
5317
// deleteChannelOpeningState removes any state for chanPoint from the database.
47✔
5318
func (f *Manager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error {
5319
        var outpointBytes bytes.Buffer
205✔
5320
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
205✔
5321
                return err
205✔
5322
        }
5323

5324
        return f.cfg.ChannelDB.DeleteChannelOpeningState(
5325
                outpointBytes.Bytes(),
24✔
5326
        )
24✔
5327
}
24✔
UNCOV
5328

×
UNCOV
5329
// selectShutdownScript selects the shutdown script we should send to the peer.
×
5330
// If we can use taproot, then we prefer that, otherwise we'll use a p2wkh
5331
// script.
24✔
5332
func (f *Manager) selectShutdownScript(taprootOK bool,
24✔
5333
) (lnwire.DeliveryAddress, error) {
24✔
5334

5335
        addrType := lnwallet.WitnessPubKey
5336
        if taprootOK {
5337
                addrType = lnwallet.TaprootPubkey
5338
        }
5339

5340
        addr, err := f.cfg.Wallet.NewAddress(
×
5341
                addrType, false, lnwallet.DefaultAccountName,
×
5342
        )
×
5343
        if err != nil {
×
5344
                return nil, err
×
5345
        }
×
5346

5347
        return txscript.PayToAddrScript(addr)
×
UNCOV
5348
}
×
UNCOV
5349

×
UNCOV
5350
// waitForPeerOnline blocks until the peer specified by peerPubkey comes online
×
UNCOV
5351
// and then returns the online peer.
×
UNCOV
5352
func (f *Manager) waitForPeerOnline(peerPubkey *btcec.PublicKey) (lnpeer.Peer,
×
5353
        error) {
UNCOV
5354

×
5355
        peerChan := make(chan lnpeer.Peer, 1)
5356

5357
        var peerKey [33]byte
5358
        copy(peerKey[:], peerPubkey.SerializeCompressed())
5359

5360
        f.cfg.NotifyWhenOnline(peerKey, peerChan)
105✔
5361

105✔
5362
        var peer lnpeer.Peer
105✔
5363
        select {
105✔
5364
        case peer = <-peerChan:
105✔
5365
        case <-f.quit:
105✔
5366
                return peer, ErrFundingManagerShuttingDown
105✔
5367
        }
105✔
5368
        return peer, nil
105✔
5369
}
105✔
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