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

lightningnetwork / lnd / 17830307614

18 Sep 2025 01:29PM UTC coverage: 54.617% (-12.0%) from 66.637%
17830307614

Pull #10200

github

web-flow
Merge 181a0a7bc into b34fc964b
Pull Request #10200: github: change to form-based issue template

109249 of 200028 relevant lines covered (54.62%)

21896.43 hits per line

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

67.69
/funding/manager.go
1
package funding
2

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

13
        "github.com/btcsuite/btcd/blockchain"
14
        "github.com/btcsuite/btcd/btcec/v2"
15
        "github.com/btcsuite/btcd/btcec/v2/ecdsa"
16
        "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
17
        "github.com/btcsuite/btcd/btcutil"
18
        "github.com/btcsuite/btcd/chaincfg/chainhash"
19
        "github.com/btcsuite/btcd/txscript"
20
        "github.com/btcsuite/btcd/wire"
21
        "github.com/lightningnetwork/lnd/chainntnfs"
22
        "github.com/lightningnetwork/lnd/chanacceptor"
23
        "github.com/lightningnetwork/lnd/channeldb"
24
        "github.com/lightningnetwork/lnd/discovery"
25
        "github.com/lightningnetwork/lnd/fn/v2"
26
        "github.com/lightningnetwork/lnd/graph"
27
        "github.com/lightningnetwork/lnd/graph/db/models"
28
        "github.com/lightningnetwork/lnd/input"
29
        "github.com/lightningnetwork/lnd/keychain"
30
        "github.com/lightningnetwork/lnd/labels"
31
        "github.com/lightningnetwork/lnd/lncfg"
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 {
370✔
66
        scratch := make([]byte, 4)
370✔
67

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

72
        byteOrder.PutUint32(scratch, o.Index)
370✔
73
        _, err := w.Write(scratch)
370✔
74
        return err
370✔
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
        // pendingChansLimit is the maximum number of pending channels that we
105
        // can have. After this point, pending channel opens will start to be
106
        // rejected.
107
        pendingChansLimit = 50
108
)
109

110
var (
111
        // ErrFundingManagerShuttingDown is an error returned when attempting to
112
        // process a funding request/message but the funding manager has already
113
        // been signaled to shut down.
114
        ErrFundingManagerShuttingDown = errors.New("funding manager shutting " +
115
                "down")
116

117
        // ErrConfirmationTimeout is an error returned when we as a responder
118
        // are waiting for a funding transaction to confirm, but too many
119
        // blocks pass without confirmation.
120
        ErrConfirmationTimeout = errors.New("timeout waiting for funding " +
121
                "confirmation")
122

123
        // errUpfrontShutdownScriptNotSupported is returned if an upfront
124
        // shutdown script is set for a peer that does not support the feature
125
        // bit.
126
        errUpfrontShutdownScriptNotSupported = errors.New("peer does not " +
127
                "support option upfront shutdown script")
128

129
        zeroID [32]byte
130
)
131

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

145
        chanAmt btcutil.Amount
146

147
        // forwardingPolicy is the policy provided by the initFundingMsg.
148
        forwardingPolicy models.ForwardingPolicy
149

150
        // Constraints we require for the remote.
151
        remoteCsvDelay    uint16
152
        remoteMinHtlc     lnwire.MilliSatoshi
153
        remoteMaxValue    lnwire.MilliSatoshi
154
        remoteMaxHtlcs    uint16
155
        remoteChanReserve btcutil.Amount
156

157
        // maxLocalCsv is the maximum csv we will accept from the remote.
158
        maxLocalCsv uint16
159

160
        // channelType is the explicit channel type proposed by the initiator of
161
        // the channel.
162
        channelType *lnwire.ChannelType
163

164
        updateMtx   sync.RWMutex
165
        lastUpdated time.Time
166

167
        updates chan *lnrpc.OpenStatusUpdate
168
        err     chan error
169
}
170

171
// isLocked checks the reservation's timestamp to determine whether it is
172
// locked.
173
func (r *reservationWithCtx) isLocked() bool {
3✔
174
        r.updateMtx.RLock()
3✔
175
        defer r.updateMtx.RUnlock()
3✔
176

3✔
177
        // The time zero value represents a locked reservation.
3✔
178
        return r.lastUpdated.IsZero()
3✔
179
}
3✔
180

181
// updateTimestamp updates the reservation's timestamp with the current time.
182
func (r *reservationWithCtx) updateTimestamp() {
137✔
183
        r.updateMtx.Lock()
137✔
184
        defer r.updateMtx.Unlock()
137✔
185

137✔
186
        r.lastUpdated = time.Now()
137✔
187
}
137✔
188

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

198
        // TargetPubkey is the public key of the peer.
199
        TargetPubkey *btcec.PublicKey
200

201
        // ChainHash is the target genesis hash for this channel.
202
        ChainHash chainhash.Hash
203

204
        // SubtractFees set to true means that fees will be subtracted
205
        // from the LocalFundingAmt.
206
        SubtractFees bool
207

208
        // LocalFundingAmt is the size of the channel.
209
        LocalFundingAmt btcutil.Amount
210

211
        // BaseFee is the base fee charged for routing payments regardless of
212
        // the number of milli-satoshis sent.
213
        BaseFee *uint64
214

215
        // FeeRate is the fee rate in ppm (parts per million) that will be
216
        // charged proportionally based on the value of each forwarded HTLC, the
217
        // lowest possible rate is 0 with a granularity of 0.000001
218
        // (millionths).
219
        FeeRate *uint64
220

221
        // PushAmt is the amount pushed to the counterparty.
222
        PushAmt lnwire.MilliSatoshi
223

224
        // FundingFeePerKw is the fee for the funding transaction.
225
        FundingFeePerKw chainfee.SatPerKWeight
226

227
        // Private determines whether or not this channel will be private.
228
        Private bool
229

230
        // MinHtlcIn is the minimum incoming HTLC that we accept.
231
        MinHtlcIn lnwire.MilliSatoshi
232

233
        // RemoteCsvDelay is the CSV delay we require for the remote peer.
234
        RemoteCsvDelay uint16
235

236
        // RemoteChanReserve is the channel reserve we required for the remote
237
        // peer.
238
        RemoteChanReserve btcutil.Amount
239

240
        // MinConfs indicates the minimum number of confirmations that each
241
        // output selected to fund the channel should satisfy.
242
        MinConfs int32
243

244
        // ShutdownScript is an optional upfront shutdown script for the
245
        // channel. This value is optional, so may be nil.
246
        ShutdownScript lnwire.DeliveryAddress
247

248
        // MaxValueInFlight is the maximum amount of coins in MilliSatoshi
249
        // that can be pending within the channel. It only applies to the
250
        // remote party.
251
        MaxValueInFlight lnwire.MilliSatoshi
252

253
        // MaxHtlcs is the maximum number of HTLCs that the remote peer
254
        // can offer us.
255
        MaxHtlcs uint16
256

257
        // MaxLocalCsv is the maximum local csv delay we will accept from our
258
        // peer.
259
        MaxLocalCsv uint16
260

261
        // FundUpToMaxAmt is the maximum amount to try to commit to. If set, the
262
        // MinFundAmt field denotes the acceptable minimum amount to commit to,
263
        // while trying to commit as many coins as possible up to this value.
264
        FundUpToMaxAmt btcutil.Amount
265

266
        // MinFundAmt must be set iff FundUpToMaxAmt is set. It denotes the
267
        // minimum amount to commit to.
268
        MinFundAmt btcutil.Amount
269

270
        // Outpoints is a list of client-selected outpoints that should be used
271
        // for funding a channel. If LocalFundingAmt is specified then this
272
        // amount is allocated from the sum of outpoints towards funding. If
273
        // the FundUpToMaxAmt is specified the entirety of selected funds is
274
        // allocated towards channel funding.
275
        Outpoints []wire.OutPoint
276

277
        // ChanFunder is an optional channel funder that allows the caller to
278
        // control exactly how the channel funding is carried out. If not
279
        // specified, then the default chanfunding.WalletAssembler will be
280
        // used.
281
        ChanFunder chanfunding.Assembler
282

283
        // PendingChanID is not all zeroes (the default value), then this will
284
        // be the pending channel ID used for the funding flow within the wire
285
        // protocol.
286
        PendingChanID PendingChanID
287

288
        // ChannelType allows the caller to use an explicit channel type for the
289
        // funding negotiation. This type will only be observed if BOTH sides
290
        // support explicit channel type negotiation.
291
        ChannelType *lnwire.ChannelType
292

293
        // Memo is any arbitrary information we wish to store locally about the
294
        // channel that will be useful to our future selves.
295
        Memo []byte
296

297
        // Updates is a channel which updates to the opening status of the
298
        // channel are sent on.
299
        Updates chan *lnrpc.OpenStatusUpdate
300

301
        // Err is a channel which errors encountered during the funding flow are
302
        // sent on.
303
        Err chan error
304
}
305

306
// fundingMsg is sent by the ProcessFundingMsg function and packages a
307
// funding-specific lnwire.Message along with the lnpeer.Peer that sent it.
308
type fundingMsg struct {
309
        msg  lnwire.Message
310
        peer lnpeer.Peer
311
}
312

313
// pendingChannels is a map instantiated per-peer which tracks all active
314
// pending single funded channels indexed by their pending channel identifier,
315
// which is a set of 32-bytes generated via a CSPRNG.
316
type pendingChannels map[PendingChanID]*reservationWithCtx
317

318
// serializedPubKey is used within the FundingManager's activeReservations list
319
// to identify the nodes with which the FundingManager is actively working to
320
// initiate new channels.
321
type serializedPubKey [33]byte
322

323
// newSerializedKey creates a new serialized public key from an instance of a
324
// live pubkey object.
325
func newSerializedKey(pubKey *btcec.PublicKey) serializedPubKey {
389✔
326
        var s serializedPubKey
389✔
327
        copy(s[:], pubKey.SerializeCompressed())
389✔
328
        return s
389✔
329
}
389✔
330

331
// DevConfig specifies configs used for integration test only.
332
type DevConfig struct {
333
        // ProcessChannelReadyWait is the duration to sleep before processing
334
        // remote node's channel ready message once the channel as been marked
335
        // as `channelReadySent`.
336
        ProcessChannelReadyWait time.Duration
337

338
        // MaxWaitNumBlocksFundingConf is the maximum number of blocks to wait
339
        // for the funding transaction to be confirmed before forgetting
340
        // channels that aren't initiated by us.
341
        MaxWaitNumBlocksFundingConf uint32
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, *btcec.PublicKey)
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, *btcec.PublicKey)
524

525
        // NotifyFundingTimeout informs the ChannelNotifier when a pending-open
526
        // channel times out because the funding transaction hasn't confirmed.
527
        // This is only called for the fundee and only if the channel is
528
        // zero-conf.
529
        NotifyFundingTimeout func(wire.OutPoint, *btcec.PublicKey)
530

531
        // EnableUpfrontShutdown specifies whether the upfront shutdown script
532
        // is enabled.
533
        EnableUpfrontShutdown bool
534

535
        // MaxAnchorsCommitFeeRate is the max commitment fee rate we'll use as
536
        // the initiator for channels of the anchor type.
537
        MaxAnchorsCommitFeeRate chainfee.SatPerKWeight
538

539
        // DeleteAliasEdge allows the Manager to delete an alias channel edge
540
        // from the graph. It also returns our local to-be-deleted policy.
541
        DeleteAliasEdge func(scid lnwire.ShortChannelID) (
542
                *models.ChannelEdgePolicy, error)
543

544
        // AliasManager is an implementation of the aliasHandler interface that
545
        // abstracts away the handling of many alias functions.
546
        AliasManager aliasHandler
547

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

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

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

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

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

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

586
        // cfg is a copy of the configuration struct that the FundingManager
587
        // was initialized with.
588
        cfg *Config
589

590
        // chanIDKey is a cryptographically random key that's used to generate
591
        // temporary channel ID's.
592
        chanIDKey [32]byte
593

594
        // chanIDNonce is a nonce that's incremented for each new funding
595
        // reservation created.
596
        chanIDNonce atomic.Uint64
597

598
        // nonceMtx is a mutex that guards the pendingMusigNonces.
599
        nonceMtx sync.RWMutex
600

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

612
        // activeReservations is a map which houses the state of all pending
613
        // funding workflows.
614
        activeReservations map[serializedPubKey]pendingChannels
615

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

623
        // resMtx guards both of the maps above to ensure that all access is
624
        // goroutine safe.
625
        resMtx sync.RWMutex
626

627
        // fundingMsgs is a channel that relays fundingMsg structs from
628
        // external sub-systems using the ProcessFundingMsg call.
629
        fundingMsgs chan *fundingMsg
630

631
        // fundingRequests is a channel used to receive channel initiation
632
        // requests from a local subsystem within the daemon.
633
        fundingRequests chan *InitFundingMsg
634

635
        localDiscoverySignals *lnutils.SyncMap[lnwire.ChannelID, chan struct{}]
636

637
        handleChannelReadyBarriers *lnutils.SyncMap[lnwire.ChannelID, struct{}]
638

639
        quit chan struct{}
640
        wg   sync.WaitGroup
641
}
642

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

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

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

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

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

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

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

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

733
        for _, channel := range allChannels {
118✔
734
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
9✔
735

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

1✔
745
                        f.localDiscoverySignals.Store(
1✔
746
                                chanID, make(chan struct{}),
1✔
747
                        )
1✔
748

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

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

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

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

778
        f.wg.Add(1) // TODO(roasbeef): tune
109✔
779
        go f.reservationCoordinator()
109✔
780

109✔
781
        return nil
109✔
782
}
783

784
// Stop signals all helper goroutines to execute a graceful shutdown. This
785
// method will block until all goroutines have exited.
786
func (f *Manager) Stop() error {
106✔
787
        f.stopped.Do(func() {
211✔
788
                log.Info("Funding manager shutting down...")
105✔
789
                defer log.Debug("Funding manager shutdown complete")
105✔
790

105✔
791
                close(f.quit)
105✔
792
                f.wg.Wait()
105✔
793
        })
105✔
794

795
        return nil
106✔
796
}
797

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

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

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

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

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

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

57✔
838
        var nonceBytes [8]byte
57✔
839
        binary.LittleEndian.PutUint64(nonceBytes[:], nextNonce)
57✔
840

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

57✔
851
        return nextChanID
57✔
852
}
57✔
853

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

×
860
        f.resMtx.Lock()
×
861
        defer f.resMtx.Unlock()
×
862

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

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

881
                resCtx.err <- fmt.Errorf("peer disconnected")
×
882
                delete(nodeReservations, pendingID)
×
883
        }
884

885
        // Finally, we'll delete the node itself from the set of reservations.
886
        delete(f.activeReservations, nodePub)
×
887
}
888

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

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

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

913
// newChanIdentifier creates a new chanIdentifier.
914
func newChanIdentifier(tempChanID lnwire.ChannelID) *chanIdentifier {
148✔
915
        return &chanIdentifier{
148✔
916
                tempChanID: tempChanID,
148✔
917
        }
148✔
918
}
148✔
919

920
// setChanID updates the `chanIdentifier` with the active channel ID.
921
func (c *chanIdentifier) setChanID(chanID lnwire.ChannelID) {
91✔
922
        c.chanID = chanID
91✔
923
        c.chanIDSet = true
91✔
924
}
91✔
925

926
// hasChanID returns true if the active channel ID has been set.
927
func (c *chanIdentifier) hasChanID() bool {
21✔
928
        return c.chanIDSet
21✔
929
}
21✔
930

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

21✔
941
        log.Debugf("Failing funding flow for pending_id=%v: %v",
21✔
942
                cid.tempChanID, fundingErr)
21✔
943

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

957
        ctx, err := f.cancelReservationCtx(
21✔
958
                peer.IdentityKey(), cid.tempChanID, false,
21✔
959
        )
21✔
960
        if err != nil {
30✔
961
                log.Errorf("unable to cancel reservation: %v", err)
9✔
962
        }
9✔
963

964
        // In case the case where the reservation existed, send the funding
965
        // error on the error channel.
966
        if ctx != nil {
33✔
967
                ctx.err <- fundingErr
12✔
968
        }
12✔
969

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

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

988
        errMsg := &lnwire.Error{
21✔
989
                ChanID: cid.tempChanID,
21✔
990
                Data:   msg,
21✔
991
        }
21✔
992

21✔
993
        log.Debugf("Sending funding error to peer (%x): %v",
21✔
994
                peer.IdentityKey().SerializeCompressed(),
21✔
995
                lnutils.SpewLogClosure(errMsg))
21✔
996

21✔
997
        if err := peer.SendMessage(false, errMsg); err != nil {
21✔
998
                log.Errorf("unable to send error message to peer %v", err)
×
999
        }
×
1000
}
1001

1002
// sendWarning sends a new warning message to the target peer, targeting the
1003
// specified cid with the passed funding error.
1004
func (f *Manager) sendWarning(peer lnpeer.Peer, cid *chanIdentifier,
1005
        fundingErr error) {
×
1006

×
1007
        msg := fundingErr.Error()
×
1008

×
1009
        errMsg := &lnwire.Warning{
×
1010
                ChanID: cid.tempChanID,
×
1011
                Data:   lnwire.WarningData(msg),
×
1012
        }
×
1013

×
1014
        log.Debugf("Sending funding warning to peer (%x): %v",
×
1015
                peer.IdentityKey().SerializeCompressed(),
×
1016
                lnutils.SpewLogClosure(errMsg),
×
1017
        )
×
1018

×
1019
        if err := peer.SendMessage(false, errMsg); err != nil {
×
1020
                log.Errorf("unable to send error message to peer %v", err)
×
1021
        }
×
1022
}
1023

1024
// reservationCoordinator is the primary goroutine tasked with progressing the
1025
// funding workflow between the wallet, and any outside peers or local callers.
1026
//
1027
// NOTE: This MUST be run as a goroutine.
1028
func (f *Manager) reservationCoordinator() {
109✔
1029
        defer f.wg.Done()
109✔
1030

109✔
1031
        zombieSweepTicker := time.NewTicker(f.cfg.ZombieSweeperInterval)
109✔
1032
        defer zombieSweepTicker.Stop()
109✔
1033

109✔
1034
        for {
490✔
1035
                select {
381✔
1036
                case fmsg := <-f.fundingMsgs:
215✔
1037
                        switch msg := fmsg.msg.(type) {
215✔
1038
                        case *lnwire.OpenChannel:
54✔
1039
                                f.fundeeProcessOpenChannel(fmsg.peer, msg)
54✔
1040

1041
                        case *lnwire.AcceptChannel:
33✔
1042
                                f.funderProcessAcceptChannel(fmsg.peer, msg)
33✔
1043

1044
                        case *lnwire.FundingCreated:
28✔
1045
                                f.fundeeProcessFundingCreated(fmsg.peer, msg)
28✔
1046

1047
                        case *lnwire.FundingSigned:
28✔
1048
                                f.funderProcessFundingSigned(fmsg.peer, msg)
28✔
1049

1050
                        case *lnwire.ChannelReady:
28✔
1051
                                f.wg.Add(1)
28✔
1052
                                go f.handleChannelReady(fmsg.peer, msg)
28✔
1053

1054
                        case *lnwire.Warning:
44✔
1055
                                f.handleWarningMsg(fmsg.peer, msg)
44✔
1056

1057
                        case *lnwire.Error:
×
1058
                                f.handleErrorMsg(fmsg.peer, msg)
×
1059
                        }
1060
                case req := <-f.fundingRequests:
57✔
1061
                        f.handleInitFundingMsg(req)
57✔
1062

1063
                case <-zombieSweepTicker.C:
×
1064
                        f.pruneZombieReservations()
×
1065

1066
                case <-f.quit:
105✔
1067
                        return
105✔
1068
                }
1069
        }
1070
}
1071

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

65✔
1084
        defer f.wg.Done()
65✔
1085

65✔
1086
        // If the channel is still pending we must wait for the funding
65✔
1087
        // transaction to confirm.
65✔
1088
        if channel.IsPending {
122✔
1089
                err := f.advancePendingChannelState(channel, pendingChanID)
57✔
1090
                if err != nil {
80✔
1091
                        log.Errorf("Unable to advance pending state of "+
23✔
1092
                                "ChannelPoint(%v): %v",
23✔
1093
                                channel.FundingOutpoint, err)
23✔
1094
                        return
23✔
1095
                }
23✔
1096
        }
1097

1098
        var chanOpts []lnwallet.ChannelOpt
42✔
1099
        f.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
84✔
1100
                chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
42✔
1101
        })
42✔
1102
        f.cfg.AuxSigner.WhenSome(func(s lnwallet.AuxSigner) {
84✔
1103
                chanOpts = append(chanOpts, lnwallet.WithAuxSigner(s))
42✔
1104
        })
42✔
1105
        f.cfg.AuxResolver.WhenSome(func(s lnwallet.AuxContractResolver) {
42✔
1106
                chanOpts = append(chanOpts, lnwallet.WithAuxResolver(s))
×
1107
        })
×
1108

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

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

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

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

123✔
1167
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
123✔
1168
        log.Debugf("Channel(%v) with ShortChanID %v has opening state %v",
123✔
1169
                chanID, shortChanID, channelState)
123✔
1170

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

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

1194
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
34✔
1195
                        "sent ChannelReady", chanID, shortChanID)
34✔
1196

34✔
1197
                return nil
34✔
1198

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

1212
                if !received {
96✔
1213
                        // We haven't received ChannelReady, so we'll continue
36✔
1214
                        // to the next iteration of the loop after sleeping for
36✔
1215
                        // checkPeerChannelReadyInterval.
36✔
1216
                        select {
36✔
1217
                        case <-time.After(checkPeerChannelReadyInterval):
24✔
1218
                        case <-f.quit:
12✔
1219
                                return ErrFundingManagerShuttingDown
12✔
1220
                        }
1221

1222
                        return nil
24✔
1223
                }
1224

1225
                return f.handleChannelReadyReceived(
24✔
1226
                        channel, shortChanID, pendingChanID, updateChan,
24✔
1227
                )
24✔
1228

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

1242
                        // Update the local shortChanID variable such that
1243
                        // annAfterSixConfs uses the confirmed SCID.
1244
                        confirmedScid := channel.ZeroConfRealScid()
4✔
1245
                        shortChanID = &confirmedScid
4✔
1246
                }
1247

1248
                err := f.annAfterSixConfs(channel, shortChanID)
26✔
1249
                if err != nil {
28✔
1250
                        return fmt.Errorf("error sending channel "+
2✔
1251
                                "announcement: %v", err)
2✔
1252
                }
2✔
1253

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

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

1275
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
24✔
1276
                        "announced", chanID, shortChanID)
24✔
1277

24✔
1278
                return nil
24✔
1279
        }
1280

1281
        return fmt.Errorf("undefined channelState: %v", channelState)
×
1282
}
1283

1284
// advancePendingChannelState waits for a pending channel's funding tx to
1285
// confirm, and marks it open in the database when that happens.
1286
func (f *Manager) advancePendingChannelState(channel *channeldb.OpenChannel,
1287
        pendingChanID PendingChanID) error {
57✔
1288

57✔
1289
        if channel.IsZeroConf() {
61✔
1290
                // Persist the alias to the alias database.
4✔
1291
                baseScid := channel.ShortChannelID
4✔
1292
                err := f.cfg.AliasManager.AddLocalAlias(
4✔
1293
                        baseScid, baseScid, true, false,
4✔
1294
                )
4✔
1295
                if err != nil {
4✔
1296
                        return fmt.Errorf("error adding local alias to "+
×
1297
                                "store: %v", err)
×
1298
                }
×
1299

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

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

1321
                // Inform the ChannelNotifier that the channel has transitioned
1322
                // from pending open to open.
1323
                f.cfg.NotifyOpenChannelEvent(
4✔
1324
                        channel.FundingOutpoint, channel.IdentityPub,
4✔
1325
                )
4✔
1326

4✔
1327
                // Find and close the discoverySignal for this channel such
4✔
1328
                // that ChannelReady messages will be processed.
4✔
1329
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
4✔
1330
                discoverySignal, ok := f.localDiscoverySignals.Load(chanID)
4✔
1331
                if ok {
8✔
1332
                        close(discoverySignal)
4✔
1333
                }
4✔
1334

1335
                return nil
4✔
1336
        }
1337

1338
        confChannel, err := f.waitForFundingWithTimeout(channel)
53✔
1339
        if err == ErrConfirmationTimeout {
55✔
1340
                return f.fundingTimeout(channel, pendingChanID)
2✔
1341
        } else if err != nil {
74✔
1342
                return fmt.Errorf("error waiting for funding "+
21✔
1343
                        "confirmation for ChannelPoint(%v): %v",
21✔
1344
                        channel.FundingOutpoint, err)
21✔
1345
        }
21✔
1346

1347
        if blockchain.IsCoinBaseTx(confChannel.fundingTx) {
32✔
1348
                // If it's a coinbase transaction, we need to wait for it to
2✔
1349
                // mature. We wait out an additional MinAcceptDepth on top of
2✔
1350
                // the coinbase maturity as an extra margin of safety.
2✔
1351
                maturity := f.cfg.Wallet.Cfg.NetParams.CoinbaseMaturity
2✔
1352
                numCoinbaseConfs := uint32(maturity)
2✔
1353

2✔
1354
                if channel.NumConfsRequired > maturity {
2✔
1355
                        numCoinbaseConfs = uint32(channel.NumConfsRequired)
×
1356
                }
×
1357

1358
                txid := &channel.FundingOutpoint.Hash
2✔
1359
                fundingScript, err := makeFundingScript(channel)
2✔
1360
                if err != nil {
2✔
1361
                        log.Errorf("unable to create funding script for "+
×
1362
                                "ChannelPoint(%v): %v",
×
1363
                                channel.FundingOutpoint, err)
×
1364

×
1365
                        return err
×
1366
                }
×
1367

1368
                confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
2✔
1369
                        txid, fundingScript, numCoinbaseConfs,
2✔
1370
                        channel.BroadcastHeight(),
2✔
1371
                )
2✔
1372
                if err != nil {
2✔
1373
                        log.Errorf("Unable to register for confirmation of "+
×
1374
                                "ChannelPoint(%v): %v",
×
1375
                                channel.FundingOutpoint, err)
×
1376

×
1377
                        return err
×
1378
                }
×
1379

1380
                select {
2✔
1381
                case _, ok := <-confNtfn.Confirmed:
2✔
1382
                        if !ok {
2✔
1383
                                return fmt.Errorf("ChainNotifier shutting "+
×
1384
                                        "down, can't complete funding flow "+
×
1385
                                        "for ChannelPoint(%v)",
×
1386
                                        channel.FundingOutpoint)
×
1387
                        }
×
1388

1389
                case <-f.quit:
×
1390
                        return ErrFundingManagerShuttingDown
×
1391
                }
1392
        }
1393

1394
        // Success, funding transaction was confirmed.
1395
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
30✔
1396
        log.Debugf("ChannelID(%v) is now fully confirmed! "+
30✔
1397
                "(shortChanID=%v)", chanID, confChannel.shortChanID)
30✔
1398

30✔
1399
        err = f.handleFundingConfirmation(channel, confChannel)
30✔
1400
        if err != nil {
30✔
1401
                return fmt.Errorf("unable to handle funding "+
×
1402
                        "confirmation for ChannelPoint(%v): %v",
×
1403
                        channel.FundingOutpoint, err)
×
1404
        }
×
1405

1406
        return nil
30✔
1407
}
1408

1409
// ProcessFundingMsg sends a message to the internal fundingManager goroutine,
1410
// allowing it to handle the lnwire.Message.
1411
func (f *Manager) ProcessFundingMsg(msg lnwire.Message, peer lnpeer.Peer) {
216✔
1412
        select {
216✔
1413
        case f.fundingMsgs <- &fundingMsg{msg, peer}:
216✔
1414
        case <-f.quit:
×
1415
                return
×
1416
        }
1417
}
1418

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

54✔
1430
        // Check number of pending channels to be smaller than maximum allowed
54✔
1431
        // number and send ErrorGeneric to remote peer if condition is
54✔
1432
        // violated.
54✔
1433
        peerPubKey := peer.IdentityKey()
54✔
1434
        peerIDKey := newSerializedKey(peerPubKey)
54✔
1435

54✔
1436
        amt := msg.FundingAmount
54✔
1437

54✔
1438
        // We get all pending channels for this peer. This is the list of the
54✔
1439
        // active reservations and the channels pending open in the database.
54✔
1440
        f.resMtx.RLock()
54✔
1441
        reservations := f.activeReservations[peerIDKey]
54✔
1442

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

54✔
1454
        // Create the channel identifier.
54✔
1455
        cid := newChanIdentifier(msg.PendingChannelID)
54✔
1456

54✔
1457
        // Also count the channels that are already pending. There we don't know
54✔
1458
        // the underlying intent anymore, unfortunately.
54✔
1459
        channels, err := f.cfg.ChannelDB.FetchOpenChannels(peerPubKey)
54✔
1460
        if err != nil {
54✔
1461
                f.failFundingFlow(peer, cid, err)
×
1462
                return
×
1463
        }
×
1464

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

1477
        // TODO(roasbeef): modify to only accept a _single_ pending channel per
1478
        // block unless white listed
1479
        if numPending >= f.cfg.MaxPendingChannels {
58✔
1480
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
4✔
1481

4✔
1482
                return
4✔
1483
        }
4✔
1484

1485
        // Ensure that the pendingChansLimit is respected.
1486
        pendingChans, err := f.cfg.ChannelDB.FetchPendingChannels()
50✔
1487
        if err != nil {
50✔
1488
                f.failFundingFlow(peer, cid, err)
×
1489
                return
×
1490
        }
×
1491

1492
        if len(pendingChans) > pendingChansLimit {
50✔
1493
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
×
1494
                return
×
1495
        }
×
1496

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

1510
        // Ensure that the remote party respects our maximum channel size.
1511
        if amt > f.cfg.MaxChanSize {
52✔
1512
                f.failFundingFlow(
2✔
1513
                        peer, cid,
2✔
1514
                        lnwallet.ErrChanTooLarge(amt, f.cfg.MaxChanSize),
2✔
1515
                )
2✔
1516
                return
2✔
1517
        }
2✔
1518

1519
        // We'll, also ensure that the remote party isn't attempting to propose
1520
        // a channel that's below our current min channel size.
1521
        if amt < f.cfg.MinChanSize {
48✔
1522
                f.failFundingFlow(
×
1523
                        peer, cid,
×
1524
                        lnwallet.ErrChanTooSmall(amt, f.cfg.MinChanSize),
×
1525
                )
×
1526
                return
×
1527
        }
×
1528

1529
        // If request specifies non-zero push amount and 'rejectpush' is set,
1530
        // signal an error.
1531
        if f.cfg.RejectPush && msg.PushAmount > 0 {
49✔
1532
                f.failFundingFlow(peer, cid, lnwallet.ErrNonZeroPushAmount())
1✔
1533
                return
1✔
1534
        }
1✔
1535

1536
        // Send the OpenChannel request to the ChannelAcceptor to determine
1537
        // whether this node will accept the channel.
1538
        chanReq := &chanacceptor.ChannelAcceptRequest{
47✔
1539
                Node:        peer.IdentityKey(),
47✔
1540
                OpenChanMsg: msg,
47✔
1541
        }
47✔
1542

47✔
1543
        // Query our channel acceptor to determine whether we should reject
47✔
1544
        // the channel.
47✔
1545
        acceptorResp := f.cfg.OpenChannelPredicate.Accept(chanReq)
47✔
1546
        if acceptorResp.RejectChannel() {
47✔
1547
                f.failFundingFlow(peer, cid, acceptorResp.ChanAcceptError)
×
1548
                return
×
1549
        }
×
1550

1551
        log.Infof("Recv'd fundingRequest(amt=%v, push=%v, delay=%v, "+
47✔
1552
                "pendingId=%x) from peer(%x)", amt, msg.PushAmount,
47✔
1553
                msg.CsvDelay, msg.PendingChannelID,
47✔
1554
                peer.IdentityKey().SerializeCompressed())
47✔
1555

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

1577
        var scidFeatureVal bool
47✔
1578
        if hasFeatures(
47✔
1579
                peer.LocalFeatures(), peer.RemoteFeatures(),
47✔
1580
                lnwire.ScidAliasOptional,
47✔
1581
        ) {
50✔
1582

3✔
1583
                scidFeatureVal = true
3✔
1584
        }
3✔
1585

1586
        var (
47✔
1587
                zeroConf bool
47✔
1588
                scid     bool
47✔
1589
        )
47✔
1590

47✔
1591
        // Only echo back a channel type in AcceptChannel if we actually used
47✔
1592
        // explicit negotiation above.
47✔
1593
        if chanType != nil {
51✔
1594
                // Check if the channel type includes the zero-conf or
4✔
1595
                // scid-alias bits.
4✔
1596
                featureVec := lnwire.RawFeatureVector(*chanType)
4✔
1597
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
4✔
1598
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
4✔
1599

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

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

1629
                        // Set zeroConf to true to enable the zero-conf flow.
1630
                        zeroConf = true
×
1631
                }
1632
        }
1633

1634
        public := msg.ChannelFlags&lnwire.FFAnnounceChannel != 0
47✔
1635
        switch {
47✔
1636
        // Sending the option-scid-alias channel type for a public channel is
1637
        // disallowed.
1638
        case public && scid:
×
1639
                err = fmt.Errorf("option-scid-alias chantype for public " +
×
1640
                        "channel")
×
1641
                log.Errorf("Cancelling funding flow for public channel %v "+
×
1642
                        "with scid-alias: %v", cid, err)
×
1643
                f.failFundingFlow(peer, cid, err)
×
1644

×
1645
                return
×
1646

1647
        // The current variant of taproot channels can only be used with
1648
        // unadvertised channels for now.
1649
        case commitType.IsTaproot() && public:
×
1650
                err = fmt.Errorf("taproot channel type for public channel")
×
1651
                log.Errorf("Cancelling funding flow for public taproot "+
×
1652
                        "channel %v: %v", cid, err)
×
1653
                f.failFundingFlow(peer, cid, err)
×
1654

×
1655
                return
×
1656
        }
1657

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

×
1672
                return
×
1673
        }
×
1674

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

47✔
1694
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
47✔
1695
        if err != nil {
47✔
1696
                log.Errorf("Unable to initialize reservation: %v", err)
×
1697
                f.failFundingFlow(peer, cid, err)
×
1698
                return
×
1699
        }
×
1700

1701
        log.Debugf("Initialized channel reservation: zeroConf=%v, psbt=%v, "+
47✔
1702
                "cannedShim=%v", reservation.IsZeroConf(),
47✔
1703
                reservation.IsPsbt(), reservation.IsCannedShim())
47✔
1704

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

1715
                reservation.AddAlias(aliasScid)
2✔
1716
        }
1717

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

1729
        // We'll ignore the min_depth calculated above if this is a zero-conf
1730
        // channel.
1731
        if zeroConf {
49✔
1732
                numConfsReq = 0
2✔
1733
        }
2✔
1734

1735
        reservation.SetNumConfsRequired(numConfsReq)
47✔
1736

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

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

47✔
1775
        // If a script enforced channel lease is being proposed, we'll need to
47✔
1776
        // validate its custom TLV records.
47✔
1777
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
47✔
1778
                if msg.LeaseExpiry == nil {
×
1779
                        err := errors.New("missing lease expiry")
×
1780
                        f.failFundingFlow(peer, cid, err)
×
1781
                        return
×
1782
                }
×
1783

1784
                // If we had a shim registered for this channel prior to
1785
                // receiving its corresponding OpenChannel message, then we'll
1786
                // validate the proposed LeaseExpiry against what was registered
1787
                // in our shim.
1788
                if reservation.LeaseExpiry() != 0 {
×
1789
                        if uint32(*msg.LeaseExpiry) !=
×
1790
                                reservation.LeaseExpiry() {
×
1791

×
1792
                                err := errors.New("lease expiry mismatch")
×
1793
                                f.failFundingFlow(peer, cid, err)
×
1794
                                return
×
1795
                        }
×
1796
                }
1797
        }
1798

1799
        log.Infof("Requiring %v confirmations for pendingChan(%x): "+
47✔
1800
                "amt=%v, push_amt=%v, committype=%v, upfrontShutdown=%x",
47✔
1801
                numConfsReq, msg.PendingChannelID, amt, msg.PushAmount,
47✔
1802
                commitType, msg.UpfrontShutdownScript)
47✔
1803

47✔
1804
        // Generate our required constraints for the remote party, using the
47✔
1805
        // values provided by the channel acceptor if they are non-zero.
47✔
1806
        remoteCsvDelay := f.cfg.RequiredRemoteDelay(amt)
47✔
1807
        if acceptorResp.CSVDelay != 0 {
47✔
1808
                remoteCsvDelay = acceptorResp.CSVDelay
×
1809
        }
×
1810

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

1823
        chanReserve := f.cfg.RequiredRemoteChanReserve(amt, maxDustLimit)
47✔
1824
        if acceptorResp.Reserve != 0 {
47✔
1825
                chanReserve = acceptorResp.Reserve
×
1826
        }
×
1827

1828
        remoteMaxValue := f.cfg.RequiredRemoteMaxValue(amt)
47✔
1829
        if acceptorResp.InFlightTotal != 0 {
47✔
1830
                remoteMaxValue = acceptorResp.InFlightTotal
×
1831
        }
×
1832

1833
        maxHtlcs := f.cfg.RequiredRemoteMaxHTLCs(amt)
47✔
1834
        if acceptorResp.HtlcLimit != 0 {
47✔
1835
                maxHtlcs = acceptorResp.HtlcLimit
×
1836
        }
×
1837

1838
        // Default to our default minimum hltc value, replacing it with the
1839
        // channel acceptor's value if it is set.
1840
        minHtlc := f.cfg.DefaultMinHtlcIn
47✔
1841
        if acceptorResp.MinHtlcIn != 0 {
47✔
1842
                minHtlc = acceptorResp.MinHtlcIn
×
1843
        }
×
1844

1845
        // If we are handling a FundingOpen request then we need to specify the
1846
        // default channel fees since they are not provided by the responder
1847
        // interactively.
1848
        ourContribution := reservation.OurContribution()
47✔
1849
        forwardingPolicy := f.defaultForwardingPolicy(
47✔
1850
                ourContribution.ChannelStateBounds,
47✔
1851
        )
47✔
1852

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

47✔
1877
        // Update the timestamp once the fundingOpenMsg has been handled.
47✔
1878
        defer resCtx.updateTimestamp()
47✔
1879

47✔
1880
        cfg := channeldb.ChannelConfig{
47✔
1881
                ChannelStateBounds: channeldb.ChannelStateBounds{
47✔
1882
                        MaxPendingAmount: remoteMaxValue,
47✔
1883
                        ChanReserve:      chanReserve,
47✔
1884
                        MinHTLC:          minHtlc,
47✔
1885
                        MaxAcceptedHtlcs: maxHtlcs,
47✔
1886
                },
47✔
1887
                CommitmentParams: channeldb.CommitmentParams{
47✔
1888
                        DustLimit: msg.DustLimit,
47✔
1889
                        CsvDelay:  remoteCsvDelay,
47✔
1890
                },
47✔
1891
                MultiSigKey: keychain.KeyDescriptor{
47✔
1892
                        PubKey: copyPubKey(msg.FundingKey),
47✔
1893
                },
47✔
1894
                RevocationBasePoint: keychain.KeyDescriptor{
47✔
1895
                        PubKey: copyPubKey(msg.RevocationPoint),
47✔
1896
                },
47✔
1897
                PaymentBasePoint: keychain.KeyDescriptor{
47✔
1898
                        PubKey: copyPubKey(msg.PaymentPoint),
47✔
1899
                },
47✔
1900
                DelayBasePoint: keychain.KeyDescriptor{
47✔
1901
                        PubKey: copyPubKey(msg.DelayedPaymentPoint),
47✔
1902
                },
47✔
1903
                HtlcBasePoint: keychain.KeyDescriptor{
47✔
1904
                        PubKey: copyPubKey(msg.HtlcPoint),
47✔
1905
                },
47✔
1906
        }
47✔
1907

47✔
1908
        // With our parameters set, we'll now process their contribution so we
47✔
1909
        // can move the funding workflow ahead.
47✔
1910
        remoteContribution := &lnwallet.ChannelContribution{
47✔
1911
                FundingAmount:        amt,
47✔
1912
                FirstCommitmentPoint: msg.FirstCommitmentPoint,
47✔
1913
                ChannelConfig:        &cfg,
47✔
1914
                UpfrontShutdown:      msg.UpfrontShutdownScript,
47✔
1915
        }
47✔
1916

47✔
1917
        if resCtx.reservation.IsTaproot() {
49✔
1918
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
2✔
1919
                if err != nil {
2✔
1920
                        log.Error(errNoLocalNonce)
×
1921

×
1922
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
1923

×
1924
                        return
×
1925
                }
×
1926

1927
                remoteContribution.LocalNonce = &musig2.Nonces{
2✔
1928
                        PubNonce: localNonce,
2✔
1929
                }
2✔
1930
        }
1931

1932
        err = reservation.ProcessSingleContribution(remoteContribution)
47✔
1933
        if err != nil {
53✔
1934
                log.Errorf("unable to add contribution reservation: %v", err)
6✔
1935
                f.failFundingFlow(peer, cid, err)
6✔
1936
                return
6✔
1937
        }
6✔
1938

1939
        log.Infof("Sending fundingResp for pending_id(%x)",
41✔
1940
                msg.PendingChannelID)
41✔
1941
        bounds := remoteContribution.ChannelConfig.ChannelStateBounds
41✔
1942
        log.Debugf("Remote party accepted channel state space bounds: %v",
41✔
1943
                lnutils.SpewLogClosure(bounds))
41✔
1944
        params := remoteContribution.ChannelConfig.CommitmentParams
41✔
1945
        log.Debugf("Remote party accepted commitment rendering params: %v",
41✔
1946
                lnutils.SpewLogClosure(params))
41✔
1947

41✔
1948
        reservation.SetState(lnwallet.SentAcceptChannel)
41✔
1949

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

41✔
1972
        if commitType.IsTaproot() {
43✔
1973
                fundingAccept.LocalNonce = lnwire.SomeMusig2Nonce(
2✔
1974
                        ourContribution.LocalNonce.PubNonce,
2✔
1975
                )
2✔
1976
        }
2✔
1977

1978
        if err := peer.SendMessage(true, &fundingAccept); err != nil {
41✔
1979
                log.Errorf("unable to send funding response to peer: %v", err)
×
1980
                f.failFundingFlow(peer, cid, err)
×
1981
                return
×
1982
        }
×
1983
}
1984

1985
// funderProcessAcceptChannel processes a response to the workflow initiation
1986
// sent by the remote peer. This message then queues a message with the funding
1987
// outpoint, and a commitment signature to the remote peer.
1988
//
1989
//nolint:funlen
1990
func (f *Manager) funderProcessAcceptChannel(peer lnpeer.Peer,
1991
        msg *lnwire.AcceptChannel) {
33✔
1992

33✔
1993
        pendingChanID := msg.PendingChannelID
33✔
1994
        peerKey := peer.IdentityKey()
33✔
1995
        var peerKeyBytes []byte
33✔
1996
        if peerKey != nil {
66✔
1997
                peerKeyBytes = peerKey.SerializeCompressed()
33✔
1998
        }
33✔
1999

2000
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
33✔
2001
        if err != nil {
33✔
2002
                log.Warnf("Can't find reservation (peerKey:%x, chan_id:%v)",
×
2003
                        peerKeyBytes, pendingChanID)
×
2004
                return
×
2005
        }
×
2006

2007
        // Update the timestamp once the fundingAcceptMsg has been handled.
2008
        defer resCtx.updateTimestamp()
33✔
2009

33✔
2010
        if resCtx.reservation.State() != lnwallet.SentOpenChannel {
33✔
2011
                return
×
2012
        }
×
2013

2014
        log.Infof("Recv'd fundingResponse for pending_id(%x)",
33✔
2015
                pendingChanID[:])
33✔
2016

33✔
2017
        // Create the channel identifier.
33✔
2018
        cid := newChanIdentifier(msg.PendingChannelID)
33✔
2019

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

2040
                // We'll want to do the same with the LeaseExpiry if one should
2041
                // be set.
2042
                if resCtx.reservation.LeaseExpiry() != 0 {
3✔
2043
                        if msg.LeaseExpiry == nil {
×
2044
                                err := errors.New("lease expiry not echoed " +
×
2045
                                        "back")
×
2046
                                f.failFundingFlow(peer, cid, err)
×
2047
                                return
×
2048
                        }
×
2049
                        if uint32(*msg.LeaseExpiry) !=
×
2050
                                resCtx.reservation.LeaseExpiry() {
×
2051

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

×
2067
                _, negotiatedCommitType, err := negotiateCommitmentType(
×
2068
                        msg.ChannelType, peer.LocalFeatures(),
×
2069
                        peer.RemoteFeatures(),
×
2070
                )
×
2071
                if err != nil {
×
2072
                        err := errors.New("received unexpected channel type")
×
2073
                        f.failFundingFlow(peer, cid, err)
×
2074
                        return
×
2075
                }
×
2076

2077
                if implicitCommitType != negotiatedCommitType {
×
2078
                        err := errors.New("negotiated unexpected channel type")
×
2079
                        f.failFundingFlow(peer, cid, err)
×
2080
                        return
×
2081
                }
×
2082
        }
2083

2084
        // The required number of confirmations should not be greater than the
2085
        // maximum number of confirmations required by the ChainNotifier to
2086
        // properly dispatch confirmations.
2087
        if msg.MinAcceptDepth > chainntnfs.MaxNumConfs {
33✔
2088
                err := lnwallet.ErrNumConfsTooLarge(
1✔
2089
                        msg.MinAcceptDepth, chainntnfs.MaxNumConfs,
1✔
2090
                )
1✔
2091
                log.Warnf("Unacceptable channel constraints: %v", err)
1✔
2092
                f.failFundingFlow(peer, cid, err)
1✔
2093
                return
1✔
2094
        }
1✔
2095

2096
        // Check that zero-conf channels have minimum depth set to 0.
2097
        if resCtx.reservation.IsZeroConf() && msg.MinAcceptDepth != 0 {
31✔
2098
                err = fmt.Errorf("zero-conf channel has min_depth non-zero")
×
2099
                log.Warn(err)
×
2100
                f.failFundingFlow(peer, cid, err)
×
2101
                return
×
2102
        }
×
2103

2104
        // If this is not a zero-conf channel but the peer responded with a
2105
        // min-depth of zero, we will use our minimum of 1 instead.
2106
        minDepth := msg.MinAcceptDepth
31✔
2107
        if !resCtx.reservation.IsZeroConf() && minDepth == 0 {
31✔
2108
                log.Infof("Responder to pending_id=%v sent a minimum "+
×
2109
                        "confirmation depth of 0 for non-zero-conf channel. "+
×
2110
                        "We will use a minimum depth of 1 instead.",
×
2111
                        cid.tempChanID)
×
2112

×
2113
                minDepth = 1
×
2114
        }
×
2115

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

2139
        cfg := channeldb.ChannelConfig{
30✔
2140
                ChannelStateBounds: channeldb.ChannelStateBounds{
30✔
2141
                        MaxPendingAmount: resCtx.remoteMaxValue,
30✔
2142
                        ChanReserve:      resCtx.remoteChanReserve,
30✔
2143
                        MinHTLC:          resCtx.remoteMinHtlc,
30✔
2144
                        MaxAcceptedHtlcs: resCtx.remoteMaxHtlcs,
30✔
2145
                },
30✔
2146
                CommitmentParams: channeldb.CommitmentParams{
30✔
2147
                        DustLimit: msg.DustLimit,
30✔
2148
                        CsvDelay:  resCtx.remoteCsvDelay,
30✔
2149
                },
30✔
2150
                MultiSigKey: keychain.KeyDescriptor{
30✔
2151
                        PubKey: copyPubKey(msg.FundingKey),
30✔
2152
                },
30✔
2153
                RevocationBasePoint: keychain.KeyDescriptor{
30✔
2154
                        PubKey: copyPubKey(msg.RevocationPoint),
30✔
2155
                },
30✔
2156
                PaymentBasePoint: keychain.KeyDescriptor{
30✔
2157
                        PubKey: copyPubKey(msg.PaymentPoint),
30✔
2158
                },
30✔
2159
                DelayBasePoint: keychain.KeyDescriptor{
30✔
2160
                        PubKey: copyPubKey(msg.DelayedPaymentPoint),
30✔
2161
                },
30✔
2162
                HtlcBasePoint: keychain.KeyDescriptor{
30✔
2163
                        PubKey: copyPubKey(msg.HtlcPoint),
30✔
2164
                },
30✔
2165
        }
30✔
2166

30✔
2167
        // The remote node has responded with their portion of the channel
30✔
2168
        // contribution. At this point, we can process their contribution which
30✔
2169
        // allows us to construct and sign both the commitment transaction, and
30✔
2170
        // the funding transaction.
30✔
2171
        remoteContribution := &lnwallet.ChannelContribution{
30✔
2172
                FirstCommitmentPoint: msg.FirstCommitmentPoint,
30✔
2173
                ChannelConfig:        &cfg,
30✔
2174
                UpfrontShutdown:      msg.UpfrontShutdownScript,
30✔
2175
        }
30✔
2176

30✔
2177
        if resCtx.reservation.IsTaproot() {
32✔
2178
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
2✔
2179
                if err != nil {
2✔
2180
                        log.Error(errNoLocalNonce)
×
2181

×
2182
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
2183

×
2184
                        return
×
2185
                }
×
2186

2187
                remoteContribution.LocalNonce = &musig2.Nonces{
2✔
2188
                        PubNonce: localNonce,
2✔
2189
                }
2✔
2190
        }
2191

2192
        err = resCtx.reservation.ProcessContribution(remoteContribution)
30✔
2193

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

2236
        log.Infof("pendingChan(%x): remote party proposes num_confs=%v, "+
30✔
2237
                "csv_delay=%v", pendingChanID[:], msg.MinAcceptDepth,
30✔
2238
                msg.CsvDelay)
30✔
2239
        bounds = remoteContribution.ChannelConfig.ChannelStateBounds
30✔
2240
        log.Debugf("Remote party accepted channel state space bounds: %v",
30✔
2241
                lnutils.SpewLogClosure(bounds))
30✔
2242
        commitParams = remoteContribution.ChannelConfig.CommitmentParams
30✔
2243
        log.Debugf("Remote party accepted commitment rendering params: %v",
30✔
2244
                lnutils.SpewLogClosure(commitParams))
30✔
2245

30✔
2246
        // If the user requested funding through a PSBT, we cannot directly
30✔
2247
        // continue now and need to wait for the fully funded and signed PSBT
30✔
2248
        // to arrive. To not block any other channels from opening, we wait in
30✔
2249
        // a separate goroutine.
30✔
2250
        if psbtIntent != nil {
30✔
2251
                f.wg.Add(1)
×
2252
                go func() {
×
2253
                        defer f.wg.Done()
×
2254

×
2255
                        f.waitForPsbt(psbtIntent, resCtx, cid)
×
2256
                }()
×
2257

2258
                // With the new goroutine spawned, we can now exit to unblock
2259
                // the main event loop.
2260
                return
×
2261
        }
2262

2263
        // In a normal, non-PSBT funding flow, we can jump directly to the next
2264
        // step where we expect our contribution to be finalized.
2265
        f.continueFundingAccept(resCtx, cid)
30✔
2266
}
2267

2268
// waitForPsbt blocks until either a signed PSBT arrives, an error occurs or
2269
// the funding manager shuts down. In the case of a valid PSBT, the funding flow
2270
// is continued.
2271
//
2272
// NOTE: This method must be called as a goroutine.
2273
func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
2274
        resCtx *reservationWithCtx, cid *chanIdentifier) {
×
2275

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

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

2299
                // If the remote canceled the funding reservation, we don't need
2300
                // to send another fail message. But we want to inform the user
2301
                // about what happened.
2302
                case chanfunding.ErrRemoteCanceled:
×
2303
                        log.Infof("Remote canceled, aborting PSBT flow "+
×
2304
                                "for peer_key=%x, pending_chan_id=%x",
×
2305
                                peerKey.SerializeCompressed(), cid.tempChanID)
×
2306
                        return
×
2307

2308
                // Nil error means the flow continues normally now.
2309
                case nil:
×
2310

2311
                // For any other error, we'll fail the funding flow.
2312
                default:
×
2313
                        failFlow("error waiting for PSBT flow", err)
×
2314
                        return
×
2315
                }
2316

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

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

2350
                // We are now ready to continue the funding flow.
2351
                f.continueFundingAccept(resCtx, cid)
×
2352

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

2364
// continueFundingAccept continues the channel funding flow once our
2365
// contribution is finalized, the channel output is known and the funding
2366
// transaction is signed.
2367
func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
2368
        cid *chanIdentifier) {
30✔
2369

30✔
2370
        // Now that we have their contribution, we can extract, then send over
30✔
2371
        // both the funding out point and our signature for their version of
30✔
2372
        // the commitment transaction to the remote peer.
30✔
2373
        outPoint := resCtx.reservation.FundingOutpoint()
30✔
2374
        _, sig := resCtx.reservation.OurSignatures()
30✔
2375

30✔
2376
        // A new channel has almost finished the funding process. In order to
30✔
2377
        // properly synchronize with the writeHandler goroutine, we add a new
30✔
2378
        // channel to the barriers map which will be closed once the channel is
30✔
2379
        // fully open.
30✔
2380
        channelID := lnwire.NewChanIDFromOutPoint(*outPoint)
30✔
2381
        log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
30✔
2382

30✔
2383
        // The next message that advances the funding flow will reference the
30✔
2384
        // channel via its permanent channel ID, so we'll set up this mapping
30✔
2385
        // so we can retrieve the reservation context once we get the
30✔
2386
        // FundingSigned message.
30✔
2387
        f.resMtx.Lock()
30✔
2388
        f.signedReservations[channelID] = cid.tempChanID
30✔
2389
        f.resMtx.Unlock()
30✔
2390

30✔
2391
        log.Infof("Generated ChannelPoint(%v) for pending_id(%x)", outPoint,
30✔
2392
                cid.tempChanID[:])
30✔
2393

30✔
2394
        // Before sending FundingCreated sent, we notify Brontide to keep track
30✔
2395
        // of this pending open channel.
30✔
2396
        err := resCtx.peer.AddPendingChannel(channelID, f.quit)
30✔
2397
        if err != nil {
30✔
2398
                pubKey := resCtx.peer.IdentityKey().SerializeCompressed()
×
2399
                log.Errorf("Unable to add pending channel %v with peer %x: %v",
×
2400
                        channelID, pubKey, err)
×
2401
        }
×
2402

2403
        // Once Brontide is aware of this channel, we need to set it in
2404
        // chanIdentifier so this channel will be removed from Brontide if the
2405
        // funding flow fails.
2406
        cid.setChanID(channelID)
30✔
2407

30✔
2408
        // Send the FundingCreated msg.
30✔
2409
        fundingCreated := &lnwire.FundingCreated{
30✔
2410
                PendingChannelID: cid.tempChanID,
30✔
2411
                FundingPoint:     *outPoint,
30✔
2412
        }
30✔
2413

30✔
2414
        // If this is a taproot channel, then we'll need to populate the musig2
30✔
2415
        // partial sig field instead of the regular commit sig field.
30✔
2416
        if resCtx.reservation.IsTaproot() {
32✔
2417
                partialSig, ok := sig.(*lnwallet.MusigPartialSig)
2✔
2418
                if !ok {
2✔
2419
                        err := fmt.Errorf("expected musig partial sig, got %T",
×
2420
                                sig)
×
2421
                        log.Error(err)
×
2422
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2423

×
2424
                        return
×
2425
                }
×
2426

2427
                fundingCreated.PartialSig = lnwire.MaybePartialSigWithNonce(
2✔
2428
                        partialSig.ToWireSig(),
2✔
2429
                )
2✔
2430
        } else {
28✔
2431
                fundingCreated.CommitSig, err = lnwire.NewSigFromSignature(sig)
28✔
2432
                if err != nil {
28✔
2433
                        log.Errorf("Unable to parse signature: %v", err)
×
2434
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2435
                        return
×
2436
                }
×
2437
        }
2438

2439
        resCtx.reservation.SetState(lnwallet.SentFundingCreated)
30✔
2440

30✔
2441
        if err := resCtx.peer.SendMessage(true, fundingCreated); err != nil {
30✔
2442
                log.Errorf("Unable to send funding complete message: %v", err)
×
2443
                f.failFundingFlow(resCtx.peer, cid, err)
×
2444
                return
×
2445
        }
×
2446
}
2447

2448
// fundeeProcessFundingCreated progresses the funding workflow when the daemon
2449
// is on the responding side of a single funder workflow. Once this message has
2450
// been processed, a signature is sent to the remote peer allowing it to
2451
// broadcast the funding transaction, progressing the workflow into the final
2452
// stage.
2453
//
2454
//nolint:funlen
2455
func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
2456
        msg *lnwire.FundingCreated) {
28✔
2457

28✔
2458
        peerKey := peer.IdentityKey()
28✔
2459
        pendingChanID := msg.PendingChannelID
28✔
2460

28✔
2461
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
28✔
2462
        if err != nil {
28✔
2463
                log.Warnf("can't find reservation (peer_id:%v, chan_id:%x)",
×
2464
                        peerKey, pendingChanID[:])
×
2465
                return
×
2466
        }
×
2467

2468
        // The channel initiator has responded with the funding outpoint of the
2469
        // final funding transaction, as well as a signature for our version of
2470
        // the commitment transaction. So at this point, we can validate the
2471
        // initiator's commitment transaction, then send our own if it's valid.
2472
        fundingOut := msg.FundingPoint
28✔
2473
        log.Infof("completing pending_id(%x) with ChannelPoint(%v)",
28✔
2474
                pendingChanID[:], fundingOut)
28✔
2475

28✔
2476
        if resCtx.reservation.State() != lnwallet.SentAcceptChannel {
28✔
2477
                return
×
2478
        }
×
2479

2480
        // Create the channel identifier without setting the active channel ID.
2481
        cid := newChanIdentifier(pendingChanID)
28✔
2482

28✔
2483
        // For taproot channels, the commit signature is actually the partial
28✔
2484
        // signature. Otherwise, we can convert the ECDSA commit signature into
28✔
2485
        // our internal input.Signature type.
28✔
2486
        var commitSig input.Signature
28✔
2487
        if resCtx.reservation.IsTaproot() {
30✔
2488
                partialSig, err := msg.PartialSig.UnwrapOrErrV(errNoPartialSig)
2✔
2489
                if err != nil {
2✔
2490
                        f.failFundingFlow(peer, cid, err)
×
2491

×
2492
                        return
×
2493
                }
×
2494

2495
                commitSig = new(lnwallet.MusigPartialSig).FromWireSig(
2✔
2496
                        &partialSig,
2✔
2497
                )
2✔
2498
        } else {
26✔
2499
                commitSig, err = msg.CommitSig.ToSignature()
26✔
2500
                if err != nil {
26✔
2501
                        log.Errorf("unable to parse signature: %v", err)
×
2502
                        f.failFundingFlow(peer, cid, err)
×
2503
                        return
×
2504
                }
×
2505
        }
2506

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

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

2544
        // Get forwarding policy before deleting the reservation context.
2545
        forwardingPolicy := resCtx.forwardingPolicy
28✔
2546

28✔
2547
        // The channel is marked IsPending in the database, and can be removed
28✔
2548
        // from the set of active reservations.
28✔
2549
        f.deleteReservationCtx(peerKey, cid.tempChanID)
28✔
2550

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

×
2568
                // Close the channel with us as the initiator because we are
×
2569
                // deciding to exit the funding flow due to an internal error.
×
2570
                if err := completeChan.CloseChannel(
×
2571
                        closeInfo, channeldb.ChanStatusLocalCloseInitiator,
×
2572
                ); err != nil {
×
2573
                        log.Errorf("Failed closing channel %v: %v",
×
2574
                                completeChan.FundingOutpoint, err)
×
2575
                }
×
2576
        }
2577

2578
        // A new channel has almost finished the funding process. In order to
2579
        // properly synchronize with the writeHandler goroutine, we add a new
2580
        // channel to the barriers map which will be closed once the channel is
2581
        // fully open.
2582
        channelID := lnwire.NewChanIDFromOutPoint(fundingOut)
28✔
2583
        log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
28✔
2584

28✔
2585
        fundingSigned := &lnwire.FundingSigned{}
28✔
2586

28✔
2587
        // For taproot channels, we'll need to send over a partial signature
28✔
2588
        // that includes the nonce along side the signature.
28✔
2589
        _, sig := resCtx.reservation.OurSignatures()
28✔
2590
        if resCtx.reservation.IsTaproot() {
30✔
2591
                partialSig, ok := sig.(*lnwallet.MusigPartialSig)
2✔
2592
                if !ok {
2✔
2593
                        err := fmt.Errorf("expected musig partial sig, got %T",
×
2594
                                sig)
×
2595
                        log.Error(err)
×
2596
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2597
                        deleteFromDatabase()
×
2598

×
2599
                        return
×
2600
                }
×
2601

2602
                fundingSigned.PartialSig = lnwire.MaybePartialSigWithNonce(
2✔
2603
                        partialSig.ToWireSig(),
2✔
2604
                )
2✔
2605
        } else {
26✔
2606
                fundingSigned.CommitSig, err = lnwire.NewSigFromSignature(sig)
26✔
2607
                if err != nil {
26✔
2608
                        log.Errorf("unable to parse signature: %v", err)
×
2609
                        f.failFundingFlow(peer, cid, err)
×
2610
                        deleteFromDatabase()
×
2611

×
2612
                        return
×
2613
                }
×
2614
        }
2615

2616
        // Before sending FundingSigned, we notify Brontide first to keep track
2617
        // of this pending open channel.
2618
        if err := peer.AddPendingChannel(channelID, f.quit); err != nil {
28✔
2619
                pubKey := peer.IdentityKey().SerializeCompressed()
×
2620
                log.Errorf("Unable to add pending channel %v with peer %x: %v",
×
2621
                        cid.chanID, pubKey, err)
×
2622
        }
×
2623

2624
        // Once Brontide is aware of this channel, we need to set it in
2625
        // chanIdentifier so this channel will be removed from Brontide if the
2626
        // funding flow fails.
2627
        cid.setChanID(channelID)
28✔
2628

28✔
2629
        fundingSigned.ChanID = cid.chanID
28✔
2630

28✔
2631
        log.Infof("sending FundingSigned for pending_id(%x) over "+
28✔
2632
                "ChannelPoint(%v)", pendingChanID[:], fundingOut)
28✔
2633

28✔
2634
        // With their signature for our version of the commitment transaction
28✔
2635
        // verified, we can now send over our signature to the remote peer.
28✔
2636
        if err := peer.SendMessage(true, fundingSigned); err != nil {
28✔
2637
                log.Errorf("unable to send FundingSigned message: %v", err)
×
2638
                f.failFundingFlow(peer, cid, err)
×
2639
                deleteFromDatabase()
×
2640
                return
×
2641
        }
×
2642

2643
        // With a permanent channel id established we can save the respective
2644
        // forwarding policy in the database. In the channel announcement phase
2645
        // this forwarding policy is retrieved and applied.
2646
        err = f.saveInitialForwardingPolicy(cid.chanID, &forwardingPolicy)
28✔
2647
        if err != nil {
28✔
2648
                log.Errorf("Unable to store the forwarding policy: %v", err)
×
2649
        }
×
2650

2651
        // Now that we've sent over our final signature for this channel, we'll
2652
        // send it to the ChainArbitrator so it can watch for any on-chain
2653
        // actions during this final confirmation stage.
2654
        if err := f.cfg.WatchNewChannel(completeChan, peerKey); err != nil {
28✔
2655
                log.Errorf("Unable to send new ChannelPoint(%v) for "+
×
2656
                        "arbitration: %v", fundingOut, err)
×
2657
        }
×
2658

2659
        // Create an entry in the local discovery map so we can ensure that we
2660
        // process the channel confirmation fully before we receive a
2661
        // channel_ready message.
2662
        f.localDiscoverySignals.Store(cid.chanID, make(chan struct{}))
28✔
2663

28✔
2664
        // Inform the ChannelNotifier that the channel has entered
28✔
2665
        // pending open state.
28✔
2666
        f.cfg.NotifyPendingOpenChannelEvent(
28✔
2667
                fundingOut, completeChan, completeChan.IdentityPub,
28✔
2668
        )
28✔
2669

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

2690
// funderProcessFundingSigned processes the final message received in a single
2691
// funder workflow. Once this message is processed, the funding transaction is
2692
// broadcast. Once the funding transaction reaches a sufficient number of
2693
// confirmations, a message is sent to the responding peer along with a compact
2694
// encoding of the location of the channel within the blockchain.
2695
func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
2696
        msg *lnwire.FundingSigned) {
28✔
2697

28✔
2698
        // As the funding signed message will reference the reservation by its
28✔
2699
        // permanent channel ID, we'll need to perform an intermediate look up
28✔
2700
        // before we can obtain the reservation.
28✔
2701
        f.resMtx.Lock()
28✔
2702
        pendingChanID, ok := f.signedReservations[msg.ChanID]
28✔
2703
        delete(f.signedReservations, msg.ChanID)
28✔
2704
        f.resMtx.Unlock()
28✔
2705

28✔
2706
        // Create the channel identifier and set the channel ID.
28✔
2707
        //
28✔
2708
        // NOTE: we may get an empty pending channel ID here if the key cannot
28✔
2709
        // be found, which means when we cancel the reservation context in
28✔
2710
        // `failFundingFlow`, we will get an error. In this case, we will send
28✔
2711
        // an error msg to our peer using the active channel ID.
28✔
2712
        //
28✔
2713
        // TODO(yy): refactor the funding flow to fix this case.
28✔
2714
        cid := newChanIdentifier(pendingChanID)
28✔
2715
        cid.setChanID(msg.ChanID)
28✔
2716

28✔
2717
        // If the pending channel ID is not found, fail the funding flow.
28✔
2718
        if !ok {
28✔
2719
                // NOTE: we directly overwrite the pending channel ID here for
×
2720
                // this rare case since we don't have a valid pending channel
×
2721
                // ID.
×
2722
                cid.tempChanID = msg.ChanID
×
2723

×
2724
                err := fmt.Errorf("unable to find signed reservation for "+
×
2725
                        "chan_id=%x", msg.ChanID)
×
2726
                log.Warnf(err.Error())
×
2727
                f.failFundingFlow(peer, cid, err)
×
2728
                return
×
2729
        }
×
2730

2731
        peerKey := peer.IdentityKey()
28✔
2732
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
28✔
2733
        if err != nil {
28✔
2734
                log.Warnf("Unable to find reservation (peer_id:%v, "+
×
2735
                        "chan_id:%x)", peerKey, pendingChanID[:])
×
2736
                // TODO: add ErrChanNotFound?
×
2737
                f.failFundingFlow(peer, cid, err)
×
2738
                return
×
2739
        }
×
2740

2741
        if resCtx.reservation.State() != lnwallet.SentFundingCreated {
28✔
2742
                err := fmt.Errorf("unable to find reservation for chan_id=%x",
×
2743
                        msg.ChanID)
×
2744
                f.failFundingFlow(peer, cid, err)
×
2745

×
2746
                return
×
2747
        }
×
2748

2749
        // Create an entry in the local discovery map so we can ensure that we
2750
        // process the channel confirmation fully before we receive a
2751
        // channel_ready message.
2752
        fundingPoint := resCtx.reservation.FundingOutpoint()
28✔
2753
        permChanID := lnwire.NewChanIDFromOutPoint(*fundingPoint)
28✔
2754
        f.localDiscoverySignals.Store(permChanID, make(chan struct{}))
28✔
2755

28✔
2756
        // We have to store the forwardingPolicy before the reservation context
28✔
2757
        // is deleted. The policy will then be read and applied in
28✔
2758
        // newChanAnnouncement.
28✔
2759
        err = f.saveInitialForwardingPolicy(
28✔
2760
                permChanID, &resCtx.forwardingPolicy,
28✔
2761
        )
28✔
2762
        if err != nil {
28✔
2763
                log.Errorf("Unable to store the forwarding policy: %v", err)
×
2764
        }
×
2765

2766
        // For taproot channels, the commit signature is actually the partial
2767
        // signature. Otherwise, we can convert the ECDSA commit signature into
2768
        // our internal input.Signature type.
2769
        var commitSig input.Signature
28✔
2770
        if resCtx.reservation.IsTaproot() {
30✔
2771
                partialSig, err := msg.PartialSig.UnwrapOrErrV(errNoPartialSig)
2✔
2772
                if err != nil {
2✔
2773
                        f.failFundingFlow(peer, cid, err)
×
2774

×
2775
                        return
×
2776
                }
×
2777

2778
                commitSig = new(lnwallet.MusigPartialSig).FromWireSig(
2✔
2779
                        &partialSig,
2✔
2780
                )
2✔
2781
        } else {
26✔
2782
                commitSig, err = msg.CommitSig.ToSignature()
26✔
2783
                if err != nil {
26✔
2784
                        log.Errorf("unable to parse signature: %v", err)
×
2785
                        f.failFundingFlow(peer, cid, err)
×
2786
                        return
×
2787
                }
×
2788
        }
2789

2790
        completeChan, err := resCtx.reservation.CompleteReservation(
28✔
2791
                nil, commitSig,
28✔
2792
        )
28✔
2793
        if err != nil {
28✔
2794
                log.Errorf("Unable to complete reservation sign "+
×
2795
                        "complete: %v", err)
×
2796
                f.failFundingFlow(peer, cid, err)
×
2797
                return
×
2798
        }
×
2799

2800
        // The channel is now marked IsPending in the database, and we can
2801
        // delete it from our set of active reservations.
2802
        f.deleteReservationCtx(peerKey, pendingChanID)
28✔
2803

28✔
2804
        // Broadcast the finalized funding transaction to the network, but only
28✔
2805
        // if we actually have the funding transaction.
28✔
2806
        if completeChan.ChanType.HasFundingTx() {
55✔
2807
                fundingTx := completeChan.FundingTxn
27✔
2808
                var fundingTxBuf bytes.Buffer
27✔
2809
                if err := fundingTx.Serialize(&fundingTxBuf); err != nil {
27✔
2810
                        log.Errorf("Unable to serialize funding "+
×
2811
                                "transaction %v: %v", fundingTx.TxHash(), err)
×
2812

×
2813
                        // Clear the buffer of any bytes that were written
×
2814
                        // before the serialization error to prevent logging an
×
2815
                        // incomplete transaction.
×
2816
                        fundingTxBuf.Reset()
×
2817
                }
×
2818

2819
                log.Infof("Broadcasting funding tx for ChannelPoint(%v): %x",
27✔
2820
                        completeChan.FundingOutpoint, fundingTxBuf.Bytes())
27✔
2821

27✔
2822
                // Set a nil short channel ID at this stage because we do not
27✔
2823
                // know it until our funding tx confirms.
27✔
2824
                label := labels.MakeLabel(
27✔
2825
                        labels.LabelTypeChannelOpen, nil,
27✔
2826
                )
27✔
2827

27✔
2828
                err = f.cfg.PublishTransaction(fundingTx, label)
27✔
2829
                if err != nil {
27✔
2830
                        log.Errorf("Unable to broadcast funding tx %x for "+
×
2831
                                "ChannelPoint(%v): %v", fundingTxBuf.Bytes(),
×
2832
                                completeChan.FundingOutpoint, err)
×
2833

×
2834
                        // We failed to broadcast the funding transaction, but
×
2835
                        // watch the channel regardless, in case the
×
2836
                        // transaction made it to the network. We will retry
×
2837
                        // broadcast at startup.
×
2838
                        //
×
2839
                        // TODO(halseth): retry more often? Handle with CPFP?
×
2840
                        // Just delete from the DB?
×
2841
                }
×
2842
        }
2843

2844
        // Before we proceed, if we have a funding hook that wants a
2845
        // notification that it's safe to broadcast the funding transaction,
2846
        // then we'll send that now.
2847
        err = fn.MapOptionZ(
28✔
2848
                f.cfg.AuxFundingController,
28✔
2849
                func(controller AuxFundingController) error {
28✔
2850
                        return controller.ChannelFinalized(cid.tempChanID)
×
2851
                },
×
2852
        )
2853
        if err != nil {
28✔
2854
                log.Errorf("Failed to inform aux funding controller about "+
×
2855
                        "ChannelPoint(%v) being finalized: %v", fundingPoint,
×
2856
                        err)
×
2857
        }
×
2858

2859
        // Now that we have a finalized reservation for this funding flow,
2860
        // we'll send the to be active channel to the ChainArbitrator so it can
2861
        // watch for any on-chain actions before the channel has fully
2862
        // confirmed.
2863
        if err := f.cfg.WatchNewChannel(completeChan, peerKey); err != nil {
28✔
2864
                log.Errorf("Unable to send new ChannelPoint(%v) for "+
×
2865
                        "arbitration: %v", fundingPoint, err)
×
2866
        }
×
2867

2868
        log.Infof("Finalizing pending_id(%x) over ChannelPoint(%v), "+
28✔
2869
                "waiting for channel open on-chain", pendingChanID[:],
28✔
2870
                fundingPoint)
28✔
2871

28✔
2872
        // Send an update to the upstream client that the negotiation process
28✔
2873
        // is over.
28✔
2874
        upd := &lnrpc.OpenStatusUpdate{
28✔
2875
                Update: &lnrpc.OpenStatusUpdate_ChanPending{
28✔
2876
                        ChanPending: &lnrpc.PendingUpdate{
28✔
2877
                                Txid:        fundingPoint.Hash[:],
28✔
2878
                                OutputIndex: fundingPoint.Index,
28✔
2879
                        },
28✔
2880
                },
28✔
2881
                PendingChanId: pendingChanID[:],
28✔
2882
        }
28✔
2883

28✔
2884
        select {
28✔
2885
        case resCtx.updates <- upd:
28✔
2886
                // Inform the ChannelNotifier that the channel has entered
28✔
2887
                // pending open state.
28✔
2888
                f.cfg.NotifyPendingOpenChannelEvent(
28✔
2889
                        *fundingPoint, completeChan, completeChan.IdentityPub,
28✔
2890
                )
28✔
2891

2892
        case <-f.quit:
×
2893
                return
×
2894
        }
2895

2896
        // At this point we have broadcast the funding transaction and done all
2897
        // necessary processing.
2898
        f.wg.Add(1)
28✔
2899
        go f.advanceFundingState(completeChan, pendingChanID, resCtx.updates)
28✔
2900
}
2901

2902
// confirmedChannel wraps a confirmed funding transaction, as well as the short
2903
// channel ID which identifies that channel into a single struct. We'll use
2904
// this to pass around the final state of a channel after it has been
2905
// confirmed.
2906
type confirmedChannel struct {
2907
        // shortChanID expresses where in the block the funding transaction was
2908
        // located.
2909
        shortChanID lnwire.ShortChannelID
2910

2911
        // fundingTx is the funding transaction that created the channel.
2912
        fundingTx *wire.MsgTx
2913
}
2914

2915
// fundingTimeout is called when callers of waitForFundingWithTimeout receive
2916
// an ErrConfirmationTimeout. It is used to clean-up channel state and mark the
2917
// channel as closed. The error is only returned for the responder of the
2918
// channel flow.
2919
func (f *Manager) fundingTimeout(c *channeldb.OpenChannel,
2920
        pendingID PendingChanID) error {
2✔
2921

2✔
2922
        // We'll get a timeout if the number of blocks mined since the channel
2✔
2923
        // was initiated reaches MaxWaitNumBlocksFundingConf and we are not the
2✔
2924
        // channel initiator.
2✔
2925
        localBalance := c.LocalCommitment.LocalBalance.ToSatoshis()
2✔
2926
        closeInfo := &channeldb.ChannelCloseSummary{
2✔
2927
                ChainHash:               c.ChainHash,
2✔
2928
                ChanPoint:               c.FundingOutpoint,
2✔
2929
                RemotePub:               c.IdentityPub,
2✔
2930
                Capacity:                c.Capacity,
2✔
2931
                SettledBalance:          localBalance,
2✔
2932
                CloseType:               channeldb.FundingCanceled,
2✔
2933
                RemoteCurrentRevocation: c.RemoteCurrentRevocation,
2✔
2934
                RemoteNextRevocation:    c.RemoteNextRevocation,
2✔
2935
                LocalChanConfig:         c.LocalChanCfg,
2✔
2936
        }
2✔
2937

2✔
2938
        // Close the channel with us as the initiator because we are timing the
2✔
2939
        // channel out.
2✔
2940
        if err := c.CloseChannel(
2✔
2941
                closeInfo, channeldb.ChanStatusLocalCloseInitiator,
2✔
2942
        ); err != nil {
2✔
2943
                return fmt.Errorf("failed closing channel %v: %w",
×
2944
                        c.FundingOutpoint, err)
×
2945
        }
×
2946

2947
        // Notify other subsystems about the funding timeout.
2948
        f.cfg.NotifyFundingTimeout(c.FundingOutpoint, c.IdentityPub)
2✔
2949

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

2✔
2953
        // When the peer comes online, we'll notify it that we are now
2✔
2954
        // considering the channel flow canceled.
2✔
2955
        f.wg.Add(1)
2✔
2956
        go func() {
4✔
2957
                defer f.wg.Done()
2✔
2958

2✔
2959
                peer, err := f.waitForPeerOnline(c.IdentityPub)
2✔
2960
                switch err {
2✔
2961
                // We're already shutting down, so we can just return.
2962
                case ErrFundingManagerShuttingDown:
×
2963
                        return
×
2964

2965
                // nil error means we continue on.
2966
                case nil:
2✔
2967

2968
                // For unexpected errors, we print the error and still try to
2969
                // fail the funding flow.
2970
                default:
×
2971
                        log.Errorf("Unexpected error while waiting for peer "+
×
2972
                                "to come online: %v", err)
×
2973
                }
2974

2975
                // Create channel identifier and set the channel ID.
2976
                cid := newChanIdentifier(pendingID)
2✔
2977
                cid.setChanID(lnwire.NewChanIDFromOutPoint(c.FundingOutpoint))
2✔
2978

2✔
2979
                // TODO(halseth): should this send be made
2✔
2980
                // reliable?
2✔
2981

2✔
2982
                // The reservation won't exist at this point, but we'll send an
2✔
2983
                // Error message over anyways with ChanID set to pendingID.
2✔
2984
                f.failFundingFlow(peer, cid, timeoutErr)
2✔
2985
        }()
2986

2987
        return timeoutErr
2✔
2988
}
2989

2990
// waitForFundingWithTimeout is a wrapper around waitForFundingConfirmation and
2991
// waitForTimeout that will return ErrConfirmationTimeout if we are not the
2992
// channel initiator and the MaxWaitNumBlocksFundingConf has passed from the
2993
// funding broadcast height. In case of confirmation, the short channel ID of
2994
// the channel and the funding transaction will be returned.
2995
func (f *Manager) waitForFundingWithTimeout(
2996
        ch *channeldb.OpenChannel) (*confirmedChannel, error) {
59✔
2997

59✔
2998
        confChan := make(chan *confirmedChannel)
59✔
2999
        timeoutChan := make(chan error, 1)
59✔
3000
        cancelChan := make(chan struct{})
59✔
3001

59✔
3002
        f.wg.Add(1)
59✔
3003
        go f.waitForFundingConfirmation(ch, cancelChan, confChan)
59✔
3004

59✔
3005
        // If we are not the initiator, we have no money at stake and will
59✔
3006
        // timeout waiting for the funding transaction to confirm after a
59✔
3007
        // while.
59✔
3008
        if !ch.IsInitiator && !ch.IsZeroConf() {
85✔
3009
                f.wg.Add(1)
26✔
3010
                go f.waitForTimeout(ch, cancelChan, timeoutChan)
26✔
3011
        }
26✔
3012
        defer close(cancelChan)
59✔
3013

59✔
3014
        select {
59✔
3015
        case err := <-timeoutChan:
2✔
3016
                if err != nil {
2✔
3017
                        return nil, err
×
3018
                }
×
3019
                return nil, ErrConfirmationTimeout
2✔
3020

3021
        case <-f.quit:
23✔
3022
                // The fundingManager is shutting down, and will resume wait on
23✔
3023
                // startup.
23✔
3024
                return nil, ErrFundingManagerShuttingDown
23✔
3025

3026
        case confirmedChannel, ok := <-confChan:
34✔
3027
                if !ok {
34✔
3028
                        return nil, fmt.Errorf("waiting for funding" +
×
3029
                                "confirmation failed")
×
3030
                }
×
3031
                return confirmedChannel, nil
34✔
3032
        }
3033
}
3034

3035
// makeFundingScript re-creates the funding script for the funding transaction
3036
// of the target channel.
3037
func makeFundingScript(channel *channeldb.OpenChannel) ([]byte, error) {
79✔
3038
        localKey := channel.LocalChanCfg.MultiSigKey.PubKey
79✔
3039
        remoteKey := channel.RemoteChanCfg.MultiSigKey.PubKey
79✔
3040

79✔
3041
        if channel.ChanType.IsTaproot() {
84✔
3042
                pkScript, _, err := input.GenTaprootFundingScript(
5✔
3043
                        localKey, remoteKey, int64(channel.Capacity),
5✔
3044
                        channel.TapscriptRoot,
5✔
3045
                )
5✔
3046
                if err != nil {
5✔
3047
                        return nil, err
×
3048
                }
×
3049

3050
                return pkScript, nil
5✔
3051
        }
3052

3053
        multiSigScript, err := input.GenMultiSigScript(
74✔
3054
                localKey.SerializeCompressed(),
74✔
3055
                remoteKey.SerializeCompressed(),
74✔
3056
        )
74✔
3057
        if err != nil {
74✔
3058
                return nil, err
×
3059
        }
×
3060

3061
        return input.WitnessScriptHash(multiSigScript)
74✔
3062
}
3063

3064
// waitForFundingConfirmation handles the final stages of the channel funding
3065
// process once the funding transaction has been broadcast. The primary
3066
// function of waitForFundingConfirmation is to wait for blockchain
3067
// confirmation, and then to notify the other systems that must be notified
3068
// when a channel has become active for lightning transactions. It also updates
3069
// the channel’s opening transaction block height in the database.
3070
// The wait can be canceled by closing the cancelChan. In case of success,
3071
// a *lnwire.ShortChannelID will be passed to confChan.
3072
//
3073
// NOTE: This MUST be run as a goroutine.
3074
func (f *Manager) waitForFundingConfirmation(
3075
        completeChan *channeldb.OpenChannel, cancelChan <-chan struct{},
3076
        confChan chan<- *confirmedChannel) {
59✔
3077

59✔
3078
        defer f.wg.Done()
59✔
3079
        defer close(confChan)
59✔
3080

59✔
3081
        // Register with the ChainNotifier for a notification once the funding
59✔
3082
        // transaction reaches `numConfs` confirmations.
59✔
3083
        txid := completeChan.FundingOutpoint.Hash
59✔
3084
        fundingScript, err := makeFundingScript(completeChan)
59✔
3085
        if err != nil {
59✔
3086
                log.Errorf("unable to create funding script for "+
×
3087
                        "ChannelPoint(%v): %v", completeChan.FundingOutpoint,
×
3088
                        err)
×
3089
                return
×
3090
        }
×
3091
        numConfs := uint32(completeChan.NumConfsRequired)
59✔
3092

59✔
3093
        // If the underlying channel is a zero-conf channel, we'll set numConfs
59✔
3094
        // to 6, since it will be zero here.
59✔
3095
        if completeChan.IsZeroConf() {
65✔
3096
                numConfs = 6
6✔
3097
        }
6✔
3098

3099
        confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
59✔
3100
                &txid, fundingScript, numConfs,
59✔
3101
                completeChan.BroadcastHeight(),
59✔
3102
        )
59✔
3103
        if err != nil {
59✔
3104
                log.Errorf("Unable to register for confirmation of "+
×
3105
                        "ChannelPoint(%v): %v", completeChan.FundingOutpoint,
×
3106
                        err)
×
3107
                return
×
3108
        }
×
3109

3110
        log.Infof("Waiting for funding tx (%v) to reach %v confirmations",
59✔
3111
                txid, numConfs)
59✔
3112

59✔
3113
        // Wait until the specified number of confirmations has been reached,
59✔
3114
        // we get a cancel signal, or the wallet signals a shutdown.
59✔
3115
        for {
146✔
3116
                select {
87✔
3117
                case updDetails, ok := <-confNtfn.Updates:
26✔
3118
                        if !ok {
26✔
3119
                                log.Warnf("ChainNotifier shutting down, "+
×
3120
                                        "cannot process updates for "+
×
3121
                                        "ChannelPoint(%v)",
×
3122
                                        completeChan.FundingOutpoint)
×
3123

×
3124
                                return
×
3125
                        }
×
3126

3127
                        log.Debugf("funding tx %s received confirmation in "+
26✔
3128
                                "block %d, %d confirmations left", txid,
26✔
3129
                                updDetails.BlockHeight, updDetails.NumConfsLeft)
26✔
3130

26✔
3131
                        // Only update the ConfirmationHeight the first time a
26✔
3132
                        // confirmation is received, since on subsequent
26✔
3133
                        // confirmations the block height will remain the same.
26✔
3134
                        if completeChan.ConfirmationHeight == 0 {
52✔
3135
                                err := completeChan.MarkConfirmationHeight(
26✔
3136
                                        updDetails.BlockHeight,
26✔
3137
                                )
26✔
3138
                                if err != nil {
26✔
3139
                                        log.Errorf("failed to update "+
×
3140
                                                "confirmed state for "+
×
3141
                                                "ChannelPoint(%v): %v",
×
3142
                                                completeChan.FundingOutpoint,
×
3143
                                                err)
×
3144

×
3145
                                        return
×
3146
                                }
×
3147
                        }
3148

3149
                case _, ok := <-confNtfn.NegativeConf:
2✔
3150
                        if !ok {
2✔
3151
                                log.Warnf("ChainNotifier shutting down, "+
×
3152
                                        "cannot track negative confirmations "+
×
3153
                                        "for ChannelPoint(%v)",
×
3154
                                        completeChan.FundingOutpoint)
×
3155

×
3156
                                return
×
3157
                        }
×
3158

3159
                        log.Warnf("funding tx %s was reorged out; channel "+
2✔
3160
                                "point: %s", txid, completeChan.FundingOutpoint)
2✔
3161

2✔
3162
                        // Reset the confirmation height to 0 because the
2✔
3163
                        // funding transaction was reorged out.
2✔
3164
                        err := completeChan.MarkConfirmationHeight(uint32(0))
2✔
3165
                        if err != nil {
2✔
3166
                                log.Errorf("failed to update state for "+
×
3167
                                        "ChannelPoint(%v): %v",
×
3168
                                        completeChan.FundingOutpoint, err)
×
3169

×
3170
                                return
×
3171
                        }
×
3172

3173
                case confDetails, ok := <-confNtfn.Confirmed:
34✔
3174
                        if !ok {
34✔
3175
                                log.Warnf("ChainNotifier shutting down, "+
×
3176
                                        "cannot complete funding flow for "+
×
3177
                                        "ChannelPoint(%v)",
×
3178
                                        completeChan.FundingOutpoint)
×
3179

×
3180
                                return
×
3181
                        }
×
3182

3183
                        log.Debugf("funding tx %s for ChannelPoint(%v) "+
34✔
3184
                                "confirmed in block %d", txid,
34✔
3185
                                completeChan.FundingOutpoint,
34✔
3186
                                confDetails.BlockHeight)
34✔
3187

34✔
3188
                        // In the case of requiring a single confirmation, it
34✔
3189
                        // can happen that the `Confirmed` channel is read
34✔
3190
                        // from first, in which case the confirmation height
34✔
3191
                        // will not be set. If this happens, we take the
34✔
3192
                        // confirmation height from the `Confirmed` channel.
34✔
3193
                        if completeChan.ConfirmationHeight == 0 {
46✔
3194
                                err := completeChan.MarkConfirmationHeight(
12✔
3195
                                        confDetails.BlockHeight,
12✔
3196
                                )
12✔
3197
                                if err != nil {
12✔
3198
                                        log.Errorf("failed to update "+
×
3199
                                                "confirmed state for "+
×
3200
                                                "ChannelPoint(%v): %v",
×
3201
                                                completeChan.FundingOutpoint,
×
3202
                                                err)
×
3203

×
3204
                                        return
×
3205
                                }
×
3206
                        }
3207

3208
                        err := f.handleConfirmation(
34✔
3209
                                confDetails, completeChan, confChan,
34✔
3210
                        )
34✔
3211
                        if err != nil {
34✔
3212
                                log.Errorf("Error handling confirmation for "+
×
3213
                                        "ChannelPoint(%v), txid=%v: %v",
×
3214
                                        completeChan.FundingOutpoint, txid, err)
×
3215
                        }
×
3216

3217
                        return
34✔
3218

3219
                case <-cancelChan:
3✔
3220
                        log.Warnf("canceled waiting for funding confirmation, "+
3✔
3221
                                "stopping funding flow for ChannelPoint(%v)",
3✔
3222
                                completeChan.FundingOutpoint)
3✔
3223

3✔
3224
                        return
3✔
3225

3226
                case <-f.quit:
22✔
3227
                        log.Warnf("fundingManager shutting down, stopping "+
22✔
3228
                                "funding flow for ChannelPoint(%v)",
22✔
3229
                                completeChan.FundingOutpoint)
22✔
3230

22✔
3231
                        return
22✔
3232
                }
3233
        }
3234
}
3235

3236
// handleConfirmation is a helper function that constructs a ShortChannelID
3237
// based on the confirmation details and sends this information, along with the
3238
// funding transaction, to the provided confirmation channel.
3239
func (f *Manager) handleConfirmation(confDetails *chainntnfs.TxConfirmation,
3240
        completeChan *channeldb.OpenChannel,
3241
        confChan chan<- *confirmedChannel) error {
34✔
3242

34✔
3243
        fundingPoint := completeChan.FundingOutpoint
34✔
3244
        log.Infof("ChannelPoint(%v) is now active: ChannelID(%v)",
34✔
3245
                fundingPoint, lnwire.NewChanIDFromOutPoint(fundingPoint))
34✔
3246

34✔
3247
        // With the block height and the transaction index known, we can
34✔
3248
        // construct the compact chanID which is used on the network to unique
34✔
3249
        // identify channels.
34✔
3250
        shortChanID := lnwire.ShortChannelID{
34✔
3251
                BlockHeight: confDetails.BlockHeight,
34✔
3252
                TxIndex:     confDetails.TxIndex,
34✔
3253
                TxPosition:  uint16(fundingPoint.Index),
34✔
3254
        }
34✔
3255

34✔
3256
        select {
34✔
3257
        case confChan <- &confirmedChannel{
3258
                shortChanID: shortChanID,
3259
                fundingTx:   confDetails.Tx,
3260
        }:
34✔
3261
        case <-f.quit:
×
3262
                return fmt.Errorf("manager shutting down")
×
3263
        }
3264

3265
        return nil
34✔
3266
}
3267

3268
// waitForTimeout will close the timeout channel if MaxWaitNumBlocksFundingConf
3269
// has passed from the broadcast height of the given channel. In case of error,
3270
// the error is sent on timeoutChan. The wait can be canceled by closing the
3271
// cancelChan.
3272
//
3273
// NOTE: timeoutChan MUST be buffered.
3274
// NOTE: This MUST be run as a goroutine.
3275
func (f *Manager) waitForTimeout(completeChan *channeldb.OpenChannel,
3276
        cancelChan <-chan struct{}, timeoutChan chan<- error) {
26✔
3277

26✔
3278
        defer f.wg.Done()
26✔
3279

26✔
3280
        epochClient, err := f.cfg.Notifier.RegisterBlockEpochNtfn(nil)
26✔
3281
        if err != nil {
26✔
3282
                timeoutChan <- fmt.Errorf("unable to register for epoch "+
×
3283
                        "notification: %v", err)
×
3284
                return
×
3285
        }
×
3286

3287
        defer epochClient.Cancel()
26✔
3288

26✔
3289
        // The value of waitBlocksForFundingConf is adjusted in a development
26✔
3290
        // environment to enhance test capabilities. Otherwise, it is set to
26✔
3291
        // DefaultMaxWaitNumBlocksFundingConf.
26✔
3292
        waitBlocksForFundingConf := uint32(
26✔
3293
                lncfg.DefaultMaxWaitNumBlocksFundingConf,
26✔
3294
        )
26✔
3295

26✔
3296
        if lncfg.IsDevBuild() {
26✔
3297
                waitBlocksForFundingConf =
×
3298
                        f.cfg.Dev.MaxWaitNumBlocksFundingConf
×
3299
        }
×
3300

3301
        // On block maxHeight we will cancel the funding confirmation wait.
3302
        broadcastHeight := completeChan.BroadcastHeight()
26✔
3303
        maxHeight := broadcastHeight + waitBlocksForFundingConf
26✔
3304
        for {
54✔
3305
                select {
28✔
3306
                case epoch, ok := <-epochClient.Epochs:
4✔
3307
                        if !ok {
4✔
3308
                                timeoutChan <- fmt.Errorf("epoch client " +
×
3309
                                        "shutting down")
×
3310
                                return
×
3311
                        }
×
3312

3313
                        // Close the timeout channel and exit if the block is
3314
                        // above the max height.
3315
                        if uint32(epoch.Height) >= maxHeight {
6✔
3316
                                log.Warnf("Waited for %v blocks without "+
2✔
3317
                                        "seeing funding transaction confirmed,"+
2✔
3318
                                        " cancelling.",
2✔
3319
                                        waitBlocksForFundingConf)
2✔
3320

2✔
3321
                                // Notify the caller of the timeout.
2✔
3322
                                close(timeoutChan)
2✔
3323
                                return
2✔
3324
                        }
2✔
3325

3326
                        // TODO: If we are the channel initiator implement
3327
                        // a method for recovering the funds from the funding
3328
                        // transaction
3329

3330
                case <-cancelChan:
15✔
3331
                        return
15✔
3332

3333
                case <-f.quit:
9✔
3334
                        // The fundingManager is shutting down, will resume
9✔
3335
                        // waiting for the funding transaction on startup.
9✔
3336
                        return
9✔
3337
                }
3338
        }
3339
}
3340

3341
// makeLabelForTx updates the label for the confirmed funding transaction. If
3342
// we opened the channel, and lnd's wallet published our funding tx (which is
3343
// not the case for some channels) then we update our transaction label with
3344
// our short channel ID, which is known now that our funding transaction has
3345
// confirmed. We do not label transactions we did not publish, because our
3346
// wallet has no knowledge of them.
3347
func (f *Manager) makeLabelForTx(c *channeldb.OpenChannel) {
34✔
3348
        if c.IsInitiator && c.ChanType.HasFundingTx() {
50✔
3349
                shortChanID := c.ShortChanID()
16✔
3350

16✔
3351
                // For zero-conf channels, we'll use the actually-confirmed
16✔
3352
                // short channel id.
16✔
3353
                if c.IsZeroConf() {
18✔
3354
                        shortChanID = c.ZeroConfRealScid()
2✔
3355
                }
2✔
3356

3357
                label := labels.MakeLabel(
16✔
3358
                        labels.LabelTypeChannelOpen, &shortChanID,
16✔
3359
                )
16✔
3360

16✔
3361
                err := f.cfg.UpdateLabel(c.FundingOutpoint.Hash, label)
16✔
3362
                if err != nil {
16✔
3363
                        log.Errorf("unable to update label: %v", err)
×
3364
                }
×
3365
        }
3366
}
3367

3368
// handleFundingConfirmation marks a channel as open in the database, and set
3369
// the channelOpeningState markedOpen. In addition it will report the now
3370
// decided short channel ID to the switch, and close the local discovery signal
3371
// for this channel.
3372
func (f *Manager) handleFundingConfirmation(
3373
        completeChan *channeldb.OpenChannel,
3374
        confChannel *confirmedChannel) error {
30✔
3375

30✔
3376
        fundingPoint := completeChan.FundingOutpoint
30✔
3377
        chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
30✔
3378

30✔
3379
        // TODO(roasbeef): ideally persistent state update for chan above
30✔
3380
        // should be abstracted
30✔
3381

30✔
3382
        // Now that that the channel has been fully confirmed, we'll request
30✔
3383
        // that the wallet fully verify this channel to ensure that it can be
30✔
3384
        // used.
30✔
3385
        err := f.cfg.Wallet.ValidateChannel(completeChan, confChannel.fundingTx)
30✔
3386
        if err != nil {
30✔
3387
                // TODO(roasbeef): delete chan state?
×
3388
                return fmt.Errorf("unable to validate channel: %w", err)
×
3389
        }
×
3390

3391
        // Now that the channel has been validated, we'll persist an alias for
3392
        // this channel if the option-scid-alias feature-bit was negotiated.
3393
        if completeChan.NegotiatedAliasFeature() {
32✔
3394
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
2✔
3395
                if err != nil {
2✔
3396
                        return fmt.Errorf("unable to request alias: %w", err)
×
3397
                }
×
3398

3399
                err = f.cfg.AliasManager.AddLocalAlias(
2✔
3400
                        aliasScid, confChannel.shortChanID, true, false,
2✔
3401
                )
2✔
3402
                if err != nil {
2✔
3403
                        return fmt.Errorf("unable to request alias: %w", err)
×
3404
                }
×
3405
        }
3406

3407
        // The funding transaction now being confirmed, we add this channel to
3408
        // the fundingManager's internal persistent state machine that we use
3409
        // to track the remaining process of the channel opening. This is
3410
        // useful to resume the opening process in case of restarts. We set the
3411
        // opening state before we mark the channel opened in the database,
3412
        // such that we can receover from one of the db writes failing.
3413
        err = f.saveChannelOpeningState(
30✔
3414
                &fundingPoint, markedOpen, &confChannel.shortChanID,
30✔
3415
        )
30✔
3416
        if err != nil {
30✔
3417
                return fmt.Errorf("error setting channel state to "+
×
3418
                        "markedOpen: %v", err)
×
3419
        }
×
3420

3421
        // Now that the channel has been fully confirmed and we successfully
3422
        // saved the opening state, we'll mark it as open within the database.
3423
        err = completeChan.MarkAsOpen(confChannel.shortChanID)
30✔
3424
        if err != nil {
30✔
3425
                return fmt.Errorf("error setting channel pending flag to "+
×
3426
                        "false:        %v", err)
×
3427
        }
×
3428

3429
        // Update the confirmed funding transaction label.
3430
        f.makeLabelForTx(completeChan)
30✔
3431

30✔
3432
        // Inform the ChannelNotifier that the channel has transitioned from
30✔
3433
        // pending open to open.
30✔
3434
        f.cfg.NotifyOpenChannelEvent(
30✔
3435
                completeChan.FundingOutpoint, completeChan.IdentityPub,
30✔
3436
        )
30✔
3437

30✔
3438
        // Close the discoverySignal channel, indicating to a separate
30✔
3439
        // goroutine that the channel now is marked as open in the database
30✔
3440
        // and that it is acceptable to process channel_ready messages
30✔
3441
        // from the peer.
30✔
3442
        if discoverySignal, ok := f.localDiscoverySignals.Load(chanID); ok {
60✔
3443
                close(discoverySignal)
30✔
3444
        }
30✔
3445

3446
        return nil
30✔
3447
}
3448

3449
// sendChannelReady creates and sends the channelReady message.
3450
// This should be called after the funding transaction has been confirmed,
3451
// and the channelState is 'markedOpen'.
3452
func (f *Manager) sendChannelReady(completeChan *channeldb.OpenChannel,
3453
        channel *lnwallet.LightningChannel) error {
35✔
3454

35✔
3455
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
35✔
3456

35✔
3457
        var peerKey [33]byte
35✔
3458
        copy(peerKey[:], completeChan.IdentityPub.SerializeCompressed())
35✔
3459

35✔
3460
        // Next, we'll send over the channel_ready message which marks that we
35✔
3461
        // consider the channel open by presenting the remote party with our
35✔
3462
        // next revocation key. Without the revocation key, the remote party
35✔
3463
        // will be unable to propose state transitions.
35✔
3464
        nextRevocation, err := channel.NextRevocationKey()
35✔
3465
        if err != nil {
35✔
3466
                return fmt.Errorf("unable to create next revocation: %w", err)
×
3467
        }
×
3468
        channelReadyMsg := lnwire.NewChannelReady(chanID, nextRevocation)
35✔
3469

35✔
3470
        // If this is a taproot channel, then we also need to send along our
35✔
3471
        // set of musig2 nonces as well.
35✔
3472
        if completeChan.ChanType.IsTaproot() {
39✔
3473
                log.Infof("ChanID(%v): generating musig2 nonces...",
4✔
3474
                        chanID)
4✔
3475

4✔
3476
                f.nonceMtx.Lock()
4✔
3477
                localNonce, ok := f.pendingMusigNonces[chanID]
4✔
3478
                if !ok {
8✔
3479
                        // If we don't have any nonces generated yet for this
4✔
3480
                        // first state, then we'll generate them now and stow
4✔
3481
                        // them away.  When we receive the funding locked
4✔
3482
                        // message, we'll then pass along this same set of
4✔
3483
                        // nonces.
4✔
3484
                        newNonce, err := channel.GenMusigNonces()
4✔
3485
                        if err != nil {
4✔
3486
                                f.nonceMtx.Unlock()
×
3487
                                return err
×
3488
                        }
×
3489

3490
                        // Now that we've generated the nonce for this channel,
3491
                        // we'll store it in the set of pending nonces.
3492
                        localNonce = newNonce
4✔
3493
                        f.pendingMusigNonces[chanID] = localNonce
4✔
3494
                }
3495
                f.nonceMtx.Unlock()
4✔
3496

4✔
3497
                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce(
4✔
3498
                        localNonce.PubNonce,
4✔
3499
                )
4✔
3500
        }
3501

3502
        // If the channel negotiated the option-scid-alias feature bit, we'll
3503
        // send a TLV segment that includes an alias the peer can use in their
3504
        // invoice hop hints. We'll send the first alias we find for the
3505
        // channel since it does not matter which alias we send. We'll error
3506
        // out in the odd case that no aliases are found.
3507
        if completeChan.NegotiatedAliasFeature() {
41✔
3508
                aliases := f.cfg.AliasManager.GetAliases(
6✔
3509
                        completeChan.ShortChanID(),
6✔
3510
                )
6✔
3511
                if len(aliases) == 0 {
6✔
3512
                        return fmt.Errorf("no aliases found")
×
3513
                }
×
3514

3515
                // We can use a pointer to aliases since GetAliases returns a
3516
                // copy of the alias slice.
3517
                channelReadyMsg.AliasScid = &aliases[0]
6✔
3518
        }
3519

3520
        // If the peer has disconnected before we reach this point, we will need
3521
        // to wait for him to come back online before sending the channelReady
3522
        // message. This is special for channelReady, since failing to send any
3523
        // of the previous messages in the funding flow just cancels the flow.
3524
        // But now the funding transaction is confirmed, the channel is open
3525
        // and we have to make sure the peer gets the channelReady message when
3526
        // it comes back online. This is also crucial during restart of lnd,
3527
        // where we might try to resend the channelReady message before the
3528
        // server has had the time to connect to the peer. We keep trying to
3529
        // send channelReady until we succeed, or the fundingManager is shut
3530
        // down.
3531
        for {
70✔
3532
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
35✔
3533
                if err != nil {
36✔
3534
                        return err
1✔
3535
                }
1✔
3536

3537
                localAlias := peer.LocalFeatures().HasFeature(
34✔
3538
                        lnwire.ScidAliasOptional,
34✔
3539
                )
34✔
3540
                remoteAlias := peer.RemoteFeatures().HasFeature(
34✔
3541
                        lnwire.ScidAliasOptional,
34✔
3542
                )
34✔
3543

34✔
3544
                // We could also refresh the channel state instead of checking
34✔
3545
                // whether the feature was negotiated, but this saves us a
34✔
3546
                // database read.
34✔
3547
                if channelReadyMsg.AliasScid == nil && localAlias &&
34✔
3548
                        remoteAlias {
34✔
3549

×
3550
                        // If an alias was not assigned above and the scid
×
3551
                        // alias feature was negotiated, check if we already
×
3552
                        // have an alias stored in case handleChannelReady was
×
3553
                        // called before this. If an alias exists, use that in
×
3554
                        // channel_ready. Otherwise, request and store an
×
3555
                        // alias and use that.
×
3556
                        aliases := f.cfg.AliasManager.GetAliases(
×
3557
                                completeChan.ShortChannelID,
×
3558
                        )
×
3559
                        if len(aliases) == 0 {
×
3560
                                // No aliases were found.
×
3561
                                alias, err := f.cfg.AliasManager.RequestAlias()
×
3562
                                if err != nil {
×
3563
                                        return err
×
3564
                                }
×
3565

3566
                                err = f.cfg.AliasManager.AddLocalAlias(
×
3567
                                        alias, completeChan.ShortChannelID,
×
3568
                                        false, false,
×
3569
                                )
×
3570
                                if err != nil {
×
3571
                                        return err
×
3572
                                }
×
3573

3574
                                channelReadyMsg.AliasScid = &alias
×
3575
                        } else {
×
3576
                                channelReadyMsg.AliasScid = &aliases[0]
×
3577
                        }
×
3578
                }
3579

3580
                log.Infof("Peer(%x) is online, sending ChannelReady "+
34✔
3581
                        "for ChannelID(%v)", peerKey, chanID)
34✔
3582

34✔
3583
                if err := peer.SendMessage(true, channelReadyMsg); err == nil {
68✔
3584
                        // Sending succeeded, we can break out and continue the
34✔
3585
                        // funding flow.
34✔
3586
                        break
34✔
3587
                }
3588

3589
                log.Warnf("Unable to send channelReady to peer %x: %v. "+
×
3590
                        "Will retry when online", peerKey, err)
×
3591
        }
3592

3593
        return nil
34✔
3594
}
3595

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

60✔
3601
        // If the funding manager has exited, return an error to stop looping.
60✔
3602
        // Note that the peer may appear as online while the funding manager
60✔
3603
        // has stopped due to the shutdown order in the server.
60✔
3604
        select {
60✔
3605
        case <-f.quit:
×
3606
                return false, ErrFundingManagerShuttingDown
×
3607
        default:
60✔
3608
        }
3609

3610
        // Avoid a tight loop if peer is offline.
3611
        if _, err := f.waitForPeerOnline(node); err != nil {
60✔
3612
                log.Errorf("Wait for peer online failed: %v", err)
×
3613
                return false, err
×
3614
        }
×
3615

3616
        // If we cannot find the channel, then we haven't processed the
3617
        // remote's channelReady message.
3618
        channel, err := f.cfg.FindChannel(node, chanID)
60✔
3619
        if err != nil {
60✔
3620
                log.Errorf("Unable to locate ChannelID(%v) to determine if "+
×
3621
                        "ChannelReady was received", chanID)
×
3622
                return false, err
×
3623
        }
×
3624

3625
        // If we haven't insert the next revocation point, we haven't finished
3626
        // processing the channel ready message.
3627
        if channel.RemoteNextRevocation == nil {
95✔
3628
                return false, nil
35✔
3629
        }
35✔
3630

3631
        // Finally, the barrier signal is removed once we finish
3632
        // `handleChannelReady`. If we can still find the signal, we haven't
3633
        // finished processing it yet.
3634
        _, loaded := f.handleChannelReadyBarriers.Load(chanID)
25✔
3635

25✔
3636
        return !loaded, nil
25✔
3637
}
3638

3639
// extractAnnounceParams extracts the various channel announcement and update
3640
// parameters that will be needed to construct a ChannelAnnouncement and a
3641
// ChannelUpdate.
3642
func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) (
3643
        lnwire.MilliSatoshi, lnwire.MilliSatoshi) {
26✔
3644

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

26✔
3651
        // We don't necessarily want to go as low as the remote party allows.
26✔
3652
        // Check it against our default forwarding policy.
26✔
3653
        if fwdMinHTLC < f.cfg.DefaultRoutingPolicy.MinHTLCOut {
26✔
3654
                fwdMinHTLC = f.cfg.DefaultRoutingPolicy.MinHTLCOut
×
3655
        }
×
3656

3657
        // We'll obtain the max HTLC value we can forward in our direction, as
3658
        // we'll use this value within our ChannelUpdate. This value must be <=
3659
        // channel capacity and <= the maximum in-flight msats set by the peer.
3660
        fwdMaxHTLC := c.LocalChanCfg.MaxPendingAmount
26✔
3661
        capacityMSat := lnwire.NewMSatFromSatoshis(c.Capacity)
26✔
3662
        if fwdMaxHTLC > capacityMSat {
26✔
3663
                fwdMaxHTLC = capacityMSat
×
3664
        }
×
3665

3666
        return fwdMinHTLC, fwdMaxHTLC
26✔
3667
}
3668

3669
// addToGraph sends a ChannelAnnouncement and a ChannelUpdate to the
3670
// gossiper so that the channel is added to the graph builder's internal graph.
3671
// These announcement messages are NOT broadcasted to the greater network,
3672
// only to the channel counter party. The proofs required to announce the
3673
// channel to the greater network will be created and sent in annAfterSixConfs.
3674
// The peerAlias is used for zero-conf channels to give the counter-party a
3675
// ChannelUpdate they understand. ourPolicy may be set for various
3676
// option-scid-alias channels to re-use the same policy.
3677
func (f *Manager) addToGraph(completeChan *channeldb.OpenChannel,
3678
        shortChanID *lnwire.ShortChannelID,
3679
        peerAlias *lnwire.ShortChannelID,
3680
        ourPolicy *models.ChannelEdgePolicy) error {
26✔
3681

26✔
3682
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
26✔
3683

26✔
3684
        fwdMinHTLC, fwdMaxHTLC := f.extractAnnounceParams(completeChan)
26✔
3685

26✔
3686
        ann, err := f.newChanAnnouncement(
26✔
3687
                f.cfg.IDKey, completeChan.IdentityPub,
26✔
3688
                &completeChan.LocalChanCfg.MultiSigKey,
26✔
3689
                completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
26✔
3690
                chanID, fwdMinHTLC, fwdMaxHTLC, ourPolicy,
26✔
3691
                completeChan.ChanType,
26✔
3692
        )
26✔
3693
        if err != nil {
26✔
3694
                return fmt.Errorf("error generating channel "+
×
3695
                        "announcement: %v", err)
×
3696
        }
×
3697

3698
        // Send ChannelAnnouncement and ChannelUpdate to the gossiper to add
3699
        // to the Router's topology.
3700
        errChan := f.cfg.SendAnnouncement(
26✔
3701
                ann.chanAnn, discovery.ChannelCapacity(completeChan.Capacity),
26✔
3702
                discovery.ChannelPoint(completeChan.FundingOutpoint),
26✔
3703
                discovery.TapscriptRoot(completeChan.TapscriptRoot),
26✔
3704
        )
26✔
3705
        select {
26✔
3706
        case err := <-errChan:
26✔
3707
                if err != nil {
26✔
3708
                        if graph.IsError(err, graph.ErrOutdated,
×
3709
                                graph.ErrIgnored) {
×
3710

×
3711
                                log.Debugf("Graph rejected "+
×
3712
                                        "ChannelAnnouncement: %v", err)
×
3713
                        } else {
×
3714
                                return fmt.Errorf("error sending channel "+
×
3715
                                        "announcement: %v", err)
×
3716
                        }
×
3717
                }
3718
        case <-f.quit:
×
3719
                return ErrFundingManagerShuttingDown
×
3720
        }
3721

3722
        errChan = f.cfg.SendAnnouncement(
26✔
3723
                ann.chanUpdateAnn, discovery.RemoteAlias(peerAlias),
26✔
3724
        )
26✔
3725
        select {
26✔
3726
        case err := <-errChan:
26✔
3727
                if err != nil {
26✔
3728
                        if graph.IsError(err, graph.ErrOutdated,
×
3729
                                graph.ErrIgnored) {
×
3730

×
3731
                                log.Debugf("Graph rejected "+
×
3732
                                        "ChannelUpdate: %v", err)
×
3733
                        } else {
×
3734
                                return fmt.Errorf("error sending channel "+
×
3735
                                        "update: %v", err)
×
3736
                        }
×
3737
                }
3738
        case <-f.quit:
×
3739
                return ErrFundingManagerShuttingDown
×
3740
        }
3741

3742
        return nil
26✔
3743
}
3744

3745
// annAfterSixConfs broadcasts the necessary channel announcement messages to
3746
// the network after 6 confs. Should be called after the channelReady message
3747
// is sent and the channel is added to the graph (channelState is
3748
// 'addedToGraph') and the channel is ready to be used. This is the last
3749
// step in the channel opening process, and the opening state will be deleted
3750
// from the database if successful.
3751
func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
3752
        shortChanID *lnwire.ShortChannelID) error {
26✔
3753

26✔
3754
        // If this channel is not meant to be announced to the greater network,
26✔
3755
        // we'll only send our NodeAnnouncement to our counterparty to ensure we
26✔
3756
        // don't leak any of our information.
26✔
3757
        announceChan := completeChan.ChannelFlags&lnwire.FFAnnounceChannel != 0
26✔
3758
        if !announceChan {
34✔
3759
                log.Debugf("Will not announce private channel %v.",
8✔
3760
                        shortChanID.ToUint64())
8✔
3761

8✔
3762
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
8✔
3763
                if err != nil {
8✔
3764
                        return err
×
3765
                }
×
3766

3767
                nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
8✔
3768
                if err != nil {
8✔
3769
                        return fmt.Errorf("unable to retrieve current node "+
×
3770
                                "announcement: %v", err)
×
3771
                }
×
3772

3773
                chanID := lnwire.NewChanIDFromOutPoint(
8✔
3774
                        completeChan.FundingOutpoint,
8✔
3775
                )
8✔
3776
                pubKey := peer.PubKey()
8✔
3777
                log.Debugf("Sending our NodeAnnouncement for "+
8✔
3778
                        "ChannelID(%v) to %x", chanID, pubKey)
8✔
3779

8✔
3780
                // TODO(halseth): make reliable. If the peer is not online this
8✔
3781
                // will fail, and the opening process will stop. Should instead
8✔
3782
                // block here, waiting for the peer to come online.
8✔
3783
                if err := peer.SendMessage(true, &nodeAnn); err != nil {
8✔
3784
                        return fmt.Errorf("unable to send node announcement "+
×
3785
                                "to peer %x: %v", pubKey, err)
×
3786
                }
×
3787
        } else {
18✔
3788
                // Otherwise, we'll wait until the funding transaction has
18✔
3789
                // reached 6 confirmations before announcing it.
18✔
3790
                numConfs := uint32(completeChan.NumConfsRequired)
18✔
3791
                if numConfs < 6 {
36✔
3792
                        numConfs = 6
18✔
3793
                }
18✔
3794
                txid := completeChan.FundingOutpoint.Hash
18✔
3795
                log.Debugf("Will announce channel %v after ChannelPoint"+
18✔
3796
                        "(%v) has gotten %d confirmations",
18✔
3797
                        shortChanID.ToUint64(), completeChan.FundingOutpoint,
18✔
3798
                        numConfs)
18✔
3799

18✔
3800
                fundingScript, err := makeFundingScript(completeChan)
18✔
3801
                if err != nil {
18✔
3802
                        return fmt.Errorf("unable to create funding script "+
×
3803
                                "for ChannelPoint(%v): %v",
×
3804
                                completeChan.FundingOutpoint, err)
×
3805
                }
×
3806

3807
                // Register with the ChainNotifier for a notification once the
3808
                // funding transaction reaches at least 6 confirmations.
3809
                confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
18✔
3810
                        &txid, fundingScript, numConfs,
18✔
3811
                        completeChan.BroadcastHeight(),
18✔
3812
                )
18✔
3813
                if err != nil {
18✔
3814
                        return fmt.Errorf("unable to register for "+
×
3815
                                "confirmation of ChannelPoint(%v): %v",
×
3816
                                completeChan.FundingOutpoint, err)
×
3817
                }
×
3818

3819
                // Wait until 6 confirmations has been reached or the wallet
3820
                // signals a shutdown.
3821
                select {
18✔
3822
                case _, ok := <-confNtfn.Confirmed:
16✔
3823
                        if !ok {
16✔
3824
                                return fmt.Errorf("ChainNotifier shutting "+
×
3825
                                        "down, cannot complete funding flow "+
×
3826
                                        "for ChannelPoint(%v)",
×
3827
                                        completeChan.FundingOutpoint)
×
3828
                        }
×
3829
                        // Fallthrough.
3830

3831
                case <-f.quit:
2✔
3832
                        return fmt.Errorf("%v, stopping funding flow for "+
2✔
3833
                                "ChannelPoint(%v)",
2✔
3834
                                ErrFundingManagerShuttingDown,
2✔
3835
                                completeChan.FundingOutpoint)
2✔
3836
                }
3837

3838
                fundingPoint := completeChan.FundingOutpoint
16✔
3839
                chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
16✔
3840

16✔
3841
                log.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
16✔
3842
                        &fundingPoint, shortChanID)
16✔
3843

16✔
3844
                // If this is a non-zero-conf option-scid-alias channel, we'll
16✔
3845
                // delete the mappings the gossiper uses so that ChannelUpdates
16✔
3846
                // with aliases won't be accepted. This is done elsewhere for
16✔
3847
                // zero-conf channels.
16✔
3848
                isScidFeature := completeChan.NegotiatedAliasFeature()
16✔
3849
                isZeroConf := completeChan.IsZeroConf()
16✔
3850
                if isScidFeature && !isZeroConf {
16✔
3851
                        baseScid := completeChan.ShortChanID()
×
3852
                        err := f.cfg.AliasManager.DeleteSixConfs(baseScid)
×
3853
                        if err != nil {
×
3854
                                return fmt.Errorf("failed deleting six confs "+
×
3855
                                        "maps: %v", err)
×
3856
                        }
×
3857

3858
                        // We'll delete the edge and add it again via
3859
                        // addToGraph. This is because the peer may have
3860
                        // sent us a ChannelUpdate with an alias and we don't
3861
                        // want to relay this.
3862
                        ourPolicy, err := f.cfg.DeleteAliasEdge(baseScid)
×
3863
                        if err != nil {
×
3864
                                return fmt.Errorf("failed deleting real edge "+
×
3865
                                        "for alias channel from graph: %v",
×
3866
                                        err)
×
3867
                        }
×
3868

3869
                        err = f.addToGraph(
×
3870
                                completeChan, &baseScid, nil, ourPolicy,
×
3871
                        )
×
3872
                        if err != nil {
×
3873
                                return fmt.Errorf("failed to re-add to "+
×
3874
                                        "graph: %v", err)
×
3875
                        }
×
3876
                }
3877

3878
                // Create and broadcast the proofs required to make this channel
3879
                // public and usable for other nodes for routing.
3880
                err = f.announceChannel(
16✔
3881
                        f.cfg.IDKey, completeChan.IdentityPub,
16✔
3882
                        &completeChan.LocalChanCfg.MultiSigKey,
16✔
3883
                        completeChan.RemoteChanCfg.MultiSigKey.PubKey,
16✔
3884
                        *shortChanID, chanID, completeChan.ChanType,
16✔
3885
                )
16✔
3886
                if err != nil {
16✔
3887
                        return fmt.Errorf("channel announcement failed: %w",
×
3888
                                err)
×
3889
                }
×
3890

3891
                log.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
16✔
3892
                        "sent to gossiper", &fundingPoint, shortChanID)
16✔
3893
        }
3894

3895
        return nil
24✔
3896
}
3897

3898
// waitForZeroConfChannel is called when the state is addedToGraph with
3899
// a zero-conf channel. This will wait for the real confirmation, add the
3900
// confirmed SCID to the router graph, and then announce after six confs.
3901
func (f *Manager) waitForZeroConfChannel(c *channeldb.OpenChannel) error {
6✔
3902
        // First we'll check whether the channel is confirmed on-chain. If it
6✔
3903
        // is already confirmed, the chainntnfs subsystem will return with the
6✔
3904
        // confirmed tx. Otherwise, we'll wait here until confirmation occurs.
6✔
3905
        confChan, err := f.waitForFundingWithTimeout(c)
6✔
3906
        if err != nil {
8✔
3907
                return fmt.Errorf("error waiting for zero-conf funding "+
2✔
3908
                        "confirmation for ChannelPoint(%v): %v",
2✔
3909
                        c.FundingOutpoint, err)
2✔
3910
        }
2✔
3911

3912
        // We'll need to refresh the channel state so that things are properly
3913
        // populated when validating the channel state. Otherwise, a panic may
3914
        // occur due to inconsistency in the OpenChannel struct.
3915
        err = c.Refresh()
4✔
3916
        if err != nil {
4✔
3917
                return fmt.Errorf("unable to refresh channel state: %w", err)
×
3918
        }
×
3919

3920
        // Now that we have the confirmed transaction and the proper SCID,
3921
        // we'll call ValidateChannel to ensure the confirmed tx is properly
3922
        // formatted.
3923
        err = f.cfg.Wallet.ValidateChannel(c, confChan.fundingTx)
4✔
3924
        if err != nil {
4✔
3925
                return fmt.Errorf("unable to validate zero-conf channel: "+
×
3926
                        "%v", err)
×
3927
        }
×
3928

3929
        // Once we know the confirmed ShortChannelID, we'll need to save it to
3930
        // the database and refresh the OpenChannel struct with it.
3931
        err = c.MarkRealScid(confChan.shortChanID)
4✔
3932
        if err != nil {
4✔
3933
                return fmt.Errorf("unable to set confirmed SCID for zero "+
×
3934
                        "channel: %v", err)
×
3935
        }
×
3936

3937
        // Six confirmations have been reached. If this channel is public,
3938
        // we'll delete some of the alias mappings the gossiper uses.
3939
        isPublic := c.ChannelFlags&lnwire.FFAnnounceChannel != 0
4✔
3940
        if isPublic {
6✔
3941
                err = f.cfg.AliasManager.DeleteSixConfs(c.ShortChannelID)
2✔
3942
                if err != nil {
2✔
3943
                        return fmt.Errorf("unable to delete base alias after "+
×
3944
                                "six confirmations: %v", err)
×
3945
                }
×
3946

3947
                // TODO: Make this atomic!
3948
                ourPolicy, err := f.cfg.DeleteAliasEdge(c.ShortChanID())
2✔
3949
                if err != nil {
2✔
3950
                        return fmt.Errorf("unable to delete alias edge from "+
×
3951
                                "graph: %v", err)
×
3952
                }
×
3953

3954
                // We'll need to update the graph with the new ShortChannelID
3955
                // via an addToGraph call. We don't pass in the peer's
3956
                // alias since we'll be using the confirmed SCID from now on
3957
                // regardless if it's public or not.
3958
                err = f.addToGraph(
2✔
3959
                        c, &confChan.shortChanID, nil, ourPolicy,
2✔
3960
                )
2✔
3961
                if err != nil {
2✔
3962
                        return fmt.Errorf("failed adding confirmed zero-conf "+
×
3963
                                "SCID to graph: %v", err)
×
3964
                }
×
3965
        }
3966

3967
        // Since we have now marked down the confirmed SCID, we'll also need to
3968
        // tell the Switch to refresh the relevant ChannelLink so that forwards
3969
        // under the confirmed SCID are possible if this is a public channel.
3970
        err = f.cfg.ReportShortChanID(c.FundingOutpoint)
4✔
3971
        if err != nil {
4✔
3972
                // This should only fail if the link is not found in the
×
3973
                // Switch's linkIndex map. If this is the case, then the peer
×
3974
                // has gone offline and the next time the link is loaded, it
×
3975
                // will have a refreshed state. Just log an error here.
×
3976
                log.Errorf("unable to report scid for zero-conf channel "+
×
3977
                        "channel: %v", err)
×
3978
        }
×
3979

3980
        // Update the confirmed transaction's label.
3981
        f.makeLabelForTx(c)
4✔
3982

4✔
3983
        return nil
4✔
3984
}
3985

3986
// genFirstStateMusigNonce generates a nonces for the "first" local state. This
3987
// is the verification nonce for the state created for us after the initial
3988
// commitment transaction signed as part of the funding flow.
3989
func genFirstStateMusigNonce(channel *channeldb.OpenChannel,
3990
) (*musig2.Nonces, error) {
4✔
3991

4✔
3992
        musig2ShaChain, err := channeldb.DeriveMusig2Shachain(
4✔
3993
                channel.RevocationProducer,
4✔
3994
        )
4✔
3995
        if err != nil {
4✔
3996
                return nil, fmt.Errorf("unable to generate musig channel "+
×
3997
                        "nonces: %v", err)
×
3998
        }
×
3999

4000
        // We use the _next_ commitment height here as we need to generate the
4001
        // nonce for the next state the remote party will sign for us.
4002
        verNonce, err := channeldb.NewMusigVerificationNonce(
4✔
4003
                channel.LocalChanCfg.MultiSigKey.PubKey,
4✔
4004
                channel.LocalCommitment.CommitHeight+1,
4✔
4005
                musig2ShaChain,
4✔
4006
        )
4✔
4007
        if err != nil {
4✔
4008
                return nil, fmt.Errorf("unable to generate musig channel "+
×
4009
                        "nonces: %v", err)
×
4010
        }
×
4011

4012
        return verNonce, nil
4✔
4013
}
4014

4015
// handleChannelReady finalizes the channel funding process and enables the
4016
// channel to enter normal operating mode.
4017
func (f *Manager) handleChannelReady(peer lnpeer.Peer, //nolint:funlen
4018
        msg *lnwire.ChannelReady) {
28✔
4019

28✔
4020
        defer f.wg.Done()
28✔
4021

28✔
4022
        // If we are in development mode, we'll wait for specified duration
28✔
4023
        // before processing the channel ready message.
28✔
4024
        if f.cfg.Dev != nil {
28✔
4025
                duration := f.cfg.Dev.ProcessChannelReadyWait
×
4026
                log.Warnf("Channel(%v): sleeping %v before processing "+
×
4027
                        "channel_ready", msg.ChanID, duration)
×
4028

×
4029
                select {
×
4030
                case <-time.After(duration):
×
4031
                        log.Warnf("Channel(%v): slept %v before processing "+
×
4032
                                "channel_ready", msg.ChanID, duration)
×
4033
                case <-f.quit:
×
4034
                        log.Warnf("Channel(%v): quit sleeping", msg.ChanID)
×
4035
                        return
×
4036
                }
4037
        }
4038

4039
        log.Debugf("Received ChannelReady for ChannelID(%v) from "+
28✔
4040
                "peer %x", msg.ChanID,
28✔
4041
                peer.IdentityKey().SerializeCompressed())
28✔
4042

28✔
4043
        // We now load or create a new channel barrier for this channel.
28✔
4044
        _, loaded := f.handleChannelReadyBarriers.LoadOrStore(
28✔
4045
                msg.ChanID, struct{}{},
28✔
4046
        )
28✔
4047

28✔
4048
        // If we are currently in the process of handling a channel_ready
28✔
4049
        // message for this channel, ignore.
28✔
4050
        if loaded {
29✔
4051
                log.Infof("Already handling channelReady for "+
1✔
4052
                        "ChannelID(%v), ignoring.", msg.ChanID)
1✔
4053
                return
1✔
4054
        }
1✔
4055

4056
        // If not already handling channelReady for this channel, then the
4057
        // `LoadOrStore` has set up a barrier, and it will be removed once this
4058
        // function exits.
4059
        defer f.handleChannelReadyBarriers.Delete(msg.ChanID)
27✔
4060

27✔
4061
        localDiscoverySignal, ok := f.localDiscoverySignals.Load(msg.ChanID)
27✔
4062
        if ok {
52✔
4063
                // Before we proceed with processing the channel_ready
25✔
4064
                // message, we'll wait for the local waitForFundingConfirmation
25✔
4065
                // goroutine to signal that it has the necessary state in
25✔
4066
                // place. Otherwise, we may be missing critical information
25✔
4067
                // required to handle forwarded HTLC's.
25✔
4068
                select {
25✔
4069
                case <-localDiscoverySignal:
25✔
4070
                        // Fallthrough
4071
                case <-f.quit:
×
4072
                        return
×
4073
                }
4074

4075
                // With the signal received, we can now safely delete the entry
4076
                // from the map.
4077
                f.localDiscoverySignals.Delete(msg.ChanID)
25✔
4078
        }
4079

4080
        // First, we'll attempt to locate the channel whose funding workflow is
4081
        // being finalized by this message. We go to the database rather than
4082
        // our reservation map as we may have restarted, mid funding flow. Also
4083
        // provide the node's public key to make the search faster.
4084
        chanID := msg.ChanID
27✔
4085
        channel, err := f.cfg.FindChannel(peer.IdentityKey(), chanID)
27✔
4086
        if err != nil {
27✔
4087
                log.Errorf("Unable to locate ChannelID(%v), cannot complete "+
×
4088
                        "funding", chanID)
×
4089
                return
×
4090
        }
×
4091

4092
        // If this is a taproot channel, then we can generate the set of nonces
4093
        // the remote party needs to send the next remote commitment here.
4094
        var firstVerNonce *musig2.Nonces
27✔
4095
        if channel.ChanType.IsTaproot() {
31✔
4096
                firstVerNonce, err = genFirstStateMusigNonce(channel)
4✔
4097
                if err != nil {
4✔
4098
                        log.Error(err)
×
4099
                        return
×
4100
                }
×
4101
        }
4102

4103
        // We'll need to store the received TLV alias if the option_scid_alias
4104
        // feature was negotiated. This will be used to provide route hints
4105
        // during invoice creation. In the zero-conf case, it is also used to
4106
        // provide a ChannelUpdate to the remote peer. This is done before the
4107
        // call to InsertNextRevocation in case the call to PutPeerAlias fails.
4108
        // If it were to fail on the first call to handleChannelReady, we
4109
        // wouldn't want the channel to be usable yet.
4110
        if channel.NegotiatedAliasFeature() {
33✔
4111
                // If the AliasScid field is nil, we must fail out. We will
6✔
4112
                // most likely not be able to route through the peer.
6✔
4113
                if msg.AliasScid == nil {
6✔
4114
                        log.Debugf("Consider closing ChannelID(%v), peer "+
×
4115
                                "does not implement the option-scid-alias "+
×
4116
                                "feature properly", chanID)
×
4117
                        return
×
4118
                }
×
4119

4120
                // We'll store the AliasScid so that invoice creation can use
4121
                // it.
4122
                err = f.cfg.AliasManager.PutPeerAlias(chanID, *msg.AliasScid)
6✔
4123
                if err != nil {
6✔
4124
                        log.Errorf("unable to store peer's alias: %v", err)
×
4125
                        return
×
4126
                }
×
4127

4128
                // If we do not have an alias stored, we'll create one now.
4129
                // This is only used in the upgrade case where a user toggles
4130
                // the option-scid-alias feature-bit to on. We'll also send the
4131
                // channel_ready message here in case the link is created
4132
                // before sendChannelReady is called.
4133
                aliases := f.cfg.AliasManager.GetAliases(
6✔
4134
                        channel.ShortChannelID,
6✔
4135
                )
6✔
4136
                if len(aliases) == 0 {
6✔
4137
                        // No aliases were found so we'll request and store an
×
4138
                        // alias and use it in the channel_ready message.
×
4139
                        alias, err := f.cfg.AliasManager.RequestAlias()
×
4140
                        if err != nil {
×
4141
                                log.Errorf("unable to request alias: %v", err)
×
4142
                                return
×
4143
                        }
×
4144

4145
                        err = f.cfg.AliasManager.AddLocalAlias(
×
4146
                                alias, channel.ShortChannelID, false, false,
×
4147
                        )
×
4148
                        if err != nil {
×
4149
                                log.Errorf("unable to add local alias: %v",
×
4150
                                        err)
×
4151
                                return
×
4152
                        }
×
4153

4154
                        secondPoint, err := channel.SecondCommitmentPoint()
×
4155
                        if err != nil {
×
4156
                                log.Errorf("unable to fetch second "+
×
4157
                                        "commitment point: %v", err)
×
4158
                                return
×
4159
                        }
×
4160

4161
                        channelReadyMsg := lnwire.NewChannelReady(
×
4162
                                chanID, secondPoint,
×
4163
                        )
×
4164
                        channelReadyMsg.AliasScid = &alias
×
4165

×
4166
                        if firstVerNonce != nil {
×
4167
                                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce( //nolint:ll
×
4168
                                        firstVerNonce.PubNonce,
×
4169
                                )
×
4170
                        }
×
4171

4172
                        err = peer.SendMessage(true, channelReadyMsg)
×
4173
                        if err != nil {
×
4174
                                log.Errorf("unable to send channel_ready: %v",
×
4175
                                        err)
×
4176
                                return
×
4177
                        }
×
4178
                }
4179
        }
4180

4181
        // If the RemoteNextRevocation is non-nil, it means that we have
4182
        // already processed channelReady for this channel, so ignore. This
4183
        // check is after the alias logic so we store the peer's most recent
4184
        // alias. The spec requires us to validate that subsequent
4185
        // channel_ready messages use the same per commitment point (the
4186
        // second), but it is not actually necessary since we'll just end up
4187
        // ignoring it. We are, however, required to *send* the same per
4188
        // commitment point, since another pedantic implementation might
4189
        // verify it.
4190
        if channel.RemoteNextRevocation != nil {
28✔
4191
                log.Infof("Received duplicate channelReady for "+
1✔
4192
                        "ChannelID(%v), ignoring.", chanID)
1✔
4193
                return
1✔
4194
        }
1✔
4195

4196
        // If this is a taproot channel, then we'll need to map the received
4197
        // nonces to a nonce pair, and also fetch our pending nonces, which are
4198
        // required in order to make the channel whole.
4199
        var chanOpts []lnwallet.ChannelOpt
26✔
4200
        if channel.ChanType.IsTaproot() {
30✔
4201
                f.nonceMtx.Lock()
4✔
4202
                localNonce, ok := f.pendingMusigNonces[chanID]
4✔
4203
                if !ok {
4✔
4204
                        // If there's no pending nonce for this channel ID,
×
4205
                        // we'll use the one generated above.
×
4206
                        localNonce = firstVerNonce
×
4207
                        f.pendingMusigNonces[chanID] = firstVerNonce
×
4208
                }
×
4209
                f.nonceMtx.Unlock()
4✔
4210

4✔
4211
                log.Infof("ChanID(%v): applying local+remote musig2 nonces",
4✔
4212
                        chanID)
4✔
4213

4✔
4214
                remoteNonce, err := msg.NextLocalNonce.UnwrapOrErrV(
4✔
4215
                        errNoLocalNonce,
4✔
4216
                )
4✔
4217
                if err != nil {
4✔
4218
                        cid := newChanIdentifier(msg.ChanID)
×
4219
                        f.sendWarning(peer, cid, err)
×
4220

×
4221
                        return
×
4222
                }
×
4223

4224
                chanOpts = append(
4✔
4225
                        chanOpts,
4✔
4226
                        lnwallet.WithLocalMusigNonces(localNonce),
4✔
4227
                        lnwallet.WithRemoteMusigNonces(&musig2.Nonces{
4✔
4228
                                PubNonce: remoteNonce,
4✔
4229
                        }),
4✔
4230
                )
4✔
4231

4✔
4232
                // Inform the aux funding controller that the liquidity in the
4✔
4233
                // custom channel is now ready to be advertised. We potentially
4✔
4234
                // haven't sent our own channel ready message yet, but other
4✔
4235
                // than that the channel is ready to count toward available
4✔
4236
                // liquidity.
4✔
4237
                err = fn.MapOptionZ(
4✔
4238
                        f.cfg.AuxFundingController,
4✔
4239
                        func(controller AuxFundingController) error {
4✔
4240
                                return controller.ChannelReady(
×
4241
                                        lnwallet.NewAuxChanState(channel),
×
4242
                                )
×
4243
                        },
×
4244
                )
4245
                if err != nil {
4✔
4246
                        cid := newChanIdentifier(msg.ChanID)
×
4247
                        f.sendWarning(peer, cid, err)
×
4248

×
4249
                        return
×
4250
                }
×
4251
        }
4252

4253
        // The channel_ready message contains the next commitment point we'll
4254
        // need to create the next commitment state for the remote party. So
4255
        // we'll insert that into the channel now before passing it along to
4256
        // other sub-systems.
4257
        err = channel.InsertNextRevocation(msg.NextPerCommitmentPoint)
26✔
4258
        if err != nil {
26✔
4259
                log.Errorf("unable to insert next commitment point: %v", err)
×
4260
                return
×
4261
        }
×
4262

4263
        // Before we can add the channel to the peer, we'll need to ensure that
4264
        // we have an initial forwarding policy set.
4265
        if err := f.ensureInitialForwardingPolicy(chanID, channel); err != nil {
26✔
4266
                log.Errorf("Unable to ensure initial forwarding policy: %v",
×
4267
                        err)
×
4268
        }
×
4269

4270
        err = peer.AddNewChannel(&lnpeer.NewChannel{
26✔
4271
                OpenChannel: channel,
26✔
4272
                ChanOpts:    chanOpts,
26✔
4273
        }, f.quit)
26✔
4274
        if err != nil {
26✔
4275
                log.Errorf("Unable to add new channel %v with peer %x: %v",
×
4276
                        channel.FundingOutpoint,
×
4277
                        peer.IdentityKey().SerializeCompressed(), err,
×
4278
                )
×
4279
        }
×
4280
}
4281

4282
// handleChannelReadyReceived is called once the remote's channelReady message
4283
// is received and processed. At this stage, we must have sent out our
4284
// channelReady message, once the remote's channelReady is processed, the
4285
// channel is now active, thus we change its state to `addedToGraph` to
4286
// let the channel start handling routing.
4287
func (f *Manager) handleChannelReadyReceived(channel *channeldb.OpenChannel,
4288
        scid *lnwire.ShortChannelID, pendingChanID PendingChanID,
4289
        updateChan chan<- *lnrpc.OpenStatusUpdate) error {
24✔
4290

24✔
4291
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
24✔
4292

24✔
4293
        // Since we've sent+received funding locked at this point, we
24✔
4294
        // can clean up the pending musig2 nonce state.
24✔
4295
        f.nonceMtx.Lock()
24✔
4296
        delete(f.pendingMusigNonces, chanID)
24✔
4297
        f.nonceMtx.Unlock()
24✔
4298

24✔
4299
        var peerAlias *lnwire.ShortChannelID
24✔
4300
        if channel.IsZeroConf() {
28✔
4301
                // We'll need to wait until channel_ready has been received and
4✔
4302
                // the peer lets us know the alias they want to use for the
4✔
4303
                // channel. With this information, we can then construct a
4✔
4304
                // ChannelUpdate for them.  If an alias does not yet exist,
4✔
4305
                // we'll just return, letting the next iteration of the loop
4✔
4306
                // check again.
4✔
4307
                var defaultAlias lnwire.ShortChannelID
4✔
4308
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
4✔
4309
                foundAlias, _ := f.cfg.AliasManager.GetPeerAlias(chanID)
4✔
4310
                if foundAlias == defaultAlias {
4✔
4311
                        return nil
×
4312
                }
×
4313

4314
                peerAlias = &foundAlias
4✔
4315
        }
4316

4317
        err := f.addToGraph(channel, scid, peerAlias, nil)
24✔
4318
        if err != nil {
24✔
4319
                return fmt.Errorf("failed adding to graph: %w", err)
×
4320
        }
×
4321

4322
        // As the channel is now added to the ChannelRouter's topology, the
4323
        // channel is moved to the next state of the state machine. It will be
4324
        // moved to the last state (actually deleted from the database) after
4325
        // the channel is finally announced.
4326
        err = f.saveChannelOpeningState(
24✔
4327
                &channel.FundingOutpoint, addedToGraph, scid,
24✔
4328
        )
24✔
4329
        if err != nil {
24✔
4330
                return fmt.Errorf("error setting channel state to"+
×
4331
                        " addedToGraph: %w", err)
×
4332
        }
×
4333

4334
        log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
24✔
4335
                "added to graph", chanID, scid)
24✔
4336

24✔
4337
        err = fn.MapOptionZ(
24✔
4338
                f.cfg.AuxFundingController,
24✔
4339
                func(controller AuxFundingController) error {
24✔
4340
                        return controller.ChannelReady(
×
4341
                                lnwallet.NewAuxChanState(channel),
×
4342
                        )
×
4343
                },
×
4344
        )
4345
        if err != nil {
24✔
4346
                return fmt.Errorf("failed notifying aux funding controller "+
×
4347
                        "about channel ready: %w", err)
×
4348
        }
×
4349

4350
        // Give the caller a final update notifying them that the channel is
4351
        fundingPoint := channel.FundingOutpoint
24✔
4352
        cp := &lnrpc.ChannelPoint{
24✔
4353
                FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
24✔
4354
                        FundingTxidBytes: fundingPoint.Hash[:],
24✔
4355
                },
24✔
4356
                OutputIndex: fundingPoint.Index,
24✔
4357
        }
24✔
4358

24✔
4359
        if updateChan != nil {
34✔
4360
                upd := &lnrpc.OpenStatusUpdate{
10✔
4361
                        Update: &lnrpc.OpenStatusUpdate_ChanOpen{
10✔
4362
                                ChanOpen: &lnrpc.ChannelOpenUpdate{
10✔
4363
                                        ChannelPoint: cp,
10✔
4364
                                },
10✔
4365
                        },
10✔
4366
                        PendingChanId: pendingChanID[:],
10✔
4367
                }
10✔
4368

10✔
4369
                select {
10✔
4370
                case updateChan <- upd:
10✔
4371
                case <-f.quit:
×
4372
                        return ErrFundingManagerShuttingDown
×
4373
                }
4374
        }
4375

4376
        return nil
24✔
4377
}
4378

4379
// ensureInitialForwardingPolicy ensures that we have an initial forwarding
4380
// policy set for the given channel. If we don't, we'll fall back to the default
4381
// values.
4382
func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID,
4383
        channel *channeldb.OpenChannel) error {
26✔
4384

26✔
4385
        // Before we can add the channel to the peer, we'll need to ensure that
26✔
4386
        // we have an initial forwarding policy set. This should always be the
26✔
4387
        // case except for a channel that was created with lnd <= 0.15.5 and
26✔
4388
        // is still pending while updating to this version.
26✔
4389
        var needDBUpdate bool
26✔
4390
        forwardingPolicy, err := f.getInitialForwardingPolicy(chanID)
26✔
4391
        if err != nil {
26✔
4392
                log.Errorf("Unable to fetch initial forwarding policy, "+
×
4393
                        "falling back to default values: %v", err)
×
4394

×
4395
                forwardingPolicy = f.defaultForwardingPolicy(
×
4396
                        channel.LocalChanCfg.ChannelStateBounds,
×
4397
                )
×
4398
                needDBUpdate = true
×
4399
        }
×
4400

4401
        // We only started storing the actual values for MinHTLCOut and MaxHTLC
4402
        // after 0.16.x, so if a channel was opened with such a version and is
4403
        // still pending while updating to this version, we'll need to set the
4404
        // values to the default values.
4405
        if forwardingPolicy.MinHTLCOut == 0 {
39✔
4406
                forwardingPolicy.MinHTLCOut = channel.LocalChanCfg.MinHTLC
13✔
4407
                needDBUpdate = true
13✔
4408
        }
13✔
4409
        if forwardingPolicy.MaxHTLC == 0 {
39✔
4410
                forwardingPolicy.MaxHTLC = channel.LocalChanCfg.MaxPendingAmount
13✔
4411
                needDBUpdate = true
13✔
4412
        }
13✔
4413

4414
        // And finally, if we found that the values currently stored aren't
4415
        // sufficient for the link, we'll update the database.
4416
        if needDBUpdate {
39✔
4417
                err := f.saveInitialForwardingPolicy(chanID, forwardingPolicy)
13✔
4418
                if err != nil {
13✔
4419
                        return fmt.Errorf("unable to update initial "+
×
4420
                                "forwarding policy: %v", err)
×
4421
                }
×
4422
        }
4423

4424
        return nil
26✔
4425
}
4426

4427
// chanAnnouncement encapsulates the two authenticated announcements that we
4428
// send out to the network after a new channel has been created locally.
4429
type chanAnnouncement struct {
4430
        chanAnn       *lnwire.ChannelAnnouncement1
4431
        chanUpdateAnn *lnwire.ChannelUpdate1
4432
        chanProof     *lnwire.AnnounceSignatures1
4433
}
4434

4435
// newChanAnnouncement creates the authenticated channel announcement messages
4436
// required to broadcast a newly created channel to the network. The
4437
// announcement is two part: the first part authenticates the existence of the
4438
// channel and contains four signatures binding the funding pub keys and
4439
// identity pub keys of both parties to the channel, and the second segment is
4440
// authenticated only by us and contains our directional routing policy for the
4441
// channel. ourPolicy may be set in order to re-use an existing, non-default
4442
// policy.
4443
func (f *Manager) newChanAnnouncement(localPubKey,
4444
        remotePubKey *btcec.PublicKey, localFundingKey *keychain.KeyDescriptor,
4445
        remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
4446
        chanID lnwire.ChannelID, fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi,
4447
        ourPolicy *models.ChannelEdgePolicy,
4448
        chanType channeldb.ChannelType) (*chanAnnouncement, error) {
42✔
4449

42✔
4450
        chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
42✔
4451

42✔
4452
        // The unconditional section of the announcement is the ShortChannelID
42✔
4453
        // itself which compactly encodes the location of the funding output
42✔
4454
        // within the blockchain.
42✔
4455
        chanAnn := &lnwire.ChannelAnnouncement1{
42✔
4456
                ShortChannelID: shortChanID,
42✔
4457
                Features:       lnwire.NewRawFeatureVector(),
42✔
4458
                ChainHash:      chainHash,
42✔
4459
        }
42✔
4460

42✔
4461
        // If this is a taproot channel, then we'll set a special bit in the
42✔
4462
        // feature vector to indicate to the routing layer that this needs a
42✔
4463
        // slightly different type of validation.
42✔
4464
        //
42✔
4465
        // TODO(roasbeef): temp, remove after gossip 1.5
42✔
4466
        if chanType.IsTaproot() {
46✔
4467
                log.Debugf("Applying taproot feature bit to "+
4✔
4468
                        "ChannelAnnouncement for %v", chanID)
4✔
4469

4✔
4470
                chanAnn.Features.Set(
4✔
4471
                        lnwire.SimpleTaprootChannelsRequiredStaging,
4✔
4472
                )
4✔
4473
        }
4✔
4474

4475
        // The chanFlags field indicates which directed edge of the channel is
4476
        // being updated within the ChannelUpdateAnnouncement announcement
4477
        // below. A value of zero means it's the edge of the "first" node and 1
4478
        // being the other node.
4479
        var chanFlags lnwire.ChanUpdateChanFlags
42✔
4480

42✔
4481
        // The lexicographical ordering of the two identity public keys of the
42✔
4482
        // nodes indicates which of the nodes is "first". If our serialized
42✔
4483
        // identity key is lower than theirs then we're the "first" node and
42✔
4484
        // second otherwise.
42✔
4485
        selfBytes := localPubKey.SerializeCompressed()
42✔
4486
        remoteBytes := remotePubKey.SerializeCompressed()
42✔
4487
        if bytes.Compare(selfBytes, remoteBytes) == -1 {
63✔
4488
                copy(chanAnn.NodeID1[:], localPubKey.SerializeCompressed())
21✔
4489
                copy(chanAnn.NodeID2[:], remotePubKey.SerializeCompressed())
21✔
4490
                copy(
21✔
4491
                        chanAnn.BitcoinKey1[:],
21✔
4492
                        localFundingKey.PubKey.SerializeCompressed(),
21✔
4493
                )
21✔
4494
                copy(
21✔
4495
                        chanAnn.BitcoinKey2[:],
21✔
4496
                        remoteFundingKey.SerializeCompressed(),
21✔
4497
                )
21✔
4498

21✔
4499
                // If we're the first node then update the chanFlags to
21✔
4500
                // indicate the "direction" of the update.
21✔
4501
                chanFlags = 0
21✔
4502
        } else {
42✔
4503
                copy(chanAnn.NodeID1[:], remotePubKey.SerializeCompressed())
21✔
4504
                copy(chanAnn.NodeID2[:], localPubKey.SerializeCompressed())
21✔
4505
                copy(
21✔
4506
                        chanAnn.BitcoinKey1[:],
21✔
4507
                        remoteFundingKey.SerializeCompressed(),
21✔
4508
                )
21✔
4509
                copy(
21✔
4510
                        chanAnn.BitcoinKey2[:],
21✔
4511
                        localFundingKey.PubKey.SerializeCompressed(),
21✔
4512
                )
21✔
4513

21✔
4514
                // If we're the second node then update the chanFlags to
21✔
4515
                // indicate the "direction" of the update.
21✔
4516
                chanFlags = 1
21✔
4517
        }
21✔
4518

4519
        // Our channel update message flags will signal that we support the
4520
        // max_htlc field.
4521
        msgFlags := lnwire.ChanUpdateRequiredMaxHtlc
42✔
4522

42✔
4523
        // We announce the channel with the default values. Some of
42✔
4524
        // these values can later be changed by crafting a new ChannelUpdate.
42✔
4525
        chanUpdateAnn := &lnwire.ChannelUpdate1{
42✔
4526
                ShortChannelID: shortChanID,
42✔
4527
                ChainHash:      chainHash,
42✔
4528
                Timestamp:      uint32(time.Now().Unix()),
42✔
4529
                MessageFlags:   msgFlags,
42✔
4530
                ChannelFlags:   chanFlags,
42✔
4531
                TimeLockDelta: uint16(
42✔
4532
                        f.cfg.DefaultRoutingPolicy.TimeLockDelta,
42✔
4533
                ),
42✔
4534
                HtlcMinimumMsat: fwdMinHTLC,
42✔
4535
                HtlcMaximumMsat: fwdMaxHTLC,
42✔
4536
        }
42✔
4537

42✔
4538
        // The caller of newChanAnnouncement is expected to provide the initial
42✔
4539
        // forwarding policy to be announced. If no persisted initial policy
42✔
4540
        // values are found, then we will use the default policy values in the
42✔
4541
        // channel announcement.
42✔
4542
        storedFwdingPolicy, err := f.getInitialForwardingPolicy(chanID)
42✔
4543
        if err != nil && !errors.Is(err, channeldb.ErrChannelNotFound) {
42✔
4544
                return nil, fmt.Errorf("unable to generate channel "+
×
4545
                        "update announcement: %w", err)
×
4546
        }
×
4547

4548
        switch {
42✔
4549
        case ourPolicy != nil:
×
4550
                // If ourPolicy is non-nil, modify the default parameters of the
×
4551
                // ChannelUpdate.
×
4552
                chanUpdateAnn.MessageFlags = ourPolicy.MessageFlags
×
4553
                chanUpdateAnn.ChannelFlags = ourPolicy.ChannelFlags
×
4554
                chanUpdateAnn.TimeLockDelta = ourPolicy.TimeLockDelta
×
4555
                chanUpdateAnn.HtlcMinimumMsat = ourPolicy.MinHTLC
×
4556
                chanUpdateAnn.HtlcMaximumMsat = ourPolicy.MaxHTLC
×
4557
                chanUpdateAnn.BaseFee = uint32(ourPolicy.FeeBaseMSat)
×
4558
                chanUpdateAnn.FeeRate = uint32(
×
4559
                        ourPolicy.FeeProportionalMillionths,
×
4560
                )
×
4561

4562
        case storedFwdingPolicy != nil:
42✔
4563
                chanUpdateAnn.BaseFee = uint32(storedFwdingPolicy.BaseFee)
42✔
4564
                chanUpdateAnn.FeeRate = uint32(storedFwdingPolicy.FeeRate)
42✔
4565

4566
        default:
×
4567
                log.Infof("No channel forwarding policy specified for channel "+
×
4568
                        "announcement of ChannelID(%v). "+
×
4569
                        "Assuming default fee parameters.", chanID)
×
4570
                chanUpdateAnn.BaseFee = uint32(
×
4571
                        f.cfg.DefaultRoutingPolicy.BaseFee,
×
4572
                )
×
4573
                chanUpdateAnn.FeeRate = uint32(
×
4574
                        f.cfg.DefaultRoutingPolicy.FeeRate,
×
4575
                )
×
4576
        }
4577

4578
        // With the channel update announcement constructed, we'll generate a
4579
        // signature that signs a double-sha digest of the announcement.
4580
        // This'll serve to authenticate this announcement and any other future
4581
        // updates we may send.
4582
        chanUpdateMsg, err := chanUpdateAnn.DataToSign()
42✔
4583
        if err != nil {
42✔
4584
                return nil, err
×
4585
        }
×
4586
        sig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanUpdateMsg, true)
42✔
4587
        if err != nil {
42✔
4588
                return nil, fmt.Errorf("unable to generate channel "+
×
4589
                        "update announcement signature: %w", err)
×
4590
        }
×
4591
        chanUpdateAnn.Signature, err = lnwire.NewSigFromSignature(sig)
42✔
4592
        if err != nil {
42✔
4593
                return nil, fmt.Errorf("unable to generate channel "+
×
4594
                        "update announcement signature: %w", err)
×
4595
        }
×
4596

4597
        // The channel existence proofs itself is currently announced in
4598
        // distinct message. In order to properly authenticate this message, we
4599
        // need two signatures: one under the identity public key used which
4600
        // signs the message itself and another signature of the identity
4601
        // public key under the funding key itself.
4602
        //
4603
        // TODO(roasbeef): use SignAnnouncement here instead?
4604
        chanAnnMsg, err := chanAnn.DataToSign()
42✔
4605
        if err != nil {
42✔
4606
                return nil, err
×
4607
        }
×
4608
        nodeSig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanAnnMsg, true)
42✔
4609
        if err != nil {
42✔
4610
                return nil, fmt.Errorf("unable to generate node "+
×
4611
                        "signature for channel announcement: %w", err)
×
4612
        }
×
4613
        bitcoinSig, err := f.cfg.SignMessage(
42✔
4614
                localFundingKey.KeyLocator, chanAnnMsg, true,
42✔
4615
        )
42✔
4616
        if err != nil {
42✔
4617
                return nil, fmt.Errorf("unable to generate bitcoin "+
×
4618
                        "signature for node public key: %w", err)
×
4619
        }
×
4620

4621
        // Finally, we'll generate the announcement proof which we'll use to
4622
        // provide the other side with the necessary signatures required to
4623
        // allow them to reconstruct the full channel announcement.
4624
        proof := &lnwire.AnnounceSignatures1{
42✔
4625
                ChannelID:      chanID,
42✔
4626
                ShortChannelID: shortChanID,
42✔
4627
        }
42✔
4628
        proof.NodeSignature, err = lnwire.NewSigFromSignature(nodeSig)
42✔
4629
        if err != nil {
42✔
4630
                return nil, err
×
4631
        }
×
4632
        proof.BitcoinSignature, err = lnwire.NewSigFromSignature(bitcoinSig)
42✔
4633
        if err != nil {
42✔
4634
                return nil, err
×
4635
        }
×
4636

4637
        return &chanAnnouncement{
42✔
4638
                chanAnn:       chanAnn,
42✔
4639
                chanUpdateAnn: chanUpdateAnn,
42✔
4640
                chanProof:     proof,
42✔
4641
        }, nil
42✔
4642
}
4643

4644
// announceChannel announces a newly created channel to the rest of the network
4645
// by crafting the two authenticated announcements required for the peers on
4646
// the network to recognize the legitimacy of the channel. The crafted
4647
// announcements are then sent to the channel router to handle broadcasting to
4648
// the network during its next trickle.
4649
// This method is synchronous and will return when all the network requests
4650
// finish, either successfully or with an error.
4651
func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
4652
        localFundingKey *keychain.KeyDescriptor,
4653
        remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
4654
        chanID lnwire.ChannelID, chanType channeldb.ChannelType) error {
16✔
4655

16✔
4656
        // First, we'll create the batch of announcements to be sent upon
16✔
4657
        // initial channel creation. This includes the channel announcement
16✔
4658
        // itself, the channel update announcement, and our half of the channel
16✔
4659
        // proof needed to fully authenticate the channel.
16✔
4660
        //
16✔
4661
        // We can pass in zeroes for the min and max htlc policy, because we
16✔
4662
        // only use the channel announcement message from the returned struct.
16✔
4663
        ann, err := f.newChanAnnouncement(
16✔
4664
                localIDKey, remoteIDKey, localFundingKey, remoteFundingKey,
16✔
4665
                shortChanID, chanID, 0, 0, nil, chanType,
16✔
4666
        )
16✔
4667
        if err != nil {
16✔
4668
                log.Errorf("can't generate channel announcement: %v", err)
×
4669
                return err
×
4670
        }
×
4671

4672
        // We only send the channel proof announcement and the node announcement
4673
        // because addToGraph previously sent the ChannelAnnouncement and
4674
        // the ChannelUpdate announcement messages. The channel proof and node
4675
        // announcements are broadcast to the greater network.
4676
        errChan := f.cfg.SendAnnouncement(ann.chanProof)
16✔
4677
        select {
16✔
4678
        case err := <-errChan:
16✔
4679
                if err != nil {
16✔
4680
                        if graph.IsError(err, graph.ErrOutdated,
×
4681
                                graph.ErrIgnored) {
×
4682

×
4683
                                log.Debugf("Graph rejected "+
×
4684
                                        "AnnounceSignatures: %v", err)
×
4685
                        } else {
×
4686
                                log.Errorf("Unable to send channel "+
×
4687
                                        "proof: %v", err)
×
4688
                                return err
×
4689
                        }
×
4690
                }
4691

4692
        case <-f.quit:
×
4693
                return ErrFundingManagerShuttingDown
×
4694
        }
4695

4696
        // Now that the channel is announced to the network, we will also
4697
        // obtain and send a node announcement. This is done since a node
4698
        // announcement is only accepted after a channel is known for that
4699
        // particular node, and this might be our first channel.
4700
        nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
16✔
4701
        if err != nil {
16✔
4702
                log.Errorf("can't generate node announcement: %v", err)
×
4703
                return err
×
4704
        }
×
4705

4706
        errChan = f.cfg.SendAnnouncement(&nodeAnn)
16✔
4707
        select {
16✔
4708
        case err := <-errChan:
16✔
4709
                if err != nil {
16✔
4710
                        if graph.IsError(err, graph.ErrOutdated,
×
4711
                                graph.ErrIgnored) {
×
4712

×
4713
                                log.Debugf("Graph rejected "+
×
4714
                                        "NodeAnnouncement: %v", err)
×
4715
                        } else {
×
4716
                                log.Errorf("Unable to send node "+
×
4717
                                        "announcement: %v", err)
×
4718
                                return err
×
4719
                        }
×
4720
                }
4721

4722
        case <-f.quit:
×
4723
                return ErrFundingManagerShuttingDown
×
4724
        }
4725

4726
        return nil
16✔
4727
}
4728

4729
// InitFundingWorkflow sends a message to the funding manager instructing it
4730
// to initiate a single funder workflow with the source peer.
4731
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
57✔
4732
        f.fundingRequests <- msg
57✔
4733
}
57✔
4734

4735
// getUpfrontShutdownScript takes a user provided script and a getScript
4736
// function which can be used to generate an upfront shutdown script. If our
4737
// peer does not support the feature, this function will error if a non-zero
4738
// script was provided by the user, and return an empty script otherwise. If
4739
// our peer does support the feature, we will return the user provided script
4740
// if non-zero, or a freshly generated script if our node is configured to set
4741
// upfront shutdown scripts automatically.
4742
func getUpfrontShutdownScript(enableUpfrontShutdown bool, peer lnpeer.Peer,
4743
        script lnwire.DeliveryAddress,
4744
        getScript func(bool) (lnwire.DeliveryAddress, error)) (lnwire.DeliveryAddress,
4745
        error) {
110✔
4746

110✔
4747
        // Check whether the remote peer supports upfront shutdown scripts.
110✔
4748
        remoteUpfrontShutdown := peer.RemoteFeatures().HasFeature(
110✔
4749
                lnwire.UpfrontShutdownScriptOptional,
110✔
4750
        )
110✔
4751

110✔
4752
        // If the peer does not support upfront shutdown scripts, and one has been
110✔
4753
        // provided, return an error because the feature is not supported.
110✔
4754
        if !remoteUpfrontShutdown && len(script) != 0 {
111✔
4755
                return nil, errUpfrontShutdownScriptNotSupported
1✔
4756
        }
1✔
4757

4758
        // If the peer does not support upfront shutdown, return an empty address.
4759
        if !remoteUpfrontShutdown {
214✔
4760
                return nil, nil
105✔
4761
        }
105✔
4762

4763
        // If the user has provided an script and the peer supports the feature,
4764
        // return it. Note that user set scripts override the enable upfront
4765
        // shutdown flag.
4766
        if len(script) > 0 {
6✔
4767
                return script, nil
2✔
4768
        }
2✔
4769

4770
        // If we do not have setting of upfront shutdown script enabled, return
4771
        // an empty script.
4772
        if !enableUpfrontShutdown {
3✔
4773
                return nil, nil
1✔
4774
        }
1✔
4775

4776
        // We can safely send a taproot address iff, both sides have negotiated
4777
        // the shutdown-any-segwit feature.
4778
        taprootOK := peer.RemoteFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) &&
1✔
4779
                peer.LocalFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional)
1✔
4780

1✔
4781
        return getScript(taprootOK)
1✔
4782
}
4783

4784
// handleInitFundingMsg creates a channel reservation within the daemon's
4785
// wallet, then sends a funding request to the remote peer kicking off the
4786
// funding workflow.
4787
func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
57✔
4788
        var (
57✔
4789
                peerKey        = msg.Peer.IdentityKey()
57✔
4790
                localAmt       = msg.LocalFundingAmt
57✔
4791
                baseFee        = msg.BaseFee
57✔
4792
                feeRate        = msg.FeeRate
57✔
4793
                minHtlcIn      = msg.MinHtlcIn
57✔
4794
                remoteCsvDelay = msg.RemoteCsvDelay
57✔
4795
                maxValue       = msg.MaxValueInFlight
57✔
4796
                maxHtlcs       = msg.MaxHtlcs
57✔
4797
                maxCSV         = msg.MaxLocalCsv
57✔
4798
                chanReserve    = msg.RemoteChanReserve
57✔
4799
                outpoints      = msg.Outpoints
57✔
4800
        )
57✔
4801

57✔
4802
        // If no maximum CSV delay was set for this channel, we use our default
57✔
4803
        // value.
57✔
4804
        if maxCSV == 0 {
114✔
4805
                maxCSV = f.cfg.MaxLocalCSVDelay
57✔
4806
        }
57✔
4807

4808
        log.Infof("Initiating fundingRequest(local_amt=%v "+
57✔
4809
                "(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
57✔
4810
                "min_confs=%v)", localAmt, msg.SubtractFees, msg.PushAmt,
57✔
4811
                msg.ChainHash, peerKey.SerializeCompressed(), msg.MinConfs)
57✔
4812

57✔
4813
        // We set the channel flags to indicate whether we want this channel to
57✔
4814
        // be announced to the network.
57✔
4815
        var channelFlags lnwire.FundingFlag
57✔
4816
        if !msg.Private {
109✔
4817
                // This channel will be announced.
52✔
4818
                channelFlags = lnwire.FFAnnounceChannel
52✔
4819
        }
52✔
4820

4821
        // If the caller specified their own channel ID, then we'll use that.
4822
        // Otherwise we'll generate a fresh one as normal.  This will be used
4823
        // to track this reservation throughout its lifetime.
4824
        var chanID PendingChanID
57✔
4825
        if msg.PendingChanID == zeroID {
114✔
4826
                chanID = f.nextPendingChanID()
57✔
4827
        } else {
57✔
4828
                // If the user specified their own pending channel ID, then
×
4829
                // we'll ensure it doesn't collide with any existing pending
×
4830
                // channel ID.
×
4831
                chanID = msg.PendingChanID
×
4832
                if _, err := f.getReservationCtx(peerKey, chanID); err == nil {
×
4833
                        msg.Err <- fmt.Errorf("pendingChannelID(%x) "+
×
4834
                                "already present", chanID[:])
×
4835
                        return
×
4836
                }
×
4837
        }
4838

4839
        // Check whether the peer supports upfront shutdown, and get an address
4840
        // which should be used (either a user specified address or a new
4841
        // address from the wallet if our node is configured to set shutdown
4842
        // address by default).
4843
        shutdown, err := getUpfrontShutdownScript(
57✔
4844
                f.cfg.EnableUpfrontShutdown, msg.Peer, msg.ShutdownScript,
57✔
4845
                f.selectShutdownScript,
57✔
4846
        )
57✔
4847
        if err != nil {
57✔
4848
                msg.Err <- err
×
4849
                return
×
4850
        }
×
4851

4852
        // Initialize a funding reservation with the local wallet. If the
4853
        // wallet doesn't have enough funds to commit to this channel, then the
4854
        // request will fail, and be aborted.
4855
        //
4856
        // Before we init the channel, we'll also check to see what commitment
4857
        // format we can use with this peer. This is dependent on *both* us and
4858
        // the remote peer are signaling the proper feature bit.
4859
        chanType, commitType, err := negotiateCommitmentType(
57✔
4860
                msg.ChannelType, msg.Peer.LocalFeatures(),
57✔
4861
                msg.Peer.RemoteFeatures(),
57✔
4862
        )
57✔
4863
        if err != nil {
57✔
4864
                log.Errorf("channel type negotiation failed: %v", err)
×
4865
                msg.Err <- err
×
4866
                return
×
4867
        }
×
4868

4869
        var (
57✔
4870
                zeroConf bool
57✔
4871
                scid     bool
57✔
4872
        )
57✔
4873

57✔
4874
        if chanType != nil {
61✔
4875
                // Check if the returned chanType includes either the zero-conf
4✔
4876
                // or scid-alias bits.
4✔
4877
                featureVec := lnwire.RawFeatureVector(*chanType)
4✔
4878
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
4✔
4879
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
4✔
4880

4✔
4881
                // The option-scid-alias channel type for a public channel is
4✔
4882
                // disallowed.
4✔
4883
                if scid && !msg.Private {
4✔
4884
                        err = fmt.Errorf("option-scid-alias chantype for " +
×
4885
                                "public channel")
×
4886
                        log.Error(err)
×
4887
                        msg.Err <- err
×
4888

×
4889
                        return
×
4890
                }
×
4891
        }
4892

4893
        // First, we'll query the fee estimator for a fee that should get the
4894
        // commitment transaction confirmed by the next few blocks (conf target
4895
        // of 3). We target the near blocks here to ensure that we'll be able
4896
        // to execute a timely unilateral channel closure if needed.
4897
        commitFeePerKw, err := f.cfg.FeeEstimator.EstimateFeePerKW(3)
57✔
4898
        if err != nil {
57✔
4899
                msg.Err <- err
×
4900
                return
×
4901
        }
×
4902

4903
        // For anchor channels cap the initial commit fee rate at our defined
4904
        // maximum.
4905
        if commitType.HasAnchors() &&
57✔
4906
                commitFeePerKw > f.cfg.MaxAnchorsCommitFeeRate {
61✔
4907

4✔
4908
                commitFeePerKw = f.cfg.MaxAnchorsCommitFeeRate
4✔
4909
        }
4✔
4910

4911
        var scidFeatureVal bool
57✔
4912
        if hasFeatures(
57✔
4913
                msg.Peer.LocalFeatures(), msg.Peer.RemoteFeatures(),
57✔
4914
                lnwire.ScidAliasOptional,
57✔
4915
        ) {
60✔
4916

3✔
4917
                scidFeatureVal = true
3✔
4918
        }
3✔
4919

4920
        // At this point, if we have an AuxFundingController active, we'll check
4921
        // to see if we have a special tapscript root to use in our MuSig2
4922
        // funding output.
4923
        tapscriptRoot, err := fn.MapOptionZ(
57✔
4924
                f.cfg.AuxFundingController,
57✔
4925
                func(c AuxFundingController) AuxTapscriptResult {
57✔
4926
                        return c.DeriveTapscriptRoot(chanID)
×
4927
                },
×
4928
        ).Unpack()
4929
        if err != nil {
57✔
4930
                err = fmt.Errorf("error deriving tapscript root: %w", err)
×
4931
                log.Error(err)
×
4932
                msg.Err <- err
×
4933

×
4934
                return
×
4935
        }
×
4936

4937
        req := &lnwallet.InitFundingReserveMsg{
57✔
4938
                ChainHash:         &msg.ChainHash,
57✔
4939
                PendingChanID:     chanID,
57✔
4940
                NodeID:            peerKey,
57✔
4941
                NodeAddr:          msg.Peer.Address(),
57✔
4942
                SubtractFees:      msg.SubtractFees,
57✔
4943
                LocalFundingAmt:   localAmt,
57✔
4944
                RemoteFundingAmt:  0,
57✔
4945
                FundUpToMaxAmt:    msg.FundUpToMaxAmt,
57✔
4946
                MinFundAmt:        msg.MinFundAmt,
57✔
4947
                RemoteChanReserve: chanReserve,
57✔
4948
                Outpoints:         outpoints,
57✔
4949
                CommitFeePerKw:    commitFeePerKw,
57✔
4950
                FundingFeePerKw:   msg.FundingFeePerKw,
57✔
4951
                PushMSat:          msg.PushAmt,
57✔
4952
                Flags:             channelFlags,
57✔
4953
                MinConfs:          msg.MinConfs,
57✔
4954
                CommitType:        commitType,
57✔
4955
                ChanFunder:        msg.ChanFunder,
57✔
4956
                // Unconfirmed Utxos which are marked by the sweeper subsystem
57✔
4957
                // are excluded from the coin selection because they are not
57✔
4958
                // final and can be RBFed by the sweeper subsystem.
57✔
4959
                AllowUtxoForFunding: func(u lnwallet.Utxo) bool {
115✔
4960
                        // Utxos with at least 1 confirmation are safe to use
58✔
4961
                        // for channel openings because they don't bare the risk
58✔
4962
                        // of being replaced (BIP 125 RBF).
58✔
4963
                        if u.Confirmations > 0 {
58✔
4964
                                return true
×
4965
                        }
×
4966

4967
                        // Query the sweeper storage to make sure we don't use
4968
                        // an unconfirmed utxo still in use by the sweeper
4969
                        // subsystem.
4970
                        return !f.cfg.IsSweeperOutpoint(u.OutPoint)
58✔
4971
                },
4972
                ZeroConf:         zeroConf,
4973
                OptionScidAlias:  scid,
4974
                ScidAliasFeature: scidFeatureVal,
4975
                Memo:             msg.Memo,
4976
                TapscriptRoot:    tapscriptRoot,
4977
        }
4978

4979
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
57✔
4980
        if err != nil {
57✔
4981
                msg.Err <- err
×
4982
                return
×
4983
        }
×
4984

4985
        if zeroConf {
59✔
4986
                // Store the alias for zero-conf channels in the underlying
2✔
4987
                // partial channel state.
2✔
4988
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
2✔
4989
                if err != nil {
2✔
4990
                        msg.Err <- err
×
4991
                        return
×
4992
                }
×
4993

4994
                reservation.AddAlias(aliasScid)
2✔
4995
        }
4996

4997
        // Set our upfront shutdown address in the existing reservation.
4998
        reservation.SetOurUpfrontShutdown(shutdown)
57✔
4999

57✔
5000
        // Now that we have successfully reserved funds for this channel in the
57✔
5001
        // wallet, we can fetch the final channel capacity. This is done at
57✔
5002
        // this point since the final capacity might change in case of
57✔
5003
        // SubtractFees=true.
57✔
5004
        capacity := reservation.Capacity()
57✔
5005

57✔
5006
        log.Infof("Target commit tx sat/kw for pendingID(%x): %v", chanID,
57✔
5007
                int64(commitFeePerKw))
57✔
5008

57✔
5009
        // If the remote CSV delay was not set in the open channel request,
57✔
5010
        // we'll use the RequiredRemoteDelay closure to compute the delay we
57✔
5011
        // require given the total amount of funds within the channel.
57✔
5012
        if remoteCsvDelay == 0 {
113✔
5013
                remoteCsvDelay = f.cfg.RequiredRemoteDelay(capacity)
56✔
5014
        }
56✔
5015

5016
        // If no minimum HTLC value was specified, use the default one.
5017
        if minHtlcIn == 0 {
113✔
5018
                minHtlcIn = f.cfg.DefaultMinHtlcIn
56✔
5019
        }
56✔
5020

5021
        // If no max value was specified, use the default one.
5022
        if maxValue == 0 {
113✔
5023
                maxValue = f.cfg.RequiredRemoteMaxValue(capacity)
56✔
5024
        }
56✔
5025

5026
        if maxHtlcs == 0 {
114✔
5027
                maxHtlcs = f.cfg.RequiredRemoteMaxHTLCs(capacity)
57✔
5028
        }
57✔
5029

5030
        // Once the reservation has been created, and indexed, queue a funding
5031
        // request to the remote peer, kicking off the funding workflow.
5032
        ourContribution := reservation.OurContribution()
57✔
5033

57✔
5034
        // Prepare the optional channel fee values from the initFundingMsg. If
57✔
5035
        // useBaseFee or useFeeRate are false the client did not provide fee
57✔
5036
        // values hence we assume default fee settings from the config.
57✔
5037
        forwardingPolicy := f.defaultForwardingPolicy(
57✔
5038
                ourContribution.ChannelStateBounds,
57✔
5039
        )
57✔
5040
        if baseFee != nil {
58✔
5041
                forwardingPolicy.BaseFee = lnwire.MilliSatoshi(*baseFee)
1✔
5042
        }
1✔
5043

5044
        if feeRate != nil {
58✔
5045
                forwardingPolicy.FeeRate = lnwire.MilliSatoshi(*feeRate)
1✔
5046
        }
1✔
5047

5048
        // Fetch our dust limit which is part of the default channel
5049
        // constraints, and log it.
5050
        ourDustLimit := ourContribution.DustLimit
57✔
5051

57✔
5052
        log.Infof("Dust limit for pendingID(%x): %v", chanID, ourDustLimit)
57✔
5053

57✔
5054
        // If the channel reserve is not specified, then we calculate an
57✔
5055
        // appropriate amount here.
57✔
5056
        if chanReserve == 0 {
110✔
5057
                chanReserve = f.cfg.RequiredRemoteChanReserve(
53✔
5058
                        capacity, ourDustLimit,
53✔
5059
                )
53✔
5060
        }
53✔
5061

5062
        // If a pending channel map for this peer isn't already created, then
5063
        // we create one, ultimately allowing us to track this pending
5064
        // reservation within the target peer.
5065
        peerIDKey := newSerializedKey(peerKey)
57✔
5066
        f.resMtx.Lock()
57✔
5067
        if _, ok := f.activeReservations[peerIDKey]; !ok {
107✔
5068
                f.activeReservations[peerIDKey] = make(pendingChannels)
50✔
5069
        }
50✔
5070

5071
        resCtx := &reservationWithCtx{
57✔
5072
                chanAmt:           capacity,
57✔
5073
                forwardingPolicy:  *forwardingPolicy,
57✔
5074
                remoteCsvDelay:    remoteCsvDelay,
57✔
5075
                remoteMinHtlc:     minHtlcIn,
57✔
5076
                remoteMaxValue:    maxValue,
57✔
5077
                remoteMaxHtlcs:    maxHtlcs,
57✔
5078
                remoteChanReserve: chanReserve,
57✔
5079
                maxLocalCsv:       maxCSV,
57✔
5080
                channelType:       chanType,
57✔
5081
                reservation:       reservation,
57✔
5082
                peer:              msg.Peer,
57✔
5083
                updates:           msg.Updates,
57✔
5084
                err:               msg.Err,
57✔
5085
        }
57✔
5086
        f.activeReservations[peerIDKey][chanID] = resCtx
57✔
5087
        f.resMtx.Unlock()
57✔
5088

57✔
5089
        // Update the timestamp once the InitFundingMsg has been handled.
57✔
5090
        defer resCtx.updateTimestamp()
57✔
5091

57✔
5092
        // Check the sanity of the selected channel constraints.
57✔
5093
        bounds := &channeldb.ChannelStateBounds{
57✔
5094
                ChanReserve:      chanReserve,
57✔
5095
                MaxPendingAmount: maxValue,
57✔
5096
                MinHTLC:          minHtlcIn,
57✔
5097
                MaxAcceptedHtlcs: maxHtlcs,
57✔
5098
        }
57✔
5099
        commitParams := &channeldb.CommitmentParams{
57✔
5100
                DustLimit: ourDustLimit,
57✔
5101
                CsvDelay:  remoteCsvDelay,
57✔
5102
        }
57✔
5103
        err = lnwallet.VerifyConstraints(
57✔
5104
                bounds, commitParams, resCtx.maxLocalCsv, capacity,
57✔
5105
        )
57✔
5106
        if err != nil {
59✔
5107
                _, reserveErr := f.cancelReservationCtx(peerKey, chanID, false)
2✔
5108
                if reserveErr != nil {
2✔
5109
                        log.Errorf("unable to cancel reservation: %v",
×
5110
                                reserveErr)
×
5111
                }
×
5112

5113
                msg.Err <- err
2✔
5114
                return
2✔
5115
        }
5116

5117
        // When opening a script enforced channel lease, include the required
5118
        // expiry TLV record in our proposal.
5119
        var leaseExpiry *lnwire.LeaseExpiry
55✔
5120
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
55✔
5121
                leaseExpiry = new(lnwire.LeaseExpiry)
×
5122
                *leaseExpiry = lnwire.LeaseExpiry(reservation.LeaseExpiry())
×
5123
        }
×
5124

5125
        log.Infof("Starting funding workflow with %v for pending_id(%x), "+
55✔
5126
                "committype=%v", msg.Peer.Address(), chanID, commitType)
55✔
5127

55✔
5128
        reservation.SetState(lnwallet.SentOpenChannel)
55✔
5129

55✔
5130
        fundingOpen := lnwire.OpenChannel{
55✔
5131
                ChainHash:             *f.cfg.Wallet.Cfg.NetParams.GenesisHash,
55✔
5132
                PendingChannelID:      chanID,
55✔
5133
                FundingAmount:         capacity,
55✔
5134
                PushAmount:            msg.PushAmt,
55✔
5135
                DustLimit:             ourDustLimit,
55✔
5136
                MaxValueInFlight:      maxValue,
55✔
5137
                ChannelReserve:        chanReserve,
55✔
5138
                HtlcMinimum:           minHtlcIn,
55✔
5139
                FeePerKiloWeight:      uint32(commitFeePerKw),
55✔
5140
                CsvDelay:              remoteCsvDelay,
55✔
5141
                MaxAcceptedHTLCs:      maxHtlcs,
55✔
5142
                FundingKey:            ourContribution.MultiSigKey.PubKey,
55✔
5143
                RevocationPoint:       ourContribution.RevocationBasePoint.PubKey,
55✔
5144
                PaymentPoint:          ourContribution.PaymentBasePoint.PubKey,
55✔
5145
                HtlcPoint:             ourContribution.HtlcBasePoint.PubKey,
55✔
5146
                DelayedPaymentPoint:   ourContribution.DelayBasePoint.PubKey,
55✔
5147
                FirstCommitmentPoint:  ourContribution.FirstCommitmentPoint,
55✔
5148
                ChannelFlags:          channelFlags,
55✔
5149
                UpfrontShutdownScript: shutdown,
55✔
5150
                ChannelType:           chanType,
55✔
5151
                LeaseExpiry:           leaseExpiry,
55✔
5152
        }
55✔
5153

55✔
5154
        if commitType.IsTaproot() {
57✔
5155
                fundingOpen.LocalNonce = lnwire.SomeMusig2Nonce(
2✔
5156
                        ourContribution.LocalNonce.PubNonce,
2✔
5157
                )
2✔
5158
        }
2✔
5159

5160
        if err := msg.Peer.SendMessage(true, &fundingOpen); err != nil {
55✔
5161
                e := fmt.Errorf("unable to send funding request message: %w",
×
5162
                        err)
×
5163
                log.Errorf(e.Error())
×
5164

×
5165
                // Since we were unable to send the initial message to the peer
×
5166
                // and start the funding flow, we'll cancel this reservation.
×
5167
                _, err := f.cancelReservationCtx(peerKey, chanID, false)
×
5168
                if err != nil {
×
5169
                        log.Errorf("unable to cancel reservation: %v", err)
×
5170
                }
×
5171

5172
                msg.Err <- e
×
5173
                return
×
5174
        }
5175
}
5176

5177
// handleWarningMsg processes the warning which was received from remote peer.
5178
func (f *Manager) handleWarningMsg(peer lnpeer.Peer, msg *lnwire.Warning) {
44✔
5179
        log.Warnf("received warning message from peer %x: %v",
44✔
5180
                peer.IdentityKey().SerializeCompressed(), msg.Warning())
44✔
5181
}
44✔
5182

5183
// handleErrorMsg processes the error which was received from remote peer,
5184
// depending on the type of error we should do different clean up steps and
5185
// inform the user about it.
5186
func (f *Manager) handleErrorMsg(peer lnpeer.Peer, msg *lnwire.Error) {
×
5187
        chanID := msg.ChanID
×
5188
        peerKey := peer.IdentityKey()
×
5189

×
5190
        // First, we'll attempt to retrieve and cancel the funding workflow
×
5191
        // that this error was tied to. If we're unable to do so, then we'll
×
5192
        // exit early as this was an unwarranted error.
×
5193
        resCtx, err := f.cancelReservationCtx(peerKey, chanID, true)
×
5194
        if err != nil {
×
5195
                log.Warnf("Received error for non-existent funding "+
×
5196
                        "flow: %v (%v)", err, msg.Error())
×
5197
                return
×
5198
        }
×
5199

5200
        // If we did indeed find the funding workflow, then we'll return the
5201
        // error back to the caller (if any), and cancel the workflow itself.
5202
        fundingErr := fmt.Errorf("received funding error from %x: %v",
×
5203
                peerKey.SerializeCompressed(), msg.Error(),
×
5204
        )
×
5205
        log.Errorf(fundingErr.Error())
×
5206

×
5207
        // If this was a PSBT funding flow, the remote likely timed out because
×
5208
        // we waited too long. Return a nice error message to the user in that
×
5209
        // case so the user knows what's the problem.
×
5210
        if resCtx.reservation.IsPsbt() {
×
5211
                fundingErr = fmt.Errorf("%w: %v", chanfunding.ErrRemoteCanceled,
×
5212
                        fundingErr)
×
5213
        }
×
5214

5215
        resCtx.err <- fundingErr
×
5216
}
5217

5218
// pruneZombieReservations loops through all pending reservations and fails the
5219
// funding flow for any reservations that have not been updated since the
5220
// ReservationTimeout and are not locked waiting for the funding transaction.
5221
func (f *Manager) pruneZombieReservations() {
3✔
5222
        zombieReservations := make(pendingChannels)
3✔
5223

3✔
5224
        f.resMtx.RLock()
3✔
5225
        for _, pendingReservations := range f.activeReservations {
6✔
5226
                for pendingChanID, resCtx := range pendingReservations {
6✔
5227
                        if resCtx.isLocked() {
3✔
5228
                                continue
×
5229
                        }
5230

5231
                        // We don't want to expire PSBT funding reservations.
5232
                        // These reservations are always initiated by us and the
5233
                        // remote peer is likely going to cancel them after some
5234
                        // idle time anyway. So no need for us to also prune
5235
                        // them.
5236
                        sinceLastUpdate := time.Since(resCtx.lastUpdated)
3✔
5237
                        isExpired := sinceLastUpdate > f.cfg.ReservationTimeout
3✔
5238
                        if !resCtx.reservation.IsPsbt() && isExpired {
6✔
5239
                                zombieReservations[pendingChanID] = resCtx
3✔
5240
                        }
3✔
5241
                }
5242
        }
5243
        f.resMtx.RUnlock()
3✔
5244

3✔
5245
        for pendingChanID, resCtx := range zombieReservations {
6✔
5246
                err := fmt.Errorf("reservation timed out waiting for peer "+
3✔
5247
                        "(peer_id:%x, chan_id:%x)",
3✔
5248
                        resCtx.peer.IdentityKey().SerializeCompressed(),
3✔
5249
                        pendingChanID[:])
3✔
5250
                log.Warnf(err.Error())
3✔
5251

3✔
5252
                chanID := lnwire.NewChanIDFromOutPoint(
3✔
5253
                        *resCtx.reservation.FundingOutpoint(),
3✔
5254
                )
3✔
5255

3✔
5256
                // Create channel identifier and set the channel ID.
3✔
5257
                cid := newChanIdentifier(pendingChanID)
3✔
5258
                cid.setChanID(chanID)
3✔
5259

3✔
5260
                f.failFundingFlow(resCtx.peer, cid, err)
3✔
5261
        }
3✔
5262
}
5263

5264
// cancelReservationCtx does all needed work in order to securely cancel the
5265
// reservation.
5266
func (f *Manager) cancelReservationCtx(peerKey *btcec.PublicKey,
5267
        pendingChanID PendingChanID,
5268
        byRemote bool) (*reservationWithCtx, error) {
23✔
5269

23✔
5270
        log.Infof("Cancelling funding reservation for node_key=%x, "+
23✔
5271
                "chan_id=%x", peerKey.SerializeCompressed(), pendingChanID[:])
23✔
5272

23✔
5273
        peerIDKey := newSerializedKey(peerKey)
23✔
5274
        f.resMtx.Lock()
23✔
5275
        defer f.resMtx.Unlock()
23✔
5276

23✔
5277
        nodeReservations, ok := f.activeReservations[peerIDKey]
23✔
5278
        if !ok {
30✔
5279
                // No reservations for this node.
7✔
5280
                return nil, fmt.Errorf("no active reservations for peer(%x)",
7✔
5281
                        peerIDKey[:])
7✔
5282
        }
7✔
5283

5284
        ctx, ok := nodeReservations[pendingChanID]
16✔
5285
        if !ok {
18✔
5286
                return nil, fmt.Errorf("unknown channel (id: %x) for "+
2✔
5287
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
2✔
5288
        }
2✔
5289

5290
        // If the reservation was a PSBT funding flow and it was canceled by the
5291
        // remote peer, then we need to thread through a different error message
5292
        // to the subroutine that's waiting for the user input so it can return
5293
        // a nice error message to the user.
5294
        if ctx.reservation.IsPsbt() && byRemote {
14✔
5295
                ctx.reservation.RemoteCanceled()
×
5296
        }
×
5297

5298
        if err := ctx.reservation.Cancel(); err != nil {
14✔
5299
                return nil, fmt.Errorf("unable to cancel reservation: %w", err)
×
5300
        }
×
5301

5302
        delete(nodeReservations, pendingChanID)
14✔
5303

14✔
5304
        // If this was the last active reservation for this peer, delete the
14✔
5305
        // peer's entry altogether.
14✔
5306
        if len(nodeReservations) == 0 {
28✔
5307
                delete(f.activeReservations, peerIDKey)
14✔
5308
        }
14✔
5309
        return ctx, nil
14✔
5310
}
5311

5312
// deleteReservationCtx deletes the reservation uniquely identified by the
5313
// target public key of the peer, and the specified pending channel ID.
5314
func (f *Manager) deleteReservationCtx(peerKey *btcec.PublicKey,
5315
        pendingChanID PendingChanID) {
56✔
5316

56✔
5317
        peerIDKey := newSerializedKey(peerKey)
56✔
5318
        f.resMtx.Lock()
56✔
5319
        defer f.resMtx.Unlock()
56✔
5320

56✔
5321
        nodeReservations, ok := f.activeReservations[peerIDKey]
56✔
5322
        if !ok {
56✔
5323
                // No reservations for this node.
×
5324
                return
×
5325
        }
×
5326
        delete(nodeReservations, pendingChanID)
56✔
5327

56✔
5328
        // If this was the last active reservation for this peer, delete the
56✔
5329
        // peer's entry altogether.
56✔
5330
        if len(nodeReservations) == 0 {
105✔
5331
                delete(f.activeReservations, peerIDKey)
49✔
5332
        }
49✔
5333
}
5334

5335
// getReservationCtx returns the reservation context for a particular pending
5336
// channel ID for a target peer.
5337
func (f *Manager) getReservationCtx(peerKey *btcec.PublicKey,
5338
        pendingChanID PendingChanID) (*reservationWithCtx, error) {
91✔
5339

91✔
5340
        peerIDKey := newSerializedKey(peerKey)
91✔
5341
        f.resMtx.RLock()
91✔
5342
        resCtx, ok := f.activeReservations[peerIDKey][pendingChanID]
91✔
5343
        f.resMtx.RUnlock()
91✔
5344

91✔
5345
        if !ok {
91✔
5346
                return nil, fmt.Errorf("unknown channel (id: %x) for "+
×
5347
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
×
5348
        }
×
5349

5350
        return resCtx, nil
91✔
5351
}
5352

5353
// IsPendingChannel returns a boolean indicating whether the channel identified
5354
// by the pendingChanID and given peer is pending, meaning it is in the process
5355
// of being funded. After the funding transaction has been confirmed, the
5356
// channel will receive a new, permanent channel ID, and will no longer be
5357
// considered pending.
5358
func (f *Manager) IsPendingChannel(pendingChanID PendingChanID,
5359
        peer lnpeer.Peer) bool {
×
5360

×
5361
        peerIDKey := newSerializedKey(peer.IdentityKey())
×
5362
        f.resMtx.RLock()
×
5363
        _, ok := f.activeReservations[peerIDKey][pendingChanID]
×
5364
        f.resMtx.RUnlock()
×
5365

×
5366
        return ok
×
5367
}
×
5368

5369
func copyPubKey(pub *btcec.PublicKey) *btcec.PublicKey {
385✔
5370
        var tmp btcec.JacobianPoint
385✔
5371
        pub.AsJacobian(&tmp)
385✔
5372
        tmp.ToAffine()
385✔
5373
        return btcec.NewPublicKey(&tmp.X, &tmp.Y)
385✔
5374
}
385✔
5375

5376
// defaultForwardingPolicy returns the default forwarding policy based on the
5377
// default routing policy and our local channel constraints.
5378
func (f *Manager) defaultForwardingPolicy(
5379
        bounds channeldb.ChannelStateBounds) *models.ForwardingPolicy {
104✔
5380

104✔
5381
        return &models.ForwardingPolicy{
104✔
5382
                MinHTLCOut:    bounds.MinHTLC,
104✔
5383
                MaxHTLC:       bounds.MaxPendingAmount,
104✔
5384
                BaseFee:       f.cfg.DefaultRoutingPolicy.BaseFee,
104✔
5385
                FeeRate:       f.cfg.DefaultRoutingPolicy.FeeRate,
104✔
5386
                TimeLockDelta: f.cfg.DefaultRoutingPolicy.TimeLockDelta,
104✔
5387
        }
104✔
5388
}
104✔
5389

5390
// saveInitialForwardingPolicy saves the forwarding policy for the provided
5391
// chanPoint in the channelOpeningStateBucket.
5392
func (f *Manager) saveInitialForwardingPolicy(chanID lnwire.ChannelID,
5393
        forwardingPolicy *models.ForwardingPolicy) error {
69✔
5394

69✔
5395
        return f.cfg.ChannelDB.SaveInitialForwardingPolicy(
69✔
5396
                chanID, forwardingPolicy,
69✔
5397
        )
69✔
5398
}
69✔
5399

5400
// getInitialForwardingPolicy fetches the initial forwarding policy for a given
5401
// channel id from the database which will be applied during the channel
5402
// announcement phase.
5403
func (f *Manager) getInitialForwardingPolicy(
5404
        chanID lnwire.ChannelID) (*models.ForwardingPolicy, error) {
94✔
5405

94✔
5406
        return f.cfg.ChannelDB.GetInitialForwardingPolicy(chanID)
94✔
5407
}
94✔
5408

5409
// deleteInitialForwardingPolicy removes channel fees for this chanID from
5410
// the database.
5411
func (f *Manager) deleteInitialForwardingPolicy(chanID lnwire.ChannelID) error {
24✔
5412
        return f.cfg.ChannelDB.DeleteInitialForwardingPolicy(chanID)
24✔
5413
}
24✔
5414

5415
// saveChannelOpeningState saves the channelOpeningState for the provided
5416
// chanPoint to the channelOpeningStateBucket.
5417
func (f *Manager) saveChannelOpeningState(chanPoint *wire.OutPoint,
5418
        state channelOpeningState, shortChanID *lnwire.ShortChannelID) error {
92✔
5419

92✔
5420
        var outpointBytes bytes.Buffer
92✔
5421
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
92✔
5422
                return err
×
5423
        }
×
5424

5425
        // Save state and the uint64 representation of the shortChanID
5426
        // for later use.
5427
        scratch := make([]byte, 10)
92✔
5428
        byteOrder.PutUint16(scratch[:2], uint16(state))
92✔
5429
        byteOrder.PutUint64(scratch[2:], shortChanID.ToUint64())
92✔
5430

92✔
5431
        return f.cfg.ChannelDB.SaveChannelOpeningState(
92✔
5432
                outpointBytes.Bytes(), scratch,
92✔
5433
        )
92✔
5434
}
5435

5436
// getChannelOpeningState fetches the channelOpeningState for the provided
5437
// chanPoint from the database, or returns ErrChannelNotFound if the channel
5438
// is not found.
5439
func (f *Manager) getChannelOpeningState(chanPoint *wire.OutPoint) (
5440
        channelOpeningState, *lnwire.ShortChannelID, error) {
254✔
5441

254✔
5442
        var outpointBytes bytes.Buffer
254✔
5443
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
254✔
5444
                return 0, nil, err
×
5445
        }
×
5446

5447
        value, err := f.cfg.ChannelDB.GetChannelOpeningState(
254✔
5448
                outpointBytes.Bytes(),
254✔
5449
        )
254✔
5450
        if err != nil {
303✔
5451
                return 0, nil, err
49✔
5452
        }
49✔
5453

5454
        state := channelOpeningState(byteOrder.Uint16(value[:2]))
205✔
5455
        shortChanID := lnwire.NewShortChanIDFromInt(byteOrder.Uint64(value[2:]))
205✔
5456
        return state, &shortChanID, nil
205✔
5457
}
5458

5459
// deleteChannelOpeningState removes any state for chanPoint from the database.
5460
func (f *Manager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error {
24✔
5461
        var outpointBytes bytes.Buffer
24✔
5462
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
24✔
5463
                return err
×
5464
        }
×
5465

5466
        return f.cfg.ChannelDB.DeleteChannelOpeningState(
24✔
5467
                outpointBytes.Bytes(),
24✔
5468
        )
24✔
5469
}
5470

5471
// selectShutdownScript selects the shutdown script we should send to the peer.
5472
// If we can use taproot, then we prefer that, otherwise we'll use a p2wkh
5473
// script.
5474
func (f *Manager) selectShutdownScript(taprootOK bool,
5475
) (lnwire.DeliveryAddress, error) {
×
5476

×
5477
        addrType := lnwallet.WitnessPubKey
×
5478
        if taprootOK {
×
5479
                addrType = lnwallet.TaprootPubkey
×
5480
        }
×
5481

5482
        addr, err := f.cfg.Wallet.NewAddress(
×
5483
                addrType, false, lnwallet.DefaultAccountName,
×
5484
        )
×
5485
        if err != nil {
×
5486
                return nil, err
×
5487
        }
×
5488

5489
        return txscript.PayToAddrScript(addr)
×
5490
}
5491

5492
// waitForPeerOnline blocks until the peer specified by peerPubkey comes online
5493
// and then returns the online peer.
5494
func (f *Manager) waitForPeerOnline(peerPubkey *btcec.PublicKey) (lnpeer.Peer,
5495
        error) {
105✔
5496

105✔
5497
        peerChan := make(chan lnpeer.Peer, 1)
105✔
5498

105✔
5499
        var peerKey [33]byte
105✔
5500
        copy(peerKey[:], peerPubkey.SerializeCompressed())
105✔
5501

105✔
5502
        f.cfg.NotifyWhenOnline(peerKey, peerChan)
105✔
5503

105✔
5504
        var peer lnpeer.Peer
105✔
5505
        select {
105✔
5506
        case peer = <-peerChan:
104✔
5507
        case <-f.quit:
1✔
5508
                return peer, ErrFundingManagerShuttingDown
1✔
5509
        }
5510
        return peer, nil
104✔
5511
}
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