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

lightningnetwork / lnd / 12395709513

18 Dec 2024 03:04PM UTC coverage: 57.495% (-1.1%) from 58.595%
12395709513

Pull #8777

github

ziggie1984
funding: refactor gossip msg code

We almost never need to create all messages at the same time
(ChanUpdate,ChanAnnouncement,Proof) so we split it up into own
functions.
Pull Request #8777: multi: make reassignment of alias channel edge atomic

196 of 330 new or added lines in 7 files covered. (59.39%)

19293 existing lines in 251 files now uncovered.

102055 of 177501 relevant lines covered (57.5%)

24852.05 hits per line

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

68.23
/funding/manager.go
1
package funding
2

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

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

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

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

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

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

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

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

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

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

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

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

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

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

102
        msgBufferSize = 50
103

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

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

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

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

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

134
        zeroID [32]byte
135
)
136

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

150
        chanAmt btcutil.Amount
151

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

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

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

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

169
        updateMtx   sync.RWMutex
170
        lastUpdated time.Time
171

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

533
        // ReassignSCID allows the Manager to assign a new SCID to an
534
        // option-scid channel being part of the underlying graph. This is
535
        // necessary because option-scid channels change their scid during their
536
        // lifetime (public zeroconf channels for example) so we need to make
537
        // sure to update the underlying graph.
538
        ReAssignSCID func(aliasScID, newScID lnwire.ShortChannelID) (
539
                *models.ChannelEdgePolicy, error)
540

541
        // AliasManager is an implementation of the aliasHandler interface that
542
        // abstracts away the handling of many alias functions.
543
        AliasManager aliasHandler
544

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

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

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

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

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

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

583
        // cfg is a copy of the configuration struct that the FundingManager
584
        // was initialized with.
585
        cfg *Config
586

587
        // chanIDKey is a cryptographically random key that's used to generate
588
        // temporary channel ID's.
589
        chanIDKey [32]byte
590

591
        // chanIDNonce is a nonce that's incremented for each new funding
592
        // reservation created.
593
        chanIDNonce atomic.Uint64
594

595
        // nonceMtx is a mutex that guards the pendingMusigNonces.
596
        nonceMtx sync.RWMutex
597

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

609
        // activeReservations is a map which houses the state of all pending
610
        // funding workflows.
611
        activeReservations map[serializedPubKey]pendingChannels
612

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

620
        // resMtx guards both of the maps above to ensure that all access is
621
        // goroutine safe.
622
        resMtx sync.RWMutex
623

624
        // fundingMsgs is a channel that relays fundingMsg structs from
625
        // external sub-systems using the ProcessFundingMsg call.
626
        fundingMsgs chan *fundingMsg
627

628
        // fundingRequests is a channel used to receive channel initiation
629
        // requests from a local subsystem within the daemon.
630
        fundingRequests chan *InitFundingMsg
631

632
        localDiscoverySignals *lnutils.SyncMap[lnwire.ChannelID, chan struct{}]
633

634
        handleChannelReadyBarriers *lnutils.SyncMap[lnwire.ChannelID, struct{}]
635

636
        quit chan struct{}
637
        wg   sync.WaitGroup
638
}
639

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

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

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

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

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

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

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

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

730
        for _, channel := range allChannels {
116✔
731
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
9✔
732

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

1✔
742
                        f.localDiscoverySignals.Store(
1✔
743
                                chanID, make(chan struct{}),
1✔
744
                        )
1✔
745

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

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

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

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

775
        f.wg.Add(1) // TODO(roasbeef): tune
107✔
776
        go f.reservationCoordinator()
107✔
777

107✔
778
        return nil
107✔
779
}
780

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

103✔
788
                close(f.quit)
103✔
789
                f.wg.Wait()
103✔
790
        })
103✔
791

792
        return nil
104✔
793
}
794

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

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

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

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

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

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

56✔
835
        var nonceBytes [8]byte
56✔
836
        binary.LittleEndian.PutUint64(nonceBytes[:], nextNonce)
56✔
837

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

56✔
848
        return nextChanID
56✔
849
}
56✔
850

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

×
UNCOV
857
        f.resMtx.Lock()
×
UNCOV
858
        defer f.resMtx.Unlock()
×
UNCOV
859

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

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

878
                resCtx.err <- fmt.Errorf("peer disconnected")
×
879
                delete(nodeReservations, pendingID)
×
880
        }
881

882
        // Finally, we'll delete the node itself from the set of reservations.
883
        delete(f.activeReservations, nodePub)
×
884
}
885

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

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

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

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

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

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

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

22✔
938
        log.Debugf("Failing funding flow for pending_id=%v: %v",
22✔
939
                cid.tempChanID, fundingErr)
22✔
940

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

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

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

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

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

985
        errMsg := &lnwire.Error{
22✔
986
                ChanID: cid.tempChanID,
22✔
987
                Data:   msg,
22✔
988
        }
22✔
989

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

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

×
1002
        msg := fundingErr.Error()
×
1003

×
1004
        errMsg := &lnwire.Warning{
×
1005
                ChanID: cid.tempChanID,
×
1006
                Data:   lnwire.WarningData(msg),
×
1007
        }
×
1008

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

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

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

107✔
1026
        zombieSweepTicker := time.NewTicker(f.cfg.ZombieSweeperInterval)
107✔
1027
        defer zombieSweepTicker.Stop()
107✔
1028

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

1036
                        case *lnwire.AcceptChannel:
32✔
1037
                                f.funderProcessAcceptChannel(fmsg.peer, msg)
32✔
1038

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

1042
                        case *lnwire.FundingSigned:
27✔
1043
                                f.funderProcessFundingSigned(fmsg.peer, msg)
27✔
1044

1045
                        case *lnwire.ChannelReady:
28✔
1046
                                f.wg.Add(1)
28✔
1047
                                go f.handleChannelReady(fmsg.peer, msg)
28✔
1048

1049
                        case *lnwire.Warning:
42✔
1050
                                f.handleWarningMsg(fmsg.peer, msg)
42✔
1051

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

UNCOV
1058
                case <-zombieSweepTicker.C:
×
UNCOV
1059
                        f.pruneZombieReservations()
×
1060

1061
                case <-f.quit:
103✔
1062
                        return
103✔
1063
                }
1064
        }
1065
}
1066

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

63✔
1079
        defer f.wg.Done()
63✔
1080

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

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

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

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

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

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

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

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

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

1189
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
34✔
1190
                        "sent ChannelReady", chanID, shortChanID)
34✔
1191

34✔
1192
                return nil
34✔
1193

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

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

1217
                        return nil
24✔
1218
                }
1219

1220
                return f.handleChannelReadyReceived(
24✔
1221
                        channel, shortChanID, pendingChanID, updateChan,
24✔
1222
                )
24✔
1223

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

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

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

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

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

1270
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
24✔
1271
                        "announced", chanID, shortChanID)
24✔
1272

24✔
1273
                return nil
24✔
1274
        }
1275

1276
        return fmt.Errorf("undefined channelState: %v", channelState)
×
1277
}
1278

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

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

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

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

1316
                // Inform the ChannelNotifier that the channel has transitioned
1317
                // from pending open to open.
1318
                f.cfg.NotifyOpenChannelEvent(channel.FundingOutpoint)
4✔
1319

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

1328
                return nil
4✔
1329
        }
1330

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

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

2✔
1347
                if channel.NumConfsRequired > maturity {
2✔
1348
                        numCoinbaseConfs = uint32(channel.NumConfsRequired)
×
1349
                }
×
1350

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

×
1358
                        return err
×
1359
                }
×
1360

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

×
1370
                        return err
×
1371
                }
×
1372

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

1382
                case <-f.quit:
×
1383
                        return ErrFundingManagerShuttingDown
×
1384
                }
1385
        }
1386

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

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

1399
        return nil
30✔
1400
}
1401

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

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

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

54✔
1429
        amt := msg.FundingAmount
54✔
1430

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

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

54✔
1447
        // Create the channel identifier.
54✔
1448
        cid := newChanIdentifier(msg.PendingChannelID)
54✔
1449

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

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

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

4✔
1475
                return
4✔
1476
        }
4✔
1477

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

1485
        if len(pendingChans) > pendingChansLimit {
50✔
1486
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
×
1487
                return
×
1488
        }
×
1489

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

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

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

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

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

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

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

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

1570
        var scidFeatureVal bool
47✔
1571
        if hasFeatures(
47✔
1572
                peer.LocalFeatures(), peer.RemoteFeatures(),
47✔
1573
                lnwire.ScidAliasOptional,
47✔
1574
        ) {
50✔
1575

3✔
1576
                scidFeatureVal = true
3✔
1577
        }
3✔
1578

1579
        var (
47✔
1580
                zeroConf bool
47✔
1581
                scid     bool
47✔
1582
        )
47✔
1583

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

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

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

1622
                        // Set zeroConf to true to enable the zero-conf flow.
1623
                        zeroConf = true
×
1624
                }
1625
        }
1626

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

×
1638
                return
×
1639

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

×
1648
                return
×
1649
        }
1650

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

×
1665
                return
×
1666
        }
×
1667

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

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

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

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

1708
                reservation.AddAlias(aliasScid)
2✔
1709
        }
1710

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

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

1728
        reservation.SetNumConfsRequired(numConfsReq)
47✔
1729

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

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

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

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

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

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

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

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

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

1821
        remoteMaxValue := f.cfg.RequiredRemoteMaxValue(amt)
46✔
1822
        if acceptorResp.InFlightTotal != 0 {
46✔
1823
                remoteMaxValue = acceptorResp.InFlightTotal
×
1824
        }
×
1825

1826
        maxHtlcs := f.cfg.RequiredRemoteMaxHTLCs(amt)
46✔
1827
        if acceptorResp.HtlcLimit != 0 {
46✔
1828
                maxHtlcs = acceptorResp.HtlcLimit
×
1829
        }
×
1830

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

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

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

46✔
1870
        // Update the timestamp once the fundingOpenMsg has been handled.
46✔
1871
        defer resCtx.updateTimestamp()
46✔
1872

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

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

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

×
1915
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
1916

×
1917
                        return
×
1918
                }
×
1919

1920
                remoteContribution.LocalNonce = &musig2.Nonces{
2✔
1921
                        PubNonce: localNonce,
2✔
1922
                }
2✔
1923
        }
1924

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

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

40✔
1941
        reservation.SetState(lnwallet.SentAcceptChannel)
40✔
1942

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

40✔
1965
        if commitType.IsTaproot() {
42✔
1966
                fundingAccept.LocalNonce = lnwire.SomeMusig2Nonce(
2✔
1967
                        ourContribution.LocalNonce.PubNonce,
2✔
1968
                )
2✔
1969
        }
2✔
1970

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

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

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

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

2000
        // Update the timestamp once the fundingAcceptMsg has been handled.
2001
        defer resCtx.updateTimestamp()
32✔
2002

32✔
2003
        if resCtx.reservation.State() != lnwallet.SentOpenChannel {
32✔
2004
                return
×
2005
        }
×
2006

2007
        log.Infof("Recv'd fundingResponse for pending_id(%x)",
32✔
2008
                pendingChanID[:])
32✔
2009

32✔
2010
        // Create the channel identifier.
32✔
2011
        cid := newChanIdentifier(msg.PendingChannelID)
32✔
2012

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

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

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

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

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

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

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

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

×
2106
                minDepth = 1
×
2107
        }
×
2108

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

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

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

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

×
2175
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
2176

×
2177
                        return
×
2178
                }
×
2179

2180
                remoteContribution.LocalNonce = &musig2.Nonces{
2✔
2181
                        PubNonce: localNonce,
2✔
2182
                }
2✔
2183
        }
2184

2185
        err = resCtx.reservation.ProcessContribution(remoteContribution)
29✔
2186

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

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

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

×
UNCOV
2248
                        f.waitForPsbt(psbtIntent, resCtx, cid)
×
UNCOV
2249
                }()
×
2250

2251
                // With the new goroutine spawned, we can now exit to unblock
2252
                // the main event loop.
UNCOV
2253
                return
×
2254
        }
2255

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

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

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

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

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

2301
                // Nil error means the flow continues normally now.
UNCOV
2302
                case nil:
×
2303

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

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

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

2343
                // We are now ready to continue the funding flow.
UNCOV
2344
                f.continueFundingAccept(resCtx, cid)
×
2345

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

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

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

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

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

29✔
2384
        log.Infof("Generated ChannelPoint(%v) for pending_id(%x)", outPoint,
29✔
2385
                cid.tempChanID[:])
29✔
2386

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

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

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

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

×
2417
                        return
×
2418
                }
×
2419

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

2432
        resCtx.reservation.SetState(lnwallet.SentFundingCreated)
29✔
2433

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

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

27✔
2451
        peerKey := peer.IdentityKey()
27✔
2452
        pendingChanID := msg.PendingChannelID
27✔
2453

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

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

27✔
2469
        if resCtx.reservation.State() != lnwallet.SentAcceptChannel {
27✔
2470
                return
×
2471
        }
×
2472

2473
        // Create the channel identifier without setting the active channel ID.
2474
        cid := newChanIdentifier(pendingChanID)
27✔
2475

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

×
2485
                        return
×
2486
                }
×
2487

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

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

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

2537
        // Get forwarding policy before deleting the reservation context.
2538
        forwardingPolicy := resCtx.forwardingPolicy
27✔
2539

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

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

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

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

27✔
2578
        fundingSigned := &lnwire.FundingSigned{}
27✔
2579

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

×
2592
                        return
×
2593
                }
×
2594

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

×
2605
                        return
×
2606
                }
×
2607
        }
2608

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

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

27✔
2622
        fundingSigned.ChanID = cid.chanID
27✔
2623

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

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

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

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

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

27✔
2657
        // Inform the ChannelNotifier that the channel has entered
27✔
2658
        // pending open state.
27✔
2659
        f.cfg.NotifyPendingOpenChannelEvent(fundingOut, completeChan)
27✔
2660

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

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

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

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

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

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

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

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

×
2737
                return
×
2738
        }
×
2739

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

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

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

×
2766
                        return
×
2767
                }
×
2768

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

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

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

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

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

2810
                log.Infof("Broadcasting funding tx for ChannelPoint(%v): %x",
26✔
2811
                        completeChan.FundingOutpoint, fundingTxBuf.Bytes())
26✔
2812

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

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

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

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

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

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

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

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

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

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

2899
        // fundingTx is the funding transaction that created the channel.
2900
        fundingTx *wire.MsgTx
2901
}
2902

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

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

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

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

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

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

2950
                // nil error means we continue on.
2951
                case nil:
2✔
2952

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

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

2✔
2964
                // TODO(halseth): should this send be made
2✔
2965
                // reliable?
2✔
2966

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

2972
        return timeoutErr
2✔
2973
}
2974

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

57✔
2983
        confChan := make(chan *confirmedChannel)
57✔
2984
        timeoutChan := make(chan error, 1)
57✔
2985
        cancelChan := make(chan struct{})
57✔
2986

57✔
2987
        f.wg.Add(1)
57✔
2988
        go f.waitForFundingConfirmation(ch, cancelChan, confChan)
57✔
2989

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

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

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

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

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

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

3035
                return pkScript, nil
5✔
3036
        }
3037

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

3046
        return input.WitnessScriptHash(multiSigScript)
72✔
3047
}
3048

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

57✔
3062
        defer f.wg.Done()
57✔
3063
        defer close(confChan)
57✔
3064

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

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

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

3094
        log.Infof("Waiting for funding tx (%v) to reach %v confirmations",
57✔
3095
                txid, numConfs)
57✔
3096

57✔
3097
        var confDetails *chainntnfs.TxConfirmation
57✔
3098
        var ok bool
57✔
3099

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

3106
        case <-cancelChan:
2✔
3107
                log.Warnf("canceled waiting for funding confirmation, "+
2✔
3108
                        "stopping funding flow for ChannelPoint(%v)",
2✔
3109
                        completeChan.FundingOutpoint)
2✔
3110
                return
2✔
3111

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

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

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

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

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

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

25✔
3159
        defer f.wg.Done()
25✔
3160

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

3168
        defer epochClient.Cancel()
25✔
3169

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

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

2✔
3190
                                // Notify the caller of the timeout.
2✔
3191
                                close(timeoutChan)
2✔
3192
                                return
2✔
3193
                        }
2✔
3194

3195
                        // TODO: If we are the channel initiator implement
3196
                        // a method for recovering the funds from the funding
3197
                        // transaction
3198

3199
                case <-cancelChan:
15✔
3200
                        return
15✔
3201

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

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

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

3226
                label := labels.MakeLabel(
16✔
3227
                        labels.LabelTypeChannelOpen, &shortChanID,
16✔
3228
                )
16✔
3229

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

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

30✔
3245
        fundingPoint := completeChan.FundingOutpoint
30✔
3246
        chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
30✔
3247

30✔
3248
        // TODO(roasbeef): ideally persistent state update for chan above
30✔
3249
        // should be abstracted
30✔
3250

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

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

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

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

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

3298
        // Update the confirmed funding transaction label.
3299
        f.makeLabelForTx(completeChan)
30✔
3300

30✔
3301
        // Inform the ChannelNotifier that the channel has transitioned from
30✔
3302
        // pending open to open.
30✔
3303
        f.cfg.NotifyOpenChannelEvent(completeChan.FundingOutpoint)
30✔
3304

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

3313
        return nil
30✔
3314
}
3315

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

35✔
3322
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
35✔
3323

35✔
3324
        var peerKey [33]byte
35✔
3325
        copy(peerKey[:], completeChan.IdentityPub.SerializeCompressed())
35✔
3326

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

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

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

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

4✔
3364
                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce(
4✔
3365
                        localNonce.PubNonce,
4✔
3366
                )
4✔
3367
        }
3368

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

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

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

3404
                localAlias := peer.LocalFeatures().HasFeature(
34✔
3405
                        lnwire.ScidAliasOptional,
34✔
3406
                )
34✔
3407
                remoteAlias := peer.RemoteFeatures().HasFeature(
34✔
3408
                        lnwire.ScidAliasOptional,
34✔
3409
                )
34✔
3410

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

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

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

3441
                                channelReadyMsg.AliasScid = &alias
×
3442
                        } else {
×
3443
                                channelReadyMsg.AliasScid = &aliases[0]
×
3444
                        }
×
3445
                }
3446

3447
                log.Infof("Peer(%x) is online, sending ChannelReady "+
34✔
3448
                        "for ChannelID(%v)", peerKey, chanID)
34✔
3449

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

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

3460
        return nil
34✔
3461
}
3462

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

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

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

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

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

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

24✔
3503
        return !loaded, nil
24✔
3504
}
3505

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

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

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

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

3533
        return fwdMinHTLC, fwdMaxHTLC
26✔
3534
}
3535

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

24✔
3549
        chanAnn, err := f.newChanAnnouncement(
24✔
3550
                f.cfg.IDKey, completeChan.IdentityPub,
24✔
3551
                &completeChan.LocalChanCfg.MultiSigKey,
24✔
3552
                completeChan.RemoteChanCfg.MultiSigKey.PubKey,
24✔
3553
                completeChan.ShortChanID(),
24✔
3554
                completeChan.ChanType,
24✔
3555
        )
24✔
3556
        if err != nil {
24✔
3557
                return fmt.Errorf("error generating channel "+
×
3558
                        "announcement: %v", err)
×
3559
        }
×
3560

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

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

3585
        fwdMinHTLC, fwdMaxHTLC := f.extractAnnounceParams(completeChan)
24✔
3586

24✔
3587
        chanUpdateChanFlags := lnwire.ChanUpdateChanFlags(0)
24✔
3588
        if !IsLexicographicallyFirst(f.cfg.IDKey,
24✔
3589
                completeChan.IdentityPub) {
36✔
3590

12✔
3591
                chanUpdateChanFlags = 1
12✔
3592
        }
12✔
3593

3594
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
24✔
3595
        chanUpdateAnn, err := f.newChanUpdate(
24✔
3596
                chanUpdateChanFlags, completeChan.ShortChanID(), chanID,
24✔
3597
                fwdMinHTLC, fwdMaxHTLC, ourPolicy,
24✔
3598
        )
24✔
3599
        if err != nil {
24✔
NEW
3600
                return fmt.Errorf("error generating channel update: %w", err)
×
NEW
3601
        }
×
3602

3603
        errChan = f.cfg.SendAnnouncement(
24✔
3604
                chanUpdateAnn, discovery.RemoteAlias(peerAlias),
24✔
3605
        )
24✔
3606
        select {
24✔
3607
        case err := <-errChan:
24✔
3608
                if err != nil {
24✔
3609
                        if graph.IsError(err, graph.ErrOutdated,
×
3610
                                graph.ErrIgnored) {
×
3611

×
3612
                                log.Debugf("Graph rejected "+
×
3613
                                        "ChannelUpdate: %v", err)
×
3614
                        } else {
×
3615
                                return fmt.Errorf("error sending channel "+
×
3616
                                        "update: %v", err)
×
3617
                        }
×
3618
                }
3619
        case <-f.quit:
×
3620
                return ErrFundingManagerShuttingDown
×
3621
        }
3622

3623
        return nil
24✔
3624
}
3625

3626
// annAfterSixConfs broadcasts the necessary channel announcement messages to
3627
// the network after 6 confs. Should be called after the channelReady message
3628
// is sent and the channel is added to the graph (channelState is
3629
// 'addedToGraph') and the channel is ready to be used. This is the last
3630
// step in the channel opening process, and the opening state will be deleted
3631
// from the database if successful.
3632
func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
3633
        shortChanID *lnwire.ShortChannelID) error {
26✔
3634

26✔
3635
        // If this channel is not meant to be announced to the greater network,
26✔
3636
        // we'll only send our NodeAnnouncement to our counterparty to ensure we
26✔
3637
        // don't leak any of our information.
26✔
3638
        announceChan := completeChan.ChannelFlags&lnwire.FFAnnounceChannel != 0
26✔
3639
        if !announceChan {
34✔
3640
                log.Debugf("Will not announce private channel %v.",
8✔
3641
                        shortChanID.ToUint64())
8✔
3642

8✔
3643
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
8✔
3644
                if err != nil {
8✔
3645
                        return err
×
3646
                }
×
3647

3648
                nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
8✔
3649
                if err != nil {
8✔
3650
                        return fmt.Errorf("unable to retrieve current node "+
×
3651
                                "announcement: %v", err)
×
3652
                }
×
3653

3654
                chanID := lnwire.NewChanIDFromOutPoint(
8✔
3655
                        completeChan.FundingOutpoint,
8✔
3656
                )
8✔
3657
                pubKey := peer.PubKey()
8✔
3658
                log.Debugf("Sending our NodeAnnouncement for "+
8✔
3659
                        "ChannelID(%v) to %x", chanID, pubKey)
8✔
3660

8✔
3661
                // TODO(halseth): make reliable. If the peer is not online this
8✔
3662
                // will fail, and the opening process will stop. Should instead
8✔
3663
                // block here, waiting for the peer to come online.
8✔
3664
                if err := peer.SendMessage(true, &nodeAnn); err != nil {
8✔
3665
                        return fmt.Errorf("unable to send node announcement "+
×
3666
                                "to peer %x: %v", pubKey, err)
×
3667
                }
×
3668
        } else {
18✔
3669
                // Otherwise, we'll wait until the funding transaction has
18✔
3670
                // reached 6 confirmations before announcing it.
18✔
3671
                numConfs := uint32(completeChan.NumConfsRequired)
18✔
3672
                if numConfs < 6 {
36✔
3673
                        numConfs = 6
18✔
3674
                }
18✔
3675
                txid := completeChan.FundingOutpoint.Hash
18✔
3676
                log.Debugf("Will announce channel %v after ChannelPoint"+
18✔
3677
                        "(%v) has gotten %d confirmations",
18✔
3678
                        shortChanID.ToUint64(), completeChan.FundingOutpoint,
18✔
3679
                        numConfs)
18✔
3680

18✔
3681
                fundingScript, err := makeFundingScript(completeChan)
18✔
3682
                if err != nil {
18✔
3683
                        return fmt.Errorf("unable to create funding script "+
×
3684
                                "for ChannelPoint(%v): %v",
×
3685
                                completeChan.FundingOutpoint, err)
×
3686
                }
×
3687

3688
                // Register with the ChainNotifier for a notification once the
3689
                // funding transaction reaches at least 6 confirmations.
3690
                confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
18✔
3691
                        &txid, fundingScript, numConfs,
18✔
3692
                        completeChan.BroadcastHeight(),
18✔
3693
                )
18✔
3694
                if err != nil {
18✔
3695
                        return fmt.Errorf("unable to register for "+
×
3696
                                "confirmation of ChannelPoint(%v): %v",
×
3697
                                completeChan.FundingOutpoint, err)
×
3698
                }
×
3699

3700
                // Wait until 6 confirmations has been reached or the wallet
3701
                // signals a shutdown.
3702
                select {
18✔
3703
                case _, ok := <-confNtfn.Confirmed:
16✔
3704
                        if !ok {
16✔
3705
                                return fmt.Errorf("ChainNotifier shutting "+
×
3706
                                        "down, cannot complete funding flow "+
×
3707
                                        "for ChannelPoint(%v)",
×
3708
                                        completeChan.FundingOutpoint)
×
3709
                        }
×
3710
                        // Fallthrough.
3711

3712
                case <-f.quit:
2✔
3713
                        return fmt.Errorf("%v, stopping funding flow for "+
2✔
3714
                                "ChannelPoint(%v)",
2✔
3715
                                ErrFundingManagerShuttingDown,
2✔
3716
                                completeChan.FundingOutpoint)
2✔
3717
                }
3718

3719
                fundingPoint := completeChan.FundingOutpoint
16✔
3720
                chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
16✔
3721

16✔
3722
                log.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
16✔
3723
                        &fundingPoint, shortChanID)
16✔
3724

16✔
3725
                // If this is a non-zero-conf option-scid-alias channel, we'll
16✔
3726
                // delete the mappings the gossiper uses so that ChannelUpdates
16✔
3727
                // with aliases won't be accepted. This is done elsewhere for
16✔
3728
                // zero-conf channels.
16✔
3729
                isScidFeature := completeChan.NegotiatedAliasFeature()
16✔
3730
                isZeroConf := completeChan.IsZeroConf()
16✔
3731
                if isScidFeature && !isZeroConf {
16✔
UNCOV
3732
                        baseScid := completeChan.ShortChanID()
×
UNCOV
3733
                        err := f.cfg.AliasManager.DeleteSixConfs(baseScid)
×
UNCOV
3734
                        if err != nil {
×
3735
                                return fmt.Errorf("failed deleting six confs "+
×
3736
                                        "maps: %v", err)
×
3737
                        }
×
3738

3739
                        // We reassign the same scid to the graph db. This will
3740
                        // trigger a deletion of the current edge data and
3741
                        // reinsert the channel with the same edge info and
3742
                        // policy. This is done to guarantee that potential
3743
                        // ChannelUpdates using the alias as the scid are
3744
                        // removed and not relayed to the broader network
3745
                        // because the alias is not a verifiable channel id.
NEW
3746
                        ourPolicy, err := f.cfg.ReAssignSCID(
×
NEW
3747
                                baseScid, baseScid,
×
NEW
3748
                        )
×
3749
                        if err != nil {
×
NEW
3750
                                return fmt.Errorf("failed reassigning alias "+
×
NEW
3751
                                        "edge into graph: %v", err)
×
UNCOV
3752
                        }
×
3753

NEW
3754
                        log.Infof("Successfully reassigned alias edge in "+
×
NEW
3755
                                "graph(non-zeroconf): %v(%d) -> %v(%d)",
×
NEW
3756
                                baseScid, baseScid.ToUint64(),
×
NEW
3757
                                baseScid, baseScid.ToUint64())
×
NEW
3758

×
NEW
3759
                        // We send the rassigned ChannelUpdate to the peer.
×
NEW
3760
                        err = f.sendChanUpdate(
×
NEW
3761
                                completeChan, &baseScid, ourPolicy,
×
UNCOV
3762
                        )
×
UNCOV
3763
                        if err != nil {
×
3764
                                return fmt.Errorf("failed to re-add to "+
×
3765
                                        "graph: %v", err)
×
3766
                        }
×
3767
                }
3768

3769
                chanAnn, err := f.newChanAnnouncement(
16✔
3770
                        f.cfg.IDKey, completeChan.IdentityPub,
16✔
3771
                        &completeChan.LocalChanCfg.MultiSigKey,
16✔
3772
                        completeChan.RemoteChanCfg.MultiSigKey.PubKey,
16✔
3773
                        completeChan.ShortChanID(),
16✔
3774
                        completeChan.ChanType,
16✔
3775
                )
16✔
3776
                if err != nil {
16✔
NEW
3777
                        return fmt.Errorf("error generating channel "+
×
NEW
3778
                                "announcement: %v", err)
×
NEW
3779
                }
×
3780

3781
                // Create and broadcast the proofs required to make this channel
3782
                // public and usable for other nodes for routing.
3783
                err = f.announceChannel(
16✔
3784
                        completeChan, chanAnn, chanID,
16✔
3785
                )
16✔
3786
                if err != nil {
16✔
UNCOV
3787
                        return fmt.Errorf("channel announcement failed: %w",
×
UNCOV
3788
                                err)
×
UNCOV
3789
                }
×
3790

3791
                log.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
16✔
3792
                        "sent to gossiper", &fundingPoint, shortChanID)
16✔
3793
        }
3794

3795
        return nil
24✔
3796
}
3797

3798
// waitForZeroConfChannel is called when the state is addedToGraph with
3799
// a zero-conf channel. This will wait for the real confirmation, add the
3800
// confirmed SCID to the router graph, and then announce after six confs.
3801
func (f *Manager) waitForZeroConfChannel(c *channeldb.OpenChannel) error {
6✔
3802
        // First we'll check whether the channel is confirmed on-chain. If it
6✔
3803
        // is already confirmed, the chainntnfs subsystem will return with the
6✔
3804
        // confirmed tx. Otherwise, we'll wait here until confirmation occurs.
6✔
3805
        confChan, err := f.waitForFundingWithTimeout(c)
6✔
3806
        if err != nil {
8✔
3807
                return fmt.Errorf("error waiting for zero-conf funding "+
2✔
3808
                        "confirmation for ChannelPoint(%v): %v",
2✔
3809
                        c.FundingOutpoint, err)
2✔
3810
        }
2✔
3811

3812
        // We'll need to refresh the channel state so that things are properly
3813
        // populated when validating the channel state. Otherwise, a panic may
3814
        // occur due to inconsistency in the OpenChannel struct.
3815
        err = c.Refresh()
4✔
3816
        if err != nil {
4✔
UNCOV
3817
                return fmt.Errorf("unable to refresh channel state: %w", err)
×
UNCOV
3818
        }
×
3819

3820
        // Now that we have the confirmed transaction and the proper SCID,
3821
        // we'll call ValidateChannel to ensure the confirmed tx is properly
3822
        // formatted.
3823
        err = f.cfg.Wallet.ValidateChannel(c, confChan.fundingTx)
4✔
3824
        if err != nil {
4✔
3825
                return fmt.Errorf("unable to validate zero-conf channel: "+
×
3826
                        "%v", err)
×
3827
        }
×
3828

3829
        // Once we know the confirmed ShortChannelID, we'll need to save it to
3830
        // the database and refresh the OpenChannel struct with it.
3831
        err = c.MarkRealScid(confChan.shortChanID)
4✔
3832
        if err != nil {
4✔
3833
                return fmt.Errorf("unable to set confirmed SCID for zero "+
×
3834
                        "channel: %v", err)
×
3835
        }
×
3836

3837
        // Six confirmations have been reached. If this channel is public,
3838
        // we'll delete some of the alias mappings the gossiper uses.
3839
        isPublic := c.ChannelFlags&lnwire.FFAnnounceChannel != 0
4✔
3840
        if isPublic {
6✔
3841
                err = f.cfg.AliasManager.DeleteSixConfs(c.ShortChannelID)
2✔
3842
                if err != nil {
2✔
3843
                        return fmt.Errorf("unable to delete base alias after "+
×
3844
                                "six confirmations: %v", err)
×
3845
                }
×
3846

3847
                // The underlying graph entry for this channel id needs to be
3848
                // reassigned with the new confirmed scid. Moreover channel
3849
                // updates with the alias scid are removed so that we do not
3850
                // relay them to the broader network.
3851
                ourPolicy, err := f.cfg.ReAssignSCID(
2✔
3852
                        c.ShortChanID(), confChan.shortChanID,
2✔
3853
                )
2✔
3854
                if err != nil {
2✔
NEW
3855
                        return fmt.Errorf("unable to reassign alias edge in "+
×
3856
                                "graph: %v", err)
×
3857
                }
×
3858

3859
                aliasScid := c.ShortChanID()
2✔
3860
                confirmedScid := confChan.shortChanID
2✔
3861

2✔
3862
                log.Infof("Successfully reassigned alias edge in "+
2✔
3863
                        "graph(zeroconf): %v(%d) -> %v(%d)",
2✔
3864
                        aliasScid, aliasScid.ToUint64(),
2✔
3865
                        confirmedScid, confirmedScid.ToUint64())
2✔
3866

2✔
3867
                // Send the ChannelUpdate with the confirmed scid to the peer.
2✔
3868
                err = f.sendChanUpdate(
2✔
3869
                        c, &confChan.shortChanID, ourPolicy,
2✔
3870
                )
2✔
3871
                if err != nil {
2✔
NEW
3872
                        return fmt.Errorf("failed to send ChannelUpdate to "+
×
NEW
3873
                                "gossiper: %v", err)
×
UNCOV
3874
                }
×
3875
        }
3876

3877
        // Since we have now marked down the confirmed SCID, we'll also need to
3878
        // tell the Switch to refresh the relevant ChannelLink so that forwards
3879
        // under the confirmed SCID are possible if this is a public channel.
3880
        err = f.cfg.ReportShortChanID(c.FundingOutpoint)
4✔
3881
        if err != nil {
4✔
3882
                // This should only fail if the link is not found in the
×
3883
                // Switch's linkIndex map. If this is the case, then the peer
×
3884
                // has gone offline and the next time the link is loaded, it
×
3885
                // will have a refreshed state. Just log an error here.
×
3886
                log.Errorf("unable to report scid for zero-conf channel "+
×
3887
                        "channel: %v", err)
×
3888
        }
×
3889

3890
        // Update the confirmed transaction's label.
3891
        f.makeLabelForTx(c)
4✔
3892

4✔
3893
        return nil
4✔
3894
}
3895

3896
// genFirstStateMusigNonce generates a nonces for the "first" local state. This
3897
// is the verification nonce for the state created for us after the initial
3898
// commitment transaction signed as part of the funding flow.
3899
func genFirstStateMusigNonce(channel *channeldb.OpenChannel,
3900
) (*musig2.Nonces, error) {
4✔
3901

4✔
3902
        musig2ShaChain, err := channeldb.DeriveMusig2Shachain(
4✔
3903
                channel.RevocationProducer,
4✔
3904
        )
4✔
3905
        if err != nil {
4✔
3906
                return nil, fmt.Errorf("unable to generate musig channel "+
×
3907
                        "nonces: %v", err)
×
3908
        }
×
3909

3910
        // We use the _next_ commitment height here as we need to generate the
3911
        // nonce for the next state the remote party will sign for us.
3912
        verNonce, err := channeldb.NewMusigVerificationNonce(
4✔
3913
                channel.LocalChanCfg.MultiSigKey.PubKey,
4✔
3914
                channel.LocalCommitment.CommitHeight+1,
4✔
3915
                musig2ShaChain,
4✔
3916
        )
4✔
3917
        if err != nil {
4✔
3918
                return nil, fmt.Errorf("unable to generate musig channel "+
×
3919
                        "nonces: %v", err)
×
3920
        }
×
3921

3922
        return verNonce, nil
4✔
3923
}
3924

3925
// handleChannelReady finalizes the channel funding process and enables the
3926
// channel to enter normal operating mode.
3927
func (f *Manager) handleChannelReady(peer lnpeer.Peer, //nolint:funlen
3928
        msg *lnwire.ChannelReady) {
28✔
3929

28✔
3930
        defer f.wg.Done()
28✔
3931

28✔
3932
        // If we are in development mode, we'll wait for specified duration
28✔
3933
        // before processing the channel ready message.
28✔
3934
        if f.cfg.Dev != nil {
28✔
UNCOV
3935
                duration := f.cfg.Dev.ProcessChannelReadyWait
×
UNCOV
3936
                log.Warnf("Channel(%v): sleeping %v before processing "+
×
UNCOV
3937
                        "channel_ready", msg.ChanID, duration)
×
UNCOV
3938

×
UNCOV
3939
                select {
×
UNCOV
3940
                case <-time.After(duration):
×
UNCOV
3941
                        log.Warnf("Channel(%v): slept %v before processing "+
×
UNCOV
3942
                                "channel_ready", msg.ChanID, duration)
×
3943
                case <-f.quit:
×
3944
                        log.Warnf("Channel(%v): quit sleeping", msg.ChanID)
×
3945
                        return
×
3946
                }
3947
        }
3948

3949
        log.Debugf("Received ChannelReady for ChannelID(%v) from "+
28✔
3950
                "peer %x", msg.ChanID,
28✔
3951
                peer.IdentityKey().SerializeCompressed())
28✔
3952

28✔
3953
        // We now load or create a new channel barrier for this channel.
28✔
3954
        _, loaded := f.handleChannelReadyBarriers.LoadOrStore(
28✔
3955
                msg.ChanID, struct{}{},
28✔
3956
        )
28✔
3957

28✔
3958
        // If we are currently in the process of handling a channel_ready
28✔
3959
        // message for this channel, ignore.
28✔
3960
        if loaded {
29✔
3961
                log.Infof("Already handling channelReady for "+
1✔
3962
                        "ChannelID(%v), ignoring.", msg.ChanID)
1✔
3963
                return
1✔
3964
        }
1✔
3965

3966
        // If not already handling channelReady for this channel, then the
3967
        // `LoadOrStore` has set up a barrier, and it will be removed once this
3968
        // function exits.
3969
        defer f.handleChannelReadyBarriers.Delete(msg.ChanID)
27✔
3970

27✔
3971
        localDiscoverySignal, ok := f.localDiscoverySignals.Load(msg.ChanID)
27✔
3972
        if ok {
52✔
3973
                // Before we proceed with processing the channel_ready
25✔
3974
                // message, we'll wait for the local waitForFundingConfirmation
25✔
3975
                // goroutine to signal that it has the necessary state in
25✔
3976
                // place. Otherwise, we may be missing critical information
25✔
3977
                // required to handle forwarded HTLC's.
25✔
3978
                select {
25✔
3979
                case <-localDiscoverySignal:
25✔
3980
                        // Fallthrough
3981
                case <-f.quit:
×
3982
                        return
×
3983
                }
3984

3985
                // With the signal received, we can now safely delete the entry
3986
                // from the map.
3987
                f.localDiscoverySignals.Delete(msg.ChanID)
25✔
3988
        }
3989

3990
        // First, we'll attempt to locate the channel whose funding workflow is
3991
        // being finalized by this message. We go to the database rather than
3992
        // our reservation map as we may have restarted, mid funding flow. Also
3993
        // provide the node's public key to make the search faster.
3994
        chanID := msg.ChanID
27✔
3995
        channel, err := f.cfg.FindChannel(peer.IdentityKey(), chanID)
27✔
3996
        if err != nil {
27✔
3997
                log.Errorf("Unable to locate ChannelID(%v), cannot complete "+
×
3998
                        "funding", chanID)
×
3999
                return
×
4000
        }
×
4001

4002
        // If this is a taproot channel, then we can generate the set of nonces
4003
        // the remote party needs to send the next remote commitment here.
4004
        var firstVerNonce *musig2.Nonces
27✔
4005
        if channel.ChanType.IsTaproot() {
31✔
4006
                firstVerNonce, err = genFirstStateMusigNonce(channel)
4✔
4007
                if err != nil {
4✔
4008
                        log.Error(err)
×
4009
                        return
×
4010
                }
×
4011
        }
4012

4013
        // We'll need to store the received TLV alias if the option_scid_alias
4014
        // feature was negotiated. This will be used to provide route hints
4015
        // during invoice creation. In the zero-conf case, it is also used to
4016
        // provide a ChannelUpdate to the remote peer. This is done before the
4017
        // call to InsertNextRevocation in case the call to PutPeerAlias fails.
4018
        // If it were to fail on the first call to handleChannelReady, we
4019
        // wouldn't want the channel to be usable yet.
4020
        if channel.NegotiatedAliasFeature() {
33✔
4021
                // If the AliasScid field is nil, we must fail out. We will
6✔
4022
                // most likely not be able to route through the peer.
6✔
4023
                if msg.AliasScid == nil {
6✔
4024
                        log.Debugf("Consider closing ChannelID(%v), peer "+
×
4025
                                "does not implement the option-scid-alias "+
×
4026
                                "feature properly", chanID)
×
4027
                        return
×
4028
                }
×
4029

4030
                // We'll store the AliasScid so that invoice creation can use
4031
                // it.
4032
                err = f.cfg.AliasManager.PutPeerAlias(chanID, *msg.AliasScid)
6✔
4033
                if err != nil {
6✔
4034
                        log.Errorf("unable to store peer's alias: %v", err)
×
4035
                        return
×
4036
                }
×
4037

4038
                // If we do not have an alias stored, we'll create one now.
4039
                // This is only used in the upgrade case where a user toggles
4040
                // the option-scid-alias feature-bit to on. We'll also send the
4041
                // channel_ready message here in case the link is created
4042
                // before sendChannelReady is called.
4043
                aliases := f.cfg.AliasManager.GetAliases(
6✔
4044
                        channel.ShortChannelID,
6✔
4045
                )
6✔
4046
                if len(aliases) == 0 {
6✔
4047
                        // No aliases were found so we'll request and store an
×
4048
                        // alias and use it in the channel_ready message.
×
4049
                        alias, err := f.cfg.AliasManager.RequestAlias()
×
4050
                        if err != nil {
×
4051
                                log.Errorf("unable to request alias: %v", err)
×
4052
                                return
×
4053
                        }
×
4054

4055
                        err = f.cfg.AliasManager.AddLocalAlias(
×
4056
                                alias, channel.ShortChannelID, false, false,
×
4057
                        )
×
4058
                        if err != nil {
×
4059
                                log.Errorf("unable to add local alias: %v",
×
4060
                                        err)
×
4061
                                return
×
4062
                        }
×
4063

4064
                        secondPoint, err := channel.SecondCommitmentPoint()
×
4065
                        if err != nil {
×
4066
                                log.Errorf("unable to fetch second "+
×
4067
                                        "commitment point: %v", err)
×
4068
                                return
×
4069
                        }
×
4070

4071
                        channelReadyMsg := lnwire.NewChannelReady(
×
4072
                                chanID, secondPoint,
×
4073
                        )
×
4074
                        channelReadyMsg.AliasScid = &alias
×
4075

×
4076
                        if firstVerNonce != nil {
×
4077
                                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce( //nolint:ll
×
4078
                                        firstVerNonce.PubNonce,
×
4079
                                )
×
4080
                        }
×
4081

4082
                        err = peer.SendMessage(true, channelReadyMsg)
×
4083
                        if err != nil {
×
4084
                                log.Errorf("unable to send channel_ready: %v",
×
4085
                                        err)
×
4086
                                return
×
4087
                        }
×
4088
                }
4089
        }
4090

4091
        // If the RemoteNextRevocation is non-nil, it means that we have
4092
        // already processed channelReady for this channel, so ignore. This
4093
        // check is after the alias logic so we store the peer's most recent
4094
        // alias. The spec requires us to validate that subsequent
4095
        // channel_ready messages use the same per commitment point (the
4096
        // second), but it is not actually necessary since we'll just end up
4097
        // ignoring it. We are, however, required to *send* the same per
4098
        // commitment point, since another pedantic implementation might
4099
        // verify it.
4100
        if channel.RemoteNextRevocation != nil {
28✔
4101
                log.Infof("Received duplicate channelReady for "+
1✔
4102
                        "ChannelID(%v), ignoring.", chanID)
1✔
4103
                return
1✔
4104
        }
1✔
4105

4106
        // If this is a taproot channel, then we'll need to map the received
4107
        // nonces to a nonce pair, and also fetch our pending nonces, which are
4108
        // required in order to make the channel whole.
4109
        var chanOpts []lnwallet.ChannelOpt
26✔
4110
        if channel.ChanType.IsTaproot() {
30✔
4111
                f.nonceMtx.Lock()
4✔
4112
                localNonce, ok := f.pendingMusigNonces[chanID]
4✔
4113
                if !ok {
4✔
UNCOV
4114
                        // If there's no pending nonce for this channel ID,
×
UNCOV
4115
                        // we'll use the one generated above.
×
UNCOV
4116
                        localNonce = firstVerNonce
×
UNCOV
4117
                        f.pendingMusigNonces[chanID] = firstVerNonce
×
UNCOV
4118
                }
×
4119
                f.nonceMtx.Unlock()
4✔
4120

4✔
4121
                log.Infof("ChanID(%v): applying local+remote musig2 nonces",
4✔
4122
                        chanID)
4✔
4123

4✔
4124
                remoteNonce, err := msg.NextLocalNonce.UnwrapOrErrV(
4✔
4125
                        errNoLocalNonce,
4✔
4126
                )
4✔
4127
                if err != nil {
4✔
4128
                        cid := newChanIdentifier(msg.ChanID)
×
4129
                        f.sendWarning(peer, cid, err)
×
4130

×
4131
                        return
×
4132
                }
×
4133

4134
                chanOpts = append(
4✔
4135
                        chanOpts,
4✔
4136
                        lnwallet.WithLocalMusigNonces(localNonce),
4✔
4137
                        lnwallet.WithRemoteMusigNonces(&musig2.Nonces{
4✔
4138
                                PubNonce: remoteNonce,
4✔
4139
                        }),
4✔
4140
                )
4✔
4141

4✔
4142
                // Inform the aux funding controller that the liquidity in the
4✔
4143
                // custom channel is now ready to be advertised. We potentially
4✔
4144
                // haven't sent our own channel ready message yet, but other
4✔
4145
                // than that the channel is ready to count toward available
4✔
4146
                // liquidity.
4✔
4147
                err = fn.MapOptionZ(
4✔
4148
                        f.cfg.AuxFundingController,
4✔
4149
                        func(controller AuxFundingController) error {
4✔
4150
                                return controller.ChannelReady(
×
4151
                                        lnwallet.NewAuxChanState(channel),
×
4152
                                )
×
4153
                        },
×
4154
                )
4155
                if err != nil {
4✔
4156
                        cid := newChanIdentifier(msg.ChanID)
×
4157
                        f.sendWarning(peer, cid, err)
×
4158

×
4159
                        return
×
4160
                }
×
4161
        }
4162

4163
        // The channel_ready message contains the next commitment point we'll
4164
        // need to create the next commitment state for the remote party. So
4165
        // we'll insert that into the channel now before passing it along to
4166
        // other sub-systems.
4167
        err = channel.InsertNextRevocation(msg.NextPerCommitmentPoint)
26✔
4168
        if err != nil {
26✔
4169
                log.Errorf("unable to insert next commitment point: %v", err)
×
4170
                return
×
4171
        }
×
4172

4173
        // Before we can add the channel to the peer, we'll need to ensure that
4174
        // we have an initial forwarding policy set.
4175
        if err := f.ensureInitialForwardingPolicy(chanID, channel); err != nil {
26✔
4176
                log.Errorf("Unable to ensure initial forwarding policy: %v",
×
4177
                        err)
×
4178
        }
×
4179

4180
        err = peer.AddNewChannel(&lnpeer.NewChannel{
26✔
4181
                OpenChannel: channel,
26✔
4182
                ChanOpts:    chanOpts,
26✔
4183
        }, f.quit)
26✔
4184
        if err != nil {
26✔
4185
                log.Errorf("Unable to add new channel %v with peer %x: %v",
×
4186
                        channel.FundingOutpoint,
×
4187
                        peer.IdentityKey().SerializeCompressed(), err,
×
4188
                )
×
4189
        }
×
4190
}
4191

4192
// handleChannelReadyReceived is called once the remote's channelReady message
4193
// is received and processed. At this stage, we must have sent out our
4194
// channelReady message, once the remote's channelReady is processed, the
4195
// channel is now active, thus we change its state to `addedToGraph` to
4196
// let the channel start handling routing.
4197
func (f *Manager) handleChannelReadyReceived(channel *channeldb.OpenChannel,
4198
        scid *lnwire.ShortChannelID, pendingChanID PendingChanID,
4199
        updateChan chan<- *lnrpc.OpenStatusUpdate) error {
24✔
4200

24✔
4201
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
24✔
4202

24✔
4203
        // Since we've sent+received funding locked at this point, we
24✔
4204
        // can clean up the pending musig2 nonce state.
24✔
4205
        f.nonceMtx.Lock()
24✔
4206
        delete(f.pendingMusigNonces, chanID)
24✔
4207
        f.nonceMtx.Unlock()
24✔
4208

24✔
4209
        var peerAlias *lnwire.ShortChannelID
24✔
4210
        if channel.IsZeroConf() {
28✔
4211
                // We'll need to wait until channel_ready has been received and
4✔
4212
                // the peer lets us know the alias they want to use for the
4✔
4213
                // channel. With this information, we can then construct a
4✔
4214
                // ChannelUpdate for them.  If an alias does not yet exist,
4✔
4215
                // we'll just return, letting the next iteration of the loop
4✔
4216
                // check again.
4✔
4217
                var defaultAlias lnwire.ShortChannelID
4✔
4218
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
4✔
4219
                foundAlias, _ := f.cfg.AliasManager.GetPeerAlias(chanID)
4✔
4220
                if foundAlias == defaultAlias {
4✔
4221
                        return nil
×
4222
                }
×
4223

4224
                peerAlias = &foundAlias
4✔
4225
        }
4226

4227
        err := f.addToGraph(channel, scid, peerAlias, nil)
24✔
4228
        if err != nil {
24✔
4229
                return fmt.Errorf("failed adding to graph: %w", err)
×
4230
        }
×
4231

4232
        // As the channel is now added to the ChannelRouter's topology, the
4233
        // channel is moved to the next state of the state machine. It will be
4234
        // moved to the last state (actually deleted from the database) after
4235
        // the channel is finally announced.
4236
        err = f.saveChannelOpeningState(
24✔
4237
                &channel.FundingOutpoint, addedToGraph, scid,
24✔
4238
        )
24✔
4239
        if err != nil {
24✔
4240
                return fmt.Errorf("error setting channel state to"+
×
4241
                        " addedToGraph: %w", err)
×
4242
        }
×
4243

4244
        log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
24✔
4245
                "added to graph", chanID, scid)
24✔
4246

24✔
4247
        err = fn.MapOptionZ(
24✔
4248
                f.cfg.AuxFundingController,
24✔
4249
                func(controller AuxFundingController) error {
24✔
4250
                        return controller.ChannelReady(
×
4251
                                lnwallet.NewAuxChanState(channel),
×
4252
                        )
×
4253
                },
×
4254
        )
4255
        if err != nil {
24✔
4256
                return fmt.Errorf("failed notifying aux funding controller "+
×
4257
                        "about channel ready: %w", err)
×
4258
        }
×
4259

4260
        // Give the caller a final update notifying them that the channel is
4261
        fundingPoint := channel.FundingOutpoint
24✔
4262
        cp := &lnrpc.ChannelPoint{
24✔
4263
                FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
24✔
4264
                        FundingTxidBytes: fundingPoint.Hash[:],
24✔
4265
                },
24✔
4266
                OutputIndex: fundingPoint.Index,
24✔
4267
        }
24✔
4268

24✔
4269
        if updateChan != nil {
34✔
4270
                upd := &lnrpc.OpenStatusUpdate{
10✔
4271
                        Update: &lnrpc.OpenStatusUpdate_ChanOpen{
10✔
4272
                                ChanOpen: &lnrpc.ChannelOpenUpdate{
10✔
4273
                                        ChannelPoint: cp,
10✔
4274
                                },
10✔
4275
                        },
10✔
4276
                        PendingChanId: pendingChanID[:],
10✔
4277
                }
10✔
4278

10✔
4279
                select {
10✔
4280
                case updateChan <- upd:
10✔
4281
                case <-f.quit:
×
4282
                        return ErrFundingManagerShuttingDown
×
4283
                }
4284
        }
4285

4286
        return nil
24✔
4287
}
4288

4289
// ensureInitialForwardingPolicy ensures that we have an initial forwarding
4290
// policy set for the given channel. If we don't, we'll fall back to the default
4291
// values.
4292
func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID,
4293
        channel *channeldb.OpenChannel) error {
26✔
4294

26✔
4295
        // Before we can add the channel to the peer, we'll need to ensure that
26✔
4296
        // we have an initial forwarding policy set. This should always be the
26✔
4297
        // case except for a channel that was created with lnd <= 0.15.5 and
26✔
4298
        // is still pending while updating to this version.
26✔
4299
        var needDBUpdate bool
26✔
4300
        forwardingPolicy, err := f.getInitialForwardingPolicy(chanID)
26✔
4301
        if err != nil {
26✔
4302
                log.Errorf("Unable to fetch initial forwarding policy, "+
×
4303
                        "falling back to default values: %v", err)
×
4304

×
4305
                forwardingPolicy = f.defaultForwardingPolicy(
×
4306
                        channel.LocalChanCfg.ChannelStateBounds,
×
4307
                )
×
4308
                needDBUpdate = true
×
4309
        }
×
4310

4311
        // We only started storing the actual values for MinHTLCOut and MaxHTLC
4312
        // after 0.16.x, so if a channel was opened with such a version and is
4313
        // still pending while updating to this version, we'll need to set the
4314
        // values to the default values.
4315
        if forwardingPolicy.MinHTLCOut == 0 {
39✔
4316
                forwardingPolicy.MinHTLCOut = channel.LocalChanCfg.MinHTLC
13✔
4317
                needDBUpdate = true
13✔
4318
        }
13✔
4319
        if forwardingPolicy.MaxHTLC == 0 {
39✔
4320
                forwardingPolicy.MaxHTLC = channel.LocalChanCfg.MaxPendingAmount
13✔
4321
                needDBUpdate = true
13✔
4322
        }
13✔
4323

4324
        // And finally, if we found that the values currently stored aren't
4325
        // sufficient for the link, we'll update the database.
4326
        if needDBUpdate {
39✔
4327
                err := f.saveInitialForwardingPolicy(chanID, forwardingPolicy)
13✔
4328
                if err != nil {
13✔
4329
                        return fmt.Errorf("unable to update initial "+
×
4330
                                "forwarding policy: %v", err)
×
4331
                }
×
4332
        }
4333

4334
        return nil
26✔
4335
}
4336

4337
// newChanUpdate creates a new channel update message for the given channel.
4338
func (f *Manager) newChanUpdate(
4339
        chanUpdatechanFlags lnwire.ChanUpdateChanFlags,
4340
        shortChanID lnwire.ShortChannelID,
4341
        chanID lnwire.ChannelID,
4342
        fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi,
4343
        ourPolicy *models.ChannelEdgePolicy) (*lnwire.ChannelUpdate1,
4344
        error) {
26✔
4345

26✔
4346
        chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
26✔
4347

26✔
4348
        // Our channel update message flags will signal that we support the
26✔
4349
        // max_htlc field.
26✔
4350
        msgFlags := lnwire.ChanUpdateRequiredMaxHtlc
26✔
4351

26✔
4352
        // We announce the channel with the default values. Some of
26✔
4353
        // these values can later be changed by crafting a new ChannelUpdate.
26✔
4354
        chanUpdate := &lnwire.ChannelUpdate1{
26✔
4355
                ShortChannelID: shortChanID,
26✔
4356
                ChainHash:      chainHash,
26✔
4357
                Timestamp:      uint32(time.Now().Unix()),
26✔
4358
                MessageFlags:   msgFlags,
26✔
4359
                ChannelFlags:   chanUpdatechanFlags,
26✔
4360
                TimeLockDelta: uint16(
26✔
4361
                        f.cfg.DefaultRoutingPolicy.TimeLockDelta,
26✔
4362
                ),
26✔
4363
                HtlcMinimumMsat: fwdMinHTLC,
26✔
4364
                HtlcMaximumMsat: fwdMaxHTLC,
26✔
4365
        }
26✔
4366

26✔
4367
        // The caller of newChanAnnouncement is expected to provide the initial
26✔
4368
        // forwarding policy to be announced. If no persisted initial policy
26✔
4369
        // values are found, then we will use the default policy values in the
26✔
4370
        // channel announcement.
26✔
4371
        storedFwdingPolicy, err := f.getInitialForwardingPolicy(chanID)
26✔
4372
        if err != nil && !errors.Is(err, channeldb.ErrChannelNotFound) {
26✔
4373
                return nil, errors.Errorf("unable to generate channel "+
×
4374
                        "update announcement: %v", err)
×
4375
        }
×
4376

4377
        switch {
26✔
UNCOV
4378
        case ourPolicy != nil:
×
UNCOV
4379
                // If ourPolicy is non-nil, modify the default parameters of the
×
UNCOV
4380
                // ChannelUpdate.
×
NEW
4381
                chanUpdate.MessageFlags = ourPolicy.MessageFlags
×
NEW
4382
                chanUpdate.ChannelFlags = ourPolicy.ChannelFlags
×
NEW
4383
                chanUpdate.TimeLockDelta = ourPolicy.TimeLockDelta
×
NEW
4384
                chanUpdate.HtlcMinimumMsat = ourPolicy.MinHTLC
×
NEW
4385
                chanUpdate.HtlcMaximumMsat = ourPolicy.MaxHTLC
×
NEW
4386
                chanUpdate.BaseFee = uint32(ourPolicy.FeeBaseMSat)
×
NEW
4387
                chanUpdate.FeeRate = uint32(
×
UNCOV
4388
                        ourPolicy.FeeProportionalMillionths,
×
UNCOV
4389
                )
×
4390

4391
        case storedFwdingPolicy != nil:
26✔
4392
                chanUpdate.BaseFee = uint32(storedFwdingPolicy.BaseFee)
26✔
4393
                chanUpdate.FeeRate = uint32(storedFwdingPolicy.FeeRate)
26✔
4394

4395
        default:
×
4396
                log.Infof("No channel forwarding policy specified for channel "+
×
4397
                        "announcement of ChannelID(%v). "+
×
4398
                        "Assuming default fee parameters.", chanID)
×
NEW
4399
                chanUpdate.BaseFee = uint32(
×
4400
                        f.cfg.DefaultRoutingPolicy.BaseFee,
×
4401
                )
×
NEW
4402
                chanUpdate.FeeRate = uint32(
×
4403
                        f.cfg.DefaultRoutingPolicy.FeeRate,
×
4404
                )
×
4405
        }
4406

4407
        // With the channel update announcement constructed, we'll generate a
4408
        // signature that signs a double-sha digest of the announcement.
4409
        // This'll serve to authenticate this announcement and any other future
4410
        // updates we may send.
4411
        chanUpdateMsg, err := chanUpdate.DataToSign()
26✔
4412
        if err != nil {
26✔
4413
                return nil, err
×
4414
        }
×
4415
        sig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanUpdateMsg, true)
26✔
4416
        if err != nil {
26✔
4417
                return nil, errors.Errorf("unable to generate channel "+
×
4418
                        "update announcement signature: %v", err)
×
4419
        }
×
4420
        chanUpdate.Signature, err = lnwire.NewSigFromSignature(sig)
26✔
4421
        if err != nil {
26✔
4422
                return nil, errors.Errorf("unable to generate channel "+
×
4423
                        "update announcement signature: %v", err)
×
4424
        }
×
4425

4426
        return chanUpdate, nil
26✔
4427
}
4428

4429
// newChanProof creates a new channel proof message for the given channel
4430
// announcement message.
4431
func (f *Manager) newChanProof(
4432
        chanAnn *lnwire.ChannelAnnouncement1,
4433
        localFundingKey *keychain.KeyDescriptor,
4434
        chanID lnwire.ChannelID) (*lnwire.AnnounceSignatures1, error) {
16✔
4435

16✔
4436
        // The channel existence proofs itself is currently announced in
16✔
4437
        // distinct message. In order to properly authenticate this message, we
16✔
4438
        // need two signatures: one under the identity public key used which
16✔
4439
        // signs the message itself and another signature of the identity
16✔
4440
        // public key under the funding key itself.
16✔
4441
        //
16✔
4442
        // TODO(roasbeef): use SignAnnouncement here instead?
16✔
4443
        chanAnnMsg, err := chanAnn.DataToSign()
16✔
4444
        if err != nil {
16✔
4445
                return nil, err
×
4446
        }
×
4447
        nodeSig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanAnnMsg, true)
16✔
4448
        if err != nil {
16✔
4449
                return nil, errors.Errorf("unable to generate node "+
×
4450
                        "signature for channel announcement: %v", err)
×
4451
        }
×
4452
        bitcoinSig, err := f.cfg.SignMessage(
16✔
4453
                localFundingKey.KeyLocator, chanAnnMsg, true,
16✔
4454
        )
16✔
4455
        if err != nil {
16✔
4456
                return nil, errors.Errorf("unable to generate bitcoin "+
×
4457
                        "signature for node public key: %v", err)
×
4458
        }
×
4459

4460
        // Finally, we'll generate the announcement proof which we'll use to
4461
        // provide the other side with the necessary signatures required to
4462
        // allow them to reconstruct the full channel announcement.
4463
        proof := &lnwire.AnnounceSignatures1{
16✔
4464
                ChannelID:      chanID,
16✔
4465
                ShortChannelID: chanAnn.ShortChannelID,
16✔
4466
        }
16✔
4467
        proof.NodeSignature, err = lnwire.NewSigFromSignature(nodeSig)
16✔
4468
        if err != nil {
16✔
4469
                return nil, err
×
4470
        }
×
4471
        proof.BitcoinSignature, err = lnwire.NewSigFromSignature(bitcoinSig)
16✔
4472
        if err != nil {
16✔
4473
                return nil, err
×
4474
        }
×
4475

4476
        return proof, nil
16✔
4477
}
4478

4479
// newChanAnnouncement creates the channel announcement message for the given
4480
// channel without the signatures (proofs).
4481
func (f *Manager) newChanAnnouncement(localPubKey,
4482
        remotePubKey *btcec.PublicKey, localFundingKey *keychain.KeyDescriptor,
4483
        remoteFundingKey *btcec.PublicKey,
4484
        shortChanID lnwire.ShortChannelID,
4485
        chanType channeldb.ChannelType) (*lnwire.ChannelAnnouncement1, error) {
40✔
4486

40✔
4487
        chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
40✔
4488

40✔
4489
        // The unconditional section of the announcement is the ShortChannelID
40✔
4490
        // itself which compactly encodes the location of the funding output
40✔
4491
        // within the blockchain.
40✔
4492
        chanAnn := &lnwire.ChannelAnnouncement1{
40✔
4493
                ShortChannelID: shortChanID,
40✔
4494
                Features:       lnwire.NewRawFeatureVector(),
40✔
4495
                ChainHash:      chainHash,
40✔
4496
        }
40✔
4497

40✔
4498
        // If this is a taproot channel, then we'll set a special bit in the
40✔
4499
        // feature vector to indicate to the routing layer that this needs a
40✔
4500
        // slightly different type of validation.
40✔
4501
        //
40✔
4502
        // TODO(roasbeef): temp, remove after gossip 1.5
40✔
4503
        if chanType.IsTaproot() {
44✔
4504
                log.Debugf("Applying taproot feature bit to "+
4✔
4505
                        "ChannelAnnouncement for %v", shortChanID)
4✔
4506

4✔
4507
                chanAnn.Features.Set(
4✔
4508
                        lnwire.SimpleTaprootChannelsRequiredStaging,
4✔
4509
                )
4✔
4510
        }
4✔
4511

4512
        // The lexicographical ordering of the two identity public keys of the
4513
        // nodes indicates which of the nodes is "first". If our serialized
4514
        // identity key is lower than theirs then we're the "first" node and
4515
        // second otherwise.
4516
        selfBytes := localPubKey.SerializeCompressed()
40✔
4517
        remoteBytes := remotePubKey.SerializeCompressed()
40✔
4518
        if bytes.Compare(selfBytes, remoteBytes) == -1 {
60✔
4519
                copy(chanAnn.NodeID1[:], localPubKey.SerializeCompressed())
20✔
4520
                copy(chanAnn.NodeID2[:], remotePubKey.SerializeCompressed())
20✔
4521
                copy(
20✔
4522
                        chanAnn.BitcoinKey1[:],
20✔
4523
                        localFundingKey.PubKey.SerializeCompressed(),
20✔
4524
                )
20✔
4525
                copy(
20✔
4526
                        chanAnn.BitcoinKey2[:],
20✔
4527
                        remoteFundingKey.SerializeCompressed(),
20✔
4528
                )
20✔
4529
        } else {
40✔
4530
                copy(chanAnn.NodeID1[:], remotePubKey.SerializeCompressed())
20✔
4531
                copy(chanAnn.NodeID2[:], localPubKey.SerializeCompressed())
20✔
4532
                copy(
20✔
4533
                        chanAnn.BitcoinKey1[:],
20✔
4534
                        remoteFundingKey.SerializeCompressed(),
20✔
4535
                )
20✔
4536
                copy(
20✔
4537
                        chanAnn.BitcoinKey2[:],
20✔
4538
                        localFundingKey.PubKey.SerializeCompressed(),
20✔
4539
                )
20✔
4540
        }
20✔
4541

4542
        return chanAnn, nil
40✔
4543
}
4544

4545
// IsLexicographicallyFirst returns true if the node key of the first node is
4546
// lexicographically less than the node key of the second node.
4547
func IsLexicographicallyFirst(nodeKey1 *btcec.PublicKey,
4548
        nodeKey2 *btcec.PublicKey) bool {
26✔
4549

26✔
4550
        return bytes.Compare(nodeKey1.SerializeCompressed(),
26✔
4551
                nodeKey2.SerializeCompressed()) == -1
26✔
4552
}
26✔
4553

4554
// announceChannel announces a newly created channel to the rest of the network
4555
// by crafting the two authenticated announcements required for the peers on
4556
// the network to recognize the legitimacy of the channel. The crafted
4557
// announcements are then sent to the channel router to handle broadcasting to
4558
// the network during its next trickle.
4559
// This method is synchronous and will return when all the network requests
4560
// finish, either successfully or with an error.
4561
func (f *Manager) announceChannel(completeChan *channeldb.OpenChannel,
4562
        chanAnn *lnwire.ChannelAnnouncement1,
4563
        chanID lnwire.ChannelID) error {
16✔
4564

16✔
4565
        // First, we'll create the batch of announcements to be sent upon
16✔
4566
        // initial channel creation. This includes the channel announcement
16✔
4567
        // itself, the channel update announcement, and our half of the channel
16✔
4568
        // proof needed to fully authenticate the channel.
16✔
4569
        //
16✔
4570
        // We can pass in zeroes for the min and max htlc policy, because we
16✔
4571
        // only use the channel announcement message from the returned struct.
16✔
4572
        chanProof, err := f.newChanProof(
16✔
4573
                chanAnn, &completeChan.LocalChanCfg.MultiSigKey, chanID,
16✔
4574
        )
16✔
4575
        if err != nil {
16✔
4576
                log.Errorf("can't generate channel announcement: %v", err)
×
4577
                return err
×
4578
        }
×
4579

4580
        // We only send the channel proof announcement and the node announcement
4581
        // because addToGraph previously sent the ChannelAnnouncement and
4582
        // the ChannelUpdate announcement messages. The channel proof and node
4583
        // announcements are broadcast to the greater network.
4584
        errChan := f.cfg.SendAnnouncement(chanProof)
16✔
4585
        select {
16✔
4586
        case err := <-errChan:
16✔
4587
                if err != nil {
16✔
UNCOV
4588
                        if graph.IsError(err, graph.ErrOutdated,
×
UNCOV
4589
                                graph.ErrIgnored) {
×
4590

×
4591
                                log.Debugf("Graph rejected "+
×
4592
                                        "AnnounceSignatures: %v", err)
×
UNCOV
4593
                        } else {
×
UNCOV
4594
                                log.Errorf("Unable to send channel "+
×
UNCOV
4595
                                        "proof: %v", err)
×
UNCOV
4596
                                return err
×
UNCOV
4597
                        }
×
4598
                }
4599

4600
        case <-f.quit:
×
4601
                return ErrFundingManagerShuttingDown
×
4602
        }
4603

4604
        // Now that the channel is announced to the network, we will also
4605
        // obtain and send a node announcement. This is done since a node
4606
        // announcement is only accepted after a channel is known for that
4607
        // particular node, and this might be our first channel.
4608
        nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
16✔
4609
        if err != nil {
16✔
4610
                log.Errorf("can't generate node announcement: %v", err)
×
4611
                return err
×
4612
        }
×
4613

4614
        errChan = f.cfg.SendAnnouncement(&nodeAnn)
16✔
4615
        select {
16✔
4616
        case err := <-errChan:
16✔
4617
                if err != nil {
16✔
UNCOV
4618
                        if graph.IsError(err, graph.ErrOutdated,
×
UNCOV
4619
                                graph.ErrIgnored) {
×
UNCOV
4620

×
UNCOV
4621
                                log.Debugf("Graph rejected "+
×
UNCOV
4622
                                        "NodeAnnouncement: %v", err)
×
UNCOV
4623
                        } else {
×
4624
                                log.Errorf("Unable to send node "+
×
4625
                                        "announcement: %v", err)
×
4626
                                return err
×
4627
                        }
×
4628
                }
4629

4630
        case <-f.quit:
×
4631
                return ErrFundingManagerShuttingDown
×
4632
        }
4633

4634
        return nil
16✔
4635
}
4636

4637
// sendChanUpdate sends a ChannelUpdate to the gossiper which is as a
4638
// consequence sent to the peer.
4639
//
4640
// TODO(ziggie): Refactor the gossip msges so that not always all msges have
4641
// to be created but only the ones which are needed.
4642
func (f *Manager) sendChanUpdate(completeChan *channeldb.OpenChannel,
4643
        shortChanID *lnwire.ShortChannelID,
4644
        ourPolicy *models.ChannelEdgePolicy) error {
2✔
4645

2✔
4646
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
2✔
4647

2✔
4648
        fwdMinHTLC, fwdMaxHTLC := f.extractAnnounceParams(completeChan)
2✔
4649

2✔
4650
        chanUpdateChanFlags := lnwire.ChanUpdateChanFlags(0)
2✔
4651
        if !IsLexicographicallyFirst(f.cfg.IDKey,
2✔
4652
                completeChan.IdentityPub) {
3✔
4653

1✔
4654
                chanUpdateChanFlags = 1
1✔
4655
        }
1✔
4656

4657
        chanUpdate, err := f.newChanUpdate(
2✔
4658
                chanUpdateChanFlags, completeChan.ShortChanID(), chanID,
2✔
4659
                fwdMinHTLC, fwdMaxHTLC, ourPolicy,
2✔
4660
        )
2✔
4661
        if err != nil {
2✔
NEW
4662
                return fmt.Errorf("error generating channel update: %w", err)
×
NEW
4663
        }
×
4664

4665
        errChan := f.cfg.SendAnnouncement(chanUpdate)
2✔
4666
        select {
2✔
4667
        case err := <-errChan:
2✔
4668
                if err != nil {
2✔
NEW
4669
                        if graph.IsError(err, graph.ErrOutdated,
×
NEW
4670
                                graph.ErrIgnored) {
×
NEW
4671

×
NEW
4672
                                log.Debugf("Graph rejected "+
×
NEW
4673
                                        "ChannelUpdate: %v", err)
×
NEW
4674
                        } else {
×
NEW
4675
                                return fmt.Errorf("error sending channel "+
×
NEW
4676
                                        "update: %v", err)
×
NEW
4677
                        }
×
4678
                }
NEW
4679
        case <-f.quit:
×
NEW
4680
                return ErrFundingManagerShuttingDown
×
4681
        }
4682

4683
        return nil
2✔
4684
}
4685

4686
// InitFundingWorkflow sends a message to the funding manager instructing it
4687
// to initiate a single funder workflow with the source peer.
4688
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
56✔
4689
        f.fundingRequests <- msg
56✔
4690
}
56✔
4691

4692
// getUpfrontShutdownScript takes a user provided script and a getScript
4693
// function which can be used to generate an upfront shutdown script. If our
4694
// peer does not support the feature, this function will error if a non-zero
4695
// script was provided by the user, and return an empty script otherwise. If
4696
// our peer does support the feature, we will return the user provided script
4697
// if non-zero, or a freshly generated script if our node is configured to set
4698
// upfront shutdown scripts automatically.
4699
func getUpfrontShutdownScript(enableUpfrontShutdown bool, peer lnpeer.Peer,
4700
        script lnwire.DeliveryAddress,
4701
        getScript func(bool) (lnwire.DeliveryAddress, error)) (lnwire.DeliveryAddress,
4702
        error) {
108✔
4703

108✔
4704
        // Check whether the remote peer supports upfront shutdown scripts.
108✔
4705
        remoteUpfrontShutdown := peer.RemoteFeatures().HasFeature(
108✔
4706
                lnwire.UpfrontShutdownScriptOptional,
108✔
4707
        )
108✔
4708

108✔
4709
        // If the peer does not support upfront shutdown scripts, and one has been
108✔
4710
        // provided, return an error because the feature is not supported.
108✔
4711
        if !remoteUpfrontShutdown && len(script) != 0 {
109✔
4712
                return nil, errUpfrontShutdownScriptNotSupported
1✔
4713
        }
1✔
4714

4715
        // If the peer does not support upfront shutdown, return an empty address.
4716
        if !remoteUpfrontShutdown {
210✔
4717
                return nil, nil
103✔
4718
        }
103✔
4719

4720
        // If the user has provided an script and the peer supports the feature,
4721
        // return it. Note that user set scripts override the enable upfront
4722
        // shutdown flag.
4723
        if len(script) > 0 {
6✔
4724
                return script, nil
2✔
4725
        }
2✔
4726

4727
        // If we do not have setting of upfront shutdown script enabled, return
4728
        // an empty script.
4729
        if !enableUpfrontShutdown {
3✔
4730
                return nil, nil
1✔
4731
        }
1✔
4732

4733
        // We can safely send a taproot address iff, both sides have negotiated
4734
        // the shutdown-any-segwit feature.
4735
        taprootOK := peer.RemoteFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) &&
1✔
4736
                peer.LocalFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional)
1✔
4737

1✔
4738
        return getScript(taprootOK)
1✔
4739
}
4740

4741
// handleInitFundingMsg creates a channel reservation within the daemon's
4742
// wallet, then sends a funding request to the remote peer kicking off the
4743
// funding workflow.
4744
func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
56✔
4745
        var (
56✔
4746
                peerKey        = msg.Peer.IdentityKey()
56✔
4747
                localAmt       = msg.LocalFundingAmt
56✔
4748
                baseFee        = msg.BaseFee
56✔
4749
                feeRate        = msg.FeeRate
56✔
4750
                minHtlcIn      = msg.MinHtlcIn
56✔
4751
                remoteCsvDelay = msg.RemoteCsvDelay
56✔
4752
                maxValue       = msg.MaxValueInFlight
56✔
4753
                maxHtlcs       = msg.MaxHtlcs
56✔
4754
                maxCSV         = msg.MaxLocalCsv
56✔
4755
                chanReserve    = msg.RemoteChanReserve
56✔
4756
                outpoints      = msg.Outpoints
56✔
4757
        )
56✔
4758

56✔
4759
        // If no maximum CSV delay was set for this channel, we use our default
56✔
4760
        // value.
56✔
4761
        if maxCSV == 0 {
112✔
4762
                maxCSV = f.cfg.MaxLocalCSVDelay
56✔
4763
        }
56✔
4764

4765
        log.Infof("Initiating fundingRequest(local_amt=%v "+
56✔
4766
                "(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
56✔
4767
                "min_confs=%v)", localAmt, msg.SubtractFees, msg.PushAmt,
56✔
4768
                msg.ChainHash, peerKey.SerializeCompressed(), msg.MinConfs)
56✔
4769

56✔
4770
        // We set the channel flags to indicate whether we want this channel to
56✔
4771
        // be announced to the network.
56✔
4772
        var channelFlags lnwire.FundingFlag
56✔
4773
        if !msg.Private {
107✔
4774
                // This channel will be announced.
51✔
4775
                channelFlags = lnwire.FFAnnounceChannel
51✔
4776
        }
51✔
4777

4778
        // If the caller specified their own channel ID, then we'll use that.
4779
        // Otherwise we'll generate a fresh one as normal.  This will be used
4780
        // to track this reservation throughout its lifetime.
4781
        var chanID PendingChanID
56✔
4782
        if msg.PendingChanID == zeroID {
112✔
4783
                chanID = f.nextPendingChanID()
56✔
4784
        } else {
56✔
UNCOV
4785
                // If the user specified their own pending channel ID, then
×
UNCOV
4786
                // we'll ensure it doesn't collide with any existing pending
×
UNCOV
4787
                // channel ID.
×
UNCOV
4788
                chanID = msg.PendingChanID
×
UNCOV
4789
                if _, err := f.getReservationCtx(peerKey, chanID); err == nil {
×
4790
                        msg.Err <- fmt.Errorf("pendingChannelID(%x) "+
×
4791
                                "already present", chanID[:])
×
4792
                        return
×
4793
                }
×
4794
        }
4795

4796
        // Check whether the peer supports upfront shutdown, and get an address
4797
        // which should be used (either a user specified address or a new
4798
        // address from the wallet if our node is configured to set shutdown
4799
        // address by default).
4800
        shutdown, err := getUpfrontShutdownScript(
56✔
4801
                f.cfg.EnableUpfrontShutdown, msg.Peer, msg.ShutdownScript,
56✔
4802
                f.selectShutdownScript,
56✔
4803
        )
56✔
4804
        if err != nil {
56✔
4805
                msg.Err <- err
×
4806
                return
×
4807
        }
×
4808

4809
        // Initialize a funding reservation with the local wallet. If the
4810
        // wallet doesn't have enough funds to commit to this channel, then the
4811
        // request will fail, and be aborted.
4812
        //
4813
        // Before we init the channel, we'll also check to see what commitment
4814
        // format we can use with this peer. This is dependent on *both* us and
4815
        // the remote peer are signaling the proper feature bit.
4816
        chanType, commitType, err := negotiateCommitmentType(
56✔
4817
                msg.ChannelType, msg.Peer.LocalFeatures(),
56✔
4818
                msg.Peer.RemoteFeatures(),
56✔
4819
        )
56✔
4820
        if err != nil {
56✔
UNCOV
4821
                log.Errorf("channel type negotiation failed: %v", err)
×
UNCOV
4822
                msg.Err <- err
×
UNCOV
4823
                return
×
UNCOV
4824
        }
×
4825

4826
        var (
56✔
4827
                zeroConf bool
56✔
4828
                scid     bool
56✔
4829
        )
56✔
4830

56✔
4831
        if chanType != nil {
60✔
4832
                // Check if the returned chanType includes either the zero-conf
4✔
4833
                // or scid-alias bits.
4✔
4834
                featureVec := lnwire.RawFeatureVector(*chanType)
4✔
4835
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
4✔
4836
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
4✔
4837

4✔
4838
                // The option-scid-alias channel type for a public channel is
4✔
4839
                // disallowed.
4✔
4840
                if scid && !msg.Private {
4✔
4841
                        err = fmt.Errorf("option-scid-alias chantype for " +
×
4842
                                "public channel")
×
4843
                        log.Error(err)
×
4844
                        msg.Err <- err
×
4845

×
4846
                        return
×
4847
                }
×
4848
        }
4849

4850
        // First, we'll query the fee estimator for a fee that should get the
4851
        // commitment transaction confirmed by the next few blocks (conf target
4852
        // of 3). We target the near blocks here to ensure that we'll be able
4853
        // to execute a timely unilateral channel closure if needed.
4854
        commitFeePerKw, err := f.cfg.FeeEstimator.EstimateFeePerKW(3)
56✔
4855
        if err != nil {
56✔
4856
                msg.Err <- err
×
4857
                return
×
4858
        }
×
4859

4860
        // For anchor channels cap the initial commit fee rate at our defined
4861
        // maximum.
4862
        if commitType.HasAnchors() &&
56✔
4863
                commitFeePerKw > f.cfg.MaxAnchorsCommitFeeRate {
60✔
4864

4✔
4865
                commitFeePerKw = f.cfg.MaxAnchorsCommitFeeRate
4✔
4866
        }
4✔
4867

4868
        var scidFeatureVal bool
56✔
4869
        if hasFeatures(
56✔
4870
                msg.Peer.LocalFeatures(), msg.Peer.RemoteFeatures(),
56✔
4871
                lnwire.ScidAliasOptional,
56✔
4872
        ) {
59✔
4873

3✔
4874
                scidFeatureVal = true
3✔
4875
        }
3✔
4876

4877
        // At this point, if we have an AuxFundingController active, we'll check
4878
        // to see if we have a special tapscript root to use in our MuSig2
4879
        // funding output.
4880
        tapscriptRoot, err := fn.MapOptionZ(
56✔
4881
                f.cfg.AuxFundingController,
56✔
4882
                func(c AuxFundingController) AuxTapscriptResult {
56✔
4883
                        return c.DeriveTapscriptRoot(chanID)
×
4884
                },
×
4885
        ).Unpack()
4886
        if err != nil {
56✔
4887
                err = fmt.Errorf("error deriving tapscript root: %w", err)
×
4888
                log.Error(err)
×
4889
                msg.Err <- err
×
4890

×
4891
                return
×
4892
        }
×
4893

4894
        req := &lnwallet.InitFundingReserveMsg{
56✔
4895
                ChainHash:         &msg.ChainHash,
56✔
4896
                PendingChanID:     chanID,
56✔
4897
                NodeID:            peerKey,
56✔
4898
                NodeAddr:          msg.Peer.Address(),
56✔
4899
                SubtractFees:      msg.SubtractFees,
56✔
4900
                LocalFundingAmt:   localAmt,
56✔
4901
                RemoteFundingAmt:  0,
56✔
4902
                FundUpToMaxAmt:    msg.FundUpToMaxAmt,
56✔
4903
                MinFundAmt:        msg.MinFundAmt,
56✔
4904
                RemoteChanReserve: chanReserve,
56✔
4905
                Outpoints:         outpoints,
56✔
4906
                CommitFeePerKw:    commitFeePerKw,
56✔
4907
                FundingFeePerKw:   msg.FundingFeePerKw,
56✔
4908
                PushMSat:          msg.PushAmt,
56✔
4909
                Flags:             channelFlags,
56✔
4910
                MinConfs:          msg.MinConfs,
56✔
4911
                CommitType:        commitType,
56✔
4912
                ChanFunder:        msg.ChanFunder,
56✔
4913
                // Unconfirmed Utxos which are marked by the sweeper subsystem
56✔
4914
                // are excluded from the coin selection because they are not
56✔
4915
                // final and can be RBFed by the sweeper subsystem.
56✔
4916
                AllowUtxoForFunding: func(u lnwallet.Utxo) bool {
113✔
4917
                        // Utxos with at least 1 confirmation are safe to use
57✔
4918
                        // for channel openings because they don't bare the risk
57✔
4919
                        // of being replaced (BIP 125 RBF).
57✔
4920
                        if u.Confirmations > 0 {
57✔
UNCOV
4921
                                return true
×
UNCOV
4922
                        }
×
4923

4924
                        // Query the sweeper storage to make sure we don't use
4925
                        // an unconfirmed utxo still in use by the sweeper
4926
                        // subsystem.
4927
                        return !f.cfg.IsSweeperOutpoint(u.OutPoint)
57✔
4928
                },
4929
                ZeroConf:         zeroConf,
4930
                OptionScidAlias:  scid,
4931
                ScidAliasFeature: scidFeatureVal,
4932
                Memo:             msg.Memo,
4933
                TapscriptRoot:    tapscriptRoot,
4934
        }
4935

4936
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
56✔
4937
        if err != nil {
56✔
UNCOV
4938
                msg.Err <- err
×
UNCOV
4939
                return
×
UNCOV
4940
        }
×
4941

4942
        if zeroConf {
58✔
4943
                // Store the alias for zero-conf channels in the underlying
2✔
4944
                // partial channel state.
2✔
4945
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
2✔
4946
                if err != nil {
2✔
4947
                        msg.Err <- err
×
4948
                        return
×
4949
                }
×
4950

4951
                reservation.AddAlias(aliasScid)
2✔
4952
        }
4953

4954
        // Set our upfront shutdown address in the existing reservation.
4955
        reservation.SetOurUpfrontShutdown(shutdown)
56✔
4956

56✔
4957
        // Now that we have successfully reserved funds for this channel in the
56✔
4958
        // wallet, we can fetch the final channel capacity. This is done at
56✔
4959
        // this point since the final capacity might change in case of
56✔
4960
        // SubtractFees=true.
56✔
4961
        capacity := reservation.Capacity()
56✔
4962

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

56✔
4966
        // If the remote CSV delay was not set in the open channel request,
56✔
4967
        // we'll use the RequiredRemoteDelay closure to compute the delay we
56✔
4968
        // require given the total amount of funds within the channel.
56✔
4969
        if remoteCsvDelay == 0 {
111✔
4970
                remoteCsvDelay = f.cfg.RequiredRemoteDelay(capacity)
55✔
4971
        }
55✔
4972

4973
        // If no minimum HTLC value was specified, use the default one.
4974
        if minHtlcIn == 0 {
111✔
4975
                minHtlcIn = f.cfg.DefaultMinHtlcIn
55✔
4976
        }
55✔
4977

4978
        // If no max value was specified, use the default one.
4979
        if maxValue == 0 {
111✔
4980
                maxValue = f.cfg.RequiredRemoteMaxValue(capacity)
55✔
4981
        }
55✔
4982

4983
        if maxHtlcs == 0 {
112✔
4984
                maxHtlcs = f.cfg.RequiredRemoteMaxHTLCs(capacity)
56✔
4985
        }
56✔
4986

4987
        // Once the reservation has been created, and indexed, queue a funding
4988
        // request to the remote peer, kicking off the funding workflow.
4989
        ourContribution := reservation.OurContribution()
56✔
4990

56✔
4991
        // Prepare the optional channel fee values from the initFundingMsg. If
56✔
4992
        // useBaseFee or useFeeRate are false the client did not provide fee
56✔
4993
        // values hence we assume default fee settings from the config.
56✔
4994
        forwardingPolicy := f.defaultForwardingPolicy(
56✔
4995
                ourContribution.ChannelStateBounds,
56✔
4996
        )
56✔
4997
        if baseFee != nil {
57✔
4998
                forwardingPolicy.BaseFee = lnwire.MilliSatoshi(*baseFee)
1✔
4999
        }
1✔
5000

5001
        if feeRate != nil {
57✔
5002
                forwardingPolicy.FeeRate = lnwire.MilliSatoshi(*feeRate)
1✔
5003
        }
1✔
5004

5005
        // Fetch our dust limit which is part of the default channel
5006
        // constraints, and log it.
5007
        ourDustLimit := ourContribution.DustLimit
56✔
5008

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

56✔
5011
        // If the channel reserve is not specified, then we calculate an
56✔
5012
        // appropriate amount here.
56✔
5013
        if chanReserve == 0 {
108✔
5014
                chanReserve = f.cfg.RequiredRemoteChanReserve(
52✔
5015
                        capacity, ourDustLimit,
52✔
5016
                )
52✔
5017
        }
52✔
5018

5019
        // If a pending channel map for this peer isn't already created, then
5020
        // we create one, ultimately allowing us to track this pending
5021
        // reservation within the target peer.
5022
        peerIDKey := newSerializedKey(peerKey)
56✔
5023
        f.resMtx.Lock()
56✔
5024
        if _, ok := f.activeReservations[peerIDKey]; !ok {
105✔
5025
                f.activeReservations[peerIDKey] = make(pendingChannels)
49✔
5026
        }
49✔
5027

5028
        resCtx := &reservationWithCtx{
56✔
5029
                chanAmt:           capacity,
56✔
5030
                forwardingPolicy:  *forwardingPolicy,
56✔
5031
                remoteCsvDelay:    remoteCsvDelay,
56✔
5032
                remoteMinHtlc:     minHtlcIn,
56✔
5033
                remoteMaxValue:    maxValue,
56✔
5034
                remoteMaxHtlcs:    maxHtlcs,
56✔
5035
                remoteChanReserve: chanReserve,
56✔
5036
                maxLocalCsv:       maxCSV,
56✔
5037
                channelType:       chanType,
56✔
5038
                reservation:       reservation,
56✔
5039
                peer:              msg.Peer,
56✔
5040
                updates:           msg.Updates,
56✔
5041
                err:               msg.Err,
56✔
5042
        }
56✔
5043
        f.activeReservations[peerIDKey][chanID] = resCtx
56✔
5044
        f.resMtx.Unlock()
56✔
5045

56✔
5046
        // Update the timestamp once the InitFundingMsg has been handled.
56✔
5047
        defer resCtx.updateTimestamp()
56✔
5048

56✔
5049
        // Check the sanity of the selected channel constraints.
56✔
5050
        bounds := &channeldb.ChannelStateBounds{
56✔
5051
                ChanReserve:      chanReserve,
56✔
5052
                MaxPendingAmount: maxValue,
56✔
5053
                MinHTLC:          minHtlcIn,
56✔
5054
                MaxAcceptedHtlcs: maxHtlcs,
56✔
5055
        }
56✔
5056
        commitParams := &channeldb.CommitmentParams{
56✔
5057
                DustLimit: ourDustLimit,
56✔
5058
                CsvDelay:  remoteCsvDelay,
56✔
5059
        }
56✔
5060
        err = lnwallet.VerifyConstraints(
56✔
5061
                bounds, commitParams, resCtx.maxLocalCsv, capacity,
56✔
5062
        )
56✔
5063
        if err != nil {
58✔
5064
                _, reserveErr := f.cancelReservationCtx(peerKey, chanID, false)
2✔
5065
                if reserveErr != nil {
2✔
5066
                        log.Errorf("unable to cancel reservation: %v",
×
5067
                                reserveErr)
×
5068
                }
×
5069

5070
                msg.Err <- err
2✔
5071
                return
2✔
5072
        }
5073

5074
        // When opening a script enforced channel lease, include the required
5075
        // expiry TLV record in our proposal.
5076
        var leaseExpiry *lnwire.LeaseExpiry
54✔
5077
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
54✔
UNCOV
5078
                leaseExpiry = new(lnwire.LeaseExpiry)
×
UNCOV
5079
                *leaseExpiry = lnwire.LeaseExpiry(reservation.LeaseExpiry())
×
UNCOV
5080
        }
×
5081

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

54✔
5085
        reservation.SetState(lnwallet.SentOpenChannel)
54✔
5086

54✔
5087
        fundingOpen := lnwire.OpenChannel{
54✔
5088
                ChainHash:             *f.cfg.Wallet.Cfg.NetParams.GenesisHash,
54✔
5089
                PendingChannelID:      chanID,
54✔
5090
                FundingAmount:         capacity,
54✔
5091
                PushAmount:            msg.PushAmt,
54✔
5092
                DustLimit:             ourDustLimit,
54✔
5093
                MaxValueInFlight:      maxValue,
54✔
5094
                ChannelReserve:        chanReserve,
54✔
5095
                HtlcMinimum:           minHtlcIn,
54✔
5096
                FeePerKiloWeight:      uint32(commitFeePerKw),
54✔
5097
                CsvDelay:              remoteCsvDelay,
54✔
5098
                MaxAcceptedHTLCs:      maxHtlcs,
54✔
5099
                FundingKey:            ourContribution.MultiSigKey.PubKey,
54✔
5100
                RevocationPoint:       ourContribution.RevocationBasePoint.PubKey,
54✔
5101
                PaymentPoint:          ourContribution.PaymentBasePoint.PubKey,
54✔
5102
                HtlcPoint:             ourContribution.HtlcBasePoint.PubKey,
54✔
5103
                DelayedPaymentPoint:   ourContribution.DelayBasePoint.PubKey,
54✔
5104
                FirstCommitmentPoint:  ourContribution.FirstCommitmentPoint,
54✔
5105
                ChannelFlags:          channelFlags,
54✔
5106
                UpfrontShutdownScript: shutdown,
54✔
5107
                ChannelType:           chanType,
54✔
5108
                LeaseExpiry:           leaseExpiry,
54✔
5109
        }
54✔
5110

54✔
5111
        if commitType.IsTaproot() {
56✔
5112
                fundingOpen.LocalNonce = lnwire.SomeMusig2Nonce(
2✔
5113
                        ourContribution.LocalNonce.PubNonce,
2✔
5114
                )
2✔
5115
        }
2✔
5116

5117
        if err := msg.Peer.SendMessage(true, &fundingOpen); err != nil {
54✔
5118
                e := fmt.Errorf("unable to send funding request message: %w",
×
5119
                        err)
×
5120
                log.Errorf(e.Error())
×
5121

×
5122
                // Since we were unable to send the initial message to the peer
×
5123
                // and start the funding flow, we'll cancel this reservation.
×
5124
                _, err := f.cancelReservationCtx(peerKey, chanID, false)
×
5125
                if err != nil {
×
5126
                        log.Errorf("unable to cancel reservation: %v", err)
×
5127
                }
×
5128

5129
                msg.Err <- e
×
5130
                return
×
5131
        }
5132
}
5133

5134
// handleWarningMsg processes the warning which was received from remote peer.
5135
func (f *Manager) handleWarningMsg(peer lnpeer.Peer, msg *lnwire.Warning) {
42✔
5136
        log.Warnf("received warning message from peer %x: %v",
42✔
5137
                peer.IdentityKey().SerializeCompressed(), msg.Warning())
42✔
5138
}
42✔
5139

5140
// handleErrorMsg processes the error which was received from remote peer,
5141
// depending on the type of error we should do different clean up steps and
5142
// inform the user about it.
UNCOV
5143
func (f *Manager) handleErrorMsg(peer lnpeer.Peer, msg *lnwire.Error) {
×
UNCOV
5144
        chanID := msg.ChanID
×
UNCOV
5145
        peerKey := peer.IdentityKey()
×
UNCOV
5146

×
UNCOV
5147
        // First, we'll attempt to retrieve and cancel the funding workflow
×
UNCOV
5148
        // that this error was tied to. If we're unable to do so, then we'll
×
UNCOV
5149
        // exit early as this was an unwarranted error.
×
UNCOV
5150
        resCtx, err := f.cancelReservationCtx(peerKey, chanID, true)
×
UNCOV
5151
        if err != nil {
×
5152
                log.Warnf("Received error for non-existent funding "+
×
5153
                        "flow: %v (%v)", err, msg.Error())
×
5154
                return
×
5155
        }
×
5156

5157
        // If we did indeed find the funding workflow, then we'll return the
5158
        // error back to the caller (if any), and cancel the workflow itself.
UNCOV
5159
        fundingErr := fmt.Errorf("received funding error from %x: %v",
×
UNCOV
5160
                peerKey.SerializeCompressed(), msg.Error(),
×
UNCOV
5161
        )
×
UNCOV
5162
        log.Errorf(fundingErr.Error())
×
UNCOV
5163

×
UNCOV
5164
        // If this was a PSBT funding flow, the remote likely timed out because
×
UNCOV
5165
        // we waited too long. Return a nice error message to the user in that
×
UNCOV
5166
        // case so the user knows what's the problem.
×
UNCOV
5167
        if resCtx.reservation.IsPsbt() {
×
UNCOV
5168
                fundingErr = fmt.Errorf("%w: %v", chanfunding.ErrRemoteCanceled,
×
UNCOV
5169
                        fundingErr)
×
UNCOV
5170
        }
×
5171

UNCOV
5172
        resCtx.err <- fundingErr
×
5173
}
5174

5175
// pruneZombieReservations loops through all pending reservations and fails the
5176
// funding flow for any reservations that have not been updated since the
5177
// ReservationTimeout and are not locked waiting for the funding transaction.
5178
func (f *Manager) pruneZombieReservations() {
3✔
5179
        zombieReservations := make(pendingChannels)
3✔
5180

3✔
5181
        f.resMtx.RLock()
3✔
5182
        for _, pendingReservations := range f.activeReservations {
6✔
5183
                for pendingChanID, resCtx := range pendingReservations {
6✔
5184
                        if resCtx.isLocked() {
3✔
5185
                                continue
×
5186
                        }
5187

5188
                        // We don't want to expire PSBT funding reservations.
5189
                        // These reservations are always initiated by us and the
5190
                        // remote peer is likely going to cancel them after some
5191
                        // idle time anyway. So no need for us to also prune
5192
                        // them.
5193
                        sinceLastUpdate := time.Since(resCtx.lastUpdated)
3✔
5194
                        isExpired := sinceLastUpdate > f.cfg.ReservationTimeout
3✔
5195
                        if !resCtx.reservation.IsPsbt() && isExpired {
6✔
5196
                                zombieReservations[pendingChanID] = resCtx
3✔
5197
                        }
3✔
5198
                }
5199
        }
5200
        f.resMtx.RUnlock()
3✔
5201

3✔
5202
        for pendingChanID, resCtx := range zombieReservations {
6✔
5203
                err := fmt.Errorf("reservation timed out waiting for peer "+
3✔
5204
                        "(peer_id:%x, chan_id:%x)",
3✔
5205
                        resCtx.peer.IdentityKey().SerializeCompressed(),
3✔
5206
                        pendingChanID[:])
3✔
5207
                log.Warnf(err.Error())
3✔
5208

3✔
5209
                chanID := lnwire.NewChanIDFromOutPoint(
3✔
5210
                        *resCtx.reservation.FundingOutpoint(),
3✔
5211
                )
3✔
5212

3✔
5213
                // Create channel identifier and set the channel ID.
3✔
5214
                cid := newChanIdentifier(pendingChanID)
3✔
5215
                cid.setChanID(chanID)
3✔
5216

3✔
5217
                f.failFundingFlow(resCtx.peer, cid, err)
3✔
5218
        }
3✔
5219
}
5220

5221
// cancelReservationCtx does all needed work in order to securely cancel the
5222
// reservation.
5223
func (f *Manager) cancelReservationCtx(peerKey *btcec.PublicKey,
5224
        pendingChanID PendingChanID,
5225
        byRemote bool) (*reservationWithCtx, error) {
24✔
5226

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

24✔
5230
        peerIDKey := newSerializedKey(peerKey)
24✔
5231
        f.resMtx.Lock()
24✔
5232
        defer f.resMtx.Unlock()
24✔
5233

24✔
5234
        nodeReservations, ok := f.activeReservations[peerIDKey]
24✔
5235
        if !ok {
32✔
5236
                // No reservations for this node.
8✔
5237
                return nil, errors.Errorf("no active reservations for peer(%x)",
8✔
5238
                        peerIDKey[:])
8✔
5239
        }
8✔
5240

5241
        ctx, ok := nodeReservations[pendingChanID]
16✔
5242
        if !ok {
18✔
5243
                return nil, errors.Errorf("unknown channel (id: %x) for "+
2✔
5244
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
2✔
5245
        }
2✔
5246

5247
        // If the reservation was a PSBT funding flow and it was canceled by the
5248
        // remote peer, then we need to thread through a different error message
5249
        // to the subroutine that's waiting for the user input so it can return
5250
        // a nice error message to the user.
5251
        if ctx.reservation.IsPsbt() && byRemote {
14✔
UNCOV
5252
                ctx.reservation.RemoteCanceled()
×
UNCOV
5253
        }
×
5254

5255
        if err := ctx.reservation.Cancel(); err != nil {
14✔
5256
                return nil, errors.Errorf("unable to cancel reservation: %v",
×
5257
                        err)
×
5258
        }
×
5259

5260
        delete(nodeReservations, pendingChanID)
14✔
5261

14✔
5262
        // If this was the last active reservation for this peer, delete the
14✔
5263
        // peer's entry altogether.
14✔
5264
        if len(nodeReservations) == 0 {
28✔
5265
                delete(f.activeReservations, peerIDKey)
14✔
5266
        }
14✔
5267
        return ctx, nil
14✔
5268
}
5269

5270
// deleteReservationCtx deletes the reservation uniquely identified by the
5271
// target public key of the peer, and the specified pending channel ID.
5272
func (f *Manager) deleteReservationCtx(peerKey *btcec.PublicKey,
5273
        pendingChanID PendingChanID) {
54✔
5274

54✔
5275
        peerIDKey := newSerializedKey(peerKey)
54✔
5276
        f.resMtx.Lock()
54✔
5277
        defer f.resMtx.Unlock()
54✔
5278

54✔
5279
        nodeReservations, ok := f.activeReservations[peerIDKey]
54✔
5280
        if !ok {
54✔
5281
                // No reservations for this node.
×
5282
                return
×
5283
        }
×
5284
        delete(nodeReservations, pendingChanID)
54✔
5285

54✔
5286
        // If this was the last active reservation for this peer, delete the
54✔
5287
        // peer's entry altogether.
54✔
5288
        if len(nodeReservations) == 0 {
101✔
5289
                delete(f.activeReservations, peerIDKey)
47✔
5290
        }
47✔
5291
}
5292

5293
// getReservationCtx returns the reservation context for a particular pending
5294
// channel ID for a target peer.
5295
func (f *Manager) getReservationCtx(peerKey *btcec.PublicKey,
5296
        pendingChanID PendingChanID) (*reservationWithCtx, error) {
88✔
5297

88✔
5298
        peerIDKey := newSerializedKey(peerKey)
88✔
5299
        f.resMtx.RLock()
88✔
5300
        resCtx, ok := f.activeReservations[peerIDKey][pendingChanID]
88✔
5301
        f.resMtx.RUnlock()
88✔
5302

88✔
5303
        if !ok {
88✔
UNCOV
5304
                return nil, errors.Errorf("unknown channel (id: %x) for "+
×
UNCOV
5305
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
×
UNCOV
5306
        }
×
5307

5308
        return resCtx, nil
88✔
5309
}
5310

5311
// IsPendingChannel returns a boolean indicating whether the channel identified
5312
// by the pendingChanID and given peer is pending, meaning it is in the process
5313
// of being funded. After the funding transaction has been confirmed, the
5314
// channel will receive a new, permanent channel ID, and will no longer be
5315
// considered pending.
5316
func (f *Manager) IsPendingChannel(pendingChanID PendingChanID,
UNCOV
5317
        peer lnpeer.Peer) bool {
×
UNCOV
5318

×
UNCOV
5319
        peerIDKey := newSerializedKey(peer.IdentityKey())
×
UNCOV
5320
        f.resMtx.RLock()
×
UNCOV
5321
        _, ok := f.activeReservations[peerIDKey][pendingChanID]
×
UNCOV
5322
        f.resMtx.RUnlock()
×
UNCOV
5323

×
UNCOV
5324
        return ok
×
UNCOV
5325
}
×
5326

5327
func copyPubKey(pub *btcec.PublicKey) *btcec.PublicKey {
375✔
5328
        var tmp btcec.JacobianPoint
375✔
5329
        pub.AsJacobian(&tmp)
375✔
5330
        tmp.ToAffine()
375✔
5331
        return btcec.NewPublicKey(&tmp.X, &tmp.Y)
375✔
5332
}
375✔
5333

5334
// defaultForwardingPolicy returns the default forwarding policy based on the
5335
// default routing policy and our local channel constraints.
5336
func (f *Manager) defaultForwardingPolicy(
5337
        bounds channeldb.ChannelStateBounds) *models.ForwardingPolicy {
102✔
5338

102✔
5339
        return &models.ForwardingPolicy{
102✔
5340
                MinHTLCOut:    bounds.MinHTLC,
102✔
5341
                MaxHTLC:       bounds.MaxPendingAmount,
102✔
5342
                BaseFee:       f.cfg.DefaultRoutingPolicy.BaseFee,
102✔
5343
                FeeRate:       f.cfg.DefaultRoutingPolicy.FeeRate,
102✔
5344
                TimeLockDelta: f.cfg.DefaultRoutingPolicy.TimeLockDelta,
102✔
5345
        }
102✔
5346
}
102✔
5347

5348
// saveInitialForwardingPolicy saves the forwarding policy for the provided
5349
// chanPoint in the channelOpeningStateBucket.
5350
func (f *Manager) saveInitialForwardingPolicy(chanID lnwire.ChannelID,
5351
        forwardingPolicy *models.ForwardingPolicy) error {
67✔
5352

67✔
5353
        return f.cfg.ChannelDB.SaveInitialForwardingPolicy(
67✔
5354
                chanID, forwardingPolicy,
67✔
5355
        )
67✔
5356
}
67✔
5357

5358
// getInitialForwardingPolicy fetches the initial forwarding policy for a given
5359
// channel id from the database which will be applied during the channel
5360
// announcement phase.
5361
func (f *Manager) getInitialForwardingPolicy(
5362
        chanID lnwire.ChannelID) (*models.ForwardingPolicy, error) {
78✔
5363

78✔
5364
        return f.cfg.ChannelDB.GetInitialForwardingPolicy(chanID)
78✔
5365
}
78✔
5366

5367
// deleteInitialForwardingPolicy removes channel fees for this chanID from
5368
// the database.
5369
func (f *Manager) deleteInitialForwardingPolicy(chanID lnwire.ChannelID) error {
24✔
5370
        return f.cfg.ChannelDB.DeleteInitialForwardingPolicy(chanID)
24✔
5371
}
24✔
5372

5373
// saveChannelOpeningState saves the channelOpeningState for the provided
5374
// chanPoint to the channelOpeningStateBucket.
5375
func (f *Manager) saveChannelOpeningState(chanPoint *wire.OutPoint,
5376
        state channelOpeningState, shortChanID *lnwire.ShortChannelID) error {
92✔
5377

92✔
5378
        var outpointBytes bytes.Buffer
92✔
5379
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
92✔
5380
                return err
×
5381
        }
×
5382

5383
        // Save state and the uint64 representation of the shortChanID
5384
        // for later use.
5385
        scratch := make([]byte, 10)
92✔
5386
        byteOrder.PutUint16(scratch[:2], uint16(state))
92✔
5387
        byteOrder.PutUint64(scratch[2:], shortChanID.ToUint64())
92✔
5388

92✔
5389
        return f.cfg.ChannelDB.SaveChannelOpeningState(
92✔
5390
                outpointBytes.Bytes(), scratch,
92✔
5391
        )
92✔
5392
}
5393

5394
// getChannelOpeningState fetches the channelOpeningState for the provided
5395
// chanPoint from the database, or returns ErrChannelNotFound if the channel
5396
// is not found.
5397
func (f *Manager) getChannelOpeningState(chanPoint *wire.OutPoint) (
5398
        channelOpeningState, *lnwire.ShortChannelID, error) {
251✔
5399

251✔
5400
        var outpointBytes bytes.Buffer
251✔
5401
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
251✔
5402
                return 0, nil, err
×
5403
        }
×
5404

5405
        value, err := f.cfg.ChannelDB.GetChannelOpeningState(
251✔
5406
                outpointBytes.Bytes(),
251✔
5407
        )
251✔
5408
        if err != nil {
298✔
5409
                return 0, nil, err
47✔
5410
        }
47✔
5411

5412
        state := channelOpeningState(byteOrder.Uint16(value[:2]))
204✔
5413
        shortChanID := lnwire.NewShortChanIDFromInt(byteOrder.Uint64(value[2:]))
204✔
5414
        return state, &shortChanID, nil
204✔
5415
}
5416

5417
// deleteChannelOpeningState removes any state for chanPoint from the database.
5418
func (f *Manager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error {
24✔
5419
        var outpointBytes bytes.Buffer
24✔
5420
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
24✔
5421
                return err
×
5422
        }
×
5423

5424
        return f.cfg.ChannelDB.DeleteChannelOpeningState(
24✔
5425
                outpointBytes.Bytes(),
24✔
5426
        )
24✔
5427
}
5428

5429
// selectShutdownScript selects the shutdown script we should send to the peer.
5430
// If we can use taproot, then we prefer that, otherwise we'll use a p2wkh
5431
// script.
5432
func (f *Manager) selectShutdownScript(taprootOK bool,
5433
) (lnwire.DeliveryAddress, error) {
×
5434

×
5435
        addrType := lnwallet.WitnessPubKey
×
5436
        if taprootOK {
×
5437
                addrType = lnwallet.TaprootPubkey
×
5438
        }
×
5439

5440
        addr, err := f.cfg.Wallet.NewAddress(
×
5441
                addrType, false, lnwallet.DefaultAccountName,
×
5442
        )
×
5443
        if err != nil {
×
5444
                return nil, err
×
5445
        }
×
5446

5447
        return txscript.PayToAddrScript(addr)
×
5448
}
5449

5450
// waitForPeerOnline blocks until the peer specified by peerPubkey comes online
5451
// and then returns the online peer.
5452
func (f *Manager) waitForPeerOnline(peerPubkey *btcec.PublicKey) (lnpeer.Peer,
5453
        error) {
104✔
5454

104✔
5455
        peerChan := make(chan lnpeer.Peer, 1)
104✔
5456

104✔
5457
        var peerKey [33]byte
104✔
5458
        copy(peerKey[:], peerPubkey.SerializeCompressed())
104✔
5459

104✔
5460
        f.cfg.NotifyWhenOnline(peerKey, peerChan)
104✔
5461

104✔
5462
        var peer lnpeer.Peer
104✔
5463
        select {
104✔
5464
        case peer = <-peerChan:
103✔
5465
        case <-f.quit:
1✔
5466
                return peer, ErrFundingManagerShuttingDown
1✔
5467
        }
5468
        return peer, nil
103✔
5469
}
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