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

lightningnetwork / lnd / 13572832752

25 Feb 2025 05:33AM UTC coverage: 49.404% (-9.4%) from 58.77%
13572832752

Pull #9562

github

NishantBansal2003
"multi: Add itest for funding timeout"

This commit adds an integration test that
verifies the funding timeout behavior in the
funding manager, in dev/integration test.

Signed-off-by: Nishant Bansal <nishant.bansal.282003@gmail.com>
Pull Request #9562: Make MaxWaitNumBlocksFundingConf Configurable for itest

29 of 31 new or added lines in 4 files covered. (93.55%)

27211 existing lines in 434 files now uncovered.

101066 of 204570 relevant lines covered (49.4%)

1.54 hits per line

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

71.88
/funding/manager.go
1
package funding
2

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

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

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

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

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

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

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

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

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

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

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

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

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

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

103
        msgBufferSize = 50
104

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

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

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

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

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

135
        zeroID [32]byte
136
)
137

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

151
        chanAmt btcutil.Amount
152

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

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

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

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

170
        updateMtx   sync.RWMutex
171
        lastUpdated time.Time
172

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

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

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

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

3✔
192
        r.lastUpdated = time.Now()
3✔
193
}
3✔
194

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

344
        // MaxWaitNumBlocksFundingConf is the maximum number of blocks
345
        // to wait for the funding transaction to be confirmed before forgetting
346
        // channels that aren't initiated by us.
347
        MaxWaitNumBlocksFundingConf int
348
}
349

350
// Config defines the configuration for the FundingManager. All elements
351
// within the configuration MUST be non-nil for the FundingManager to carry out
352
// its duties.
353
type Config struct {
354
        // Dev specifies config values used in integration test. For
355
        // production, this config will always be an empty struct.
356
        Dev *DevConfig
357

358
        // NoWumboChans indicates if we're to reject all incoming wumbo channel
359
        // requests, and also reject all outgoing wumbo channel requests.
360
        NoWumboChans bool
361

362
        // IDKey is the PublicKey that is used to identify this node within the
363
        // Lightning Network.
364
        IDKey *btcec.PublicKey
365

366
        // IDKeyLoc is the locator for the key that is used to identify this
367
        // node within the LightningNetwork.
368
        IDKeyLoc keychain.KeyLocator
369

370
        // Wallet handles the parts of the funding process that involves moving
371
        // funds from on-chain transaction outputs into Lightning channels.
372
        Wallet *lnwallet.LightningWallet
373

374
        // PublishTransaction facilitates the process of broadcasting a
375
        // transaction to the network.
376
        PublishTransaction func(*wire.MsgTx, string) error
377

378
        // UpdateLabel updates the label that a transaction has in our wallet,
379
        // overwriting any existing labels.
380
        UpdateLabel func(chainhash.Hash, string) error
381

382
        // FeeEstimator calculates appropriate fee rates based on historical
383
        // transaction information.
384
        FeeEstimator chainfee.Estimator
385

386
        // Notifier is used by the FundingManager to determine when the
387
        // channel's funding transaction has been confirmed on the blockchain
388
        // so that the channel creation process can be completed.
389
        Notifier chainntnfs.ChainNotifier
390

391
        // ChannelDB is the database that keeps track of all channel state.
392
        ChannelDB *channeldb.ChannelStateDB
393

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

404
        // CurrentNodeAnnouncement should return the latest, fully signed node
405
        // announcement from the backing Lightning Network node with a fresh
406
        // timestamp.
407
        CurrentNodeAnnouncement func() (lnwire.NodeAnnouncement, error)
408

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

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

425
        // FindChannel queries the database for the channel with the given
426
        // channel ID. Providing the node's public key is an optimization that
427
        // prevents deserializing and scanning through all possible channels.
428
        FindChannel func(node *btcec.PublicKey,
429
                chanID lnwire.ChannelID) (*channeldb.OpenChannel, error)
430

431
        // TempChanIDSeed is a cryptographically random string of bytes that's
432
        // used as a seed to generate pending channel ID's.
433
        TempChanIDSeed [32]byte
434

435
        // DefaultRoutingPolicy is the default routing policy used when
436
        // initially announcing channels.
437
        DefaultRoutingPolicy models.ForwardingPolicy
438

439
        // DefaultMinHtlcIn is the default minimum incoming htlc value that is
440
        // set as a channel parameter.
441
        DefaultMinHtlcIn lnwire.MilliSatoshi
442

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

450
        // RequiredRemoteDelay is a function that maps the total amount in a
451
        // proposed channel to the CSV delay that we'll require for the remote
452
        // party. Naturally a larger channel should require a higher CSV delay
453
        // in order to give us more time to claim funds in the case of a
454
        // contract breach.
455
        RequiredRemoteDelay func(btcutil.Amount) uint16
456

457
        // RequiredRemoteChanReserve is a function closure that, given the
458
        // channel capacity and dust limit, will return an appropriate amount
459
        // for the remote peer's required channel reserve that is to be adhered
460
        // to at all times.
461
        RequiredRemoteChanReserve func(capacity,
462
                dustLimit btcutil.Amount) btcutil.Amount
463

464
        // RequiredRemoteMaxValue is a function closure that, given the channel
465
        // capacity, returns the amount of MilliSatoshis that our remote peer
466
        // can have in total outstanding HTLCs with us.
467
        RequiredRemoteMaxValue func(btcutil.Amount) lnwire.MilliSatoshi
468

469
        // RequiredRemoteMaxHTLCs is a function closure that, given the channel
470
        // capacity, returns the number of maximum HTLCs the remote peer can
471
        // offer us.
472
        RequiredRemoteMaxHTLCs func(btcutil.Amount) uint16
473

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

481
        // ReportShortChanID allows the funding manager to report the confirmed
482
        // short channel ID of a formerly pending zero-conf channel to outside
483
        // sub-systems.
484
        ReportShortChanID func(wire.OutPoint) error
485

486
        // ZombieSweeperInterval is the periodic time interval in which the
487
        // zombie sweeper is run.
488
        ZombieSweeperInterval time.Duration
489

490
        // ReservationTimeout is the length of idle time that must pass before
491
        // a reservation is considered a zombie.
492
        ReservationTimeout time.Duration
493

494
        // MinChanSize is the smallest channel size that we'll accept as an
495
        // inbound channel. We have such a parameter, as otherwise, nodes could
496
        // flood us with very small channels that would never really be usable
497
        // due to fees.
498
        MinChanSize btcutil.Amount
499

500
        // MaxChanSize is the largest channel size that we'll accept as an
501
        // inbound channel. We have such a parameter, so that you may decide how
502
        // WUMBO you would like your channel.
503
        MaxChanSize btcutil.Amount
504

505
        // MaxPendingChannels is the maximum number of pending channels we
506
        // allow for each peer.
507
        MaxPendingChannels int
508

509
        // RejectPush is set true if the fundingmanager should reject any
510
        // incoming channels having a non-zero push amount.
511
        RejectPush bool
512

513
        // MaxLocalCSVDelay is the maximum csv delay we will allow for our
514
        // commit output. Channels that exceed this value will be failed.
515
        MaxLocalCSVDelay uint16
516

517
        // NotifyOpenChannelEvent informs the ChannelNotifier when channels
518
        // transition from pending open to open.
519
        NotifyOpenChannelEvent func(wire.OutPoint)
520

521
        // OpenChannelPredicate is a predicate on the lnwire.OpenChannel message
522
        // and on the requesting node's public key that returns a bool which
523
        // tells the funding manager whether or not to accept the channel.
524
        OpenChannelPredicate chanacceptor.ChannelAcceptor
525

526
        // NotifyPendingOpenChannelEvent informs the ChannelNotifier when
527
        // channels enter a pending state.
528
        NotifyPendingOpenChannelEvent func(wire.OutPoint,
529
                *channeldb.OpenChannel)
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 {
3✔
667
        switch c {
3✔
668
        case markedOpen:
3✔
669
                return "markedOpen"
3✔
670
        case channelReadySent:
3✔
671
                return "channelReadySent"
3✔
672
        case addedToGraph:
3✔
673
                return "addedToGraph"
3✔
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) {
3✔
682
        return &Manager{
3✔
683
                cfg:       &cfg,
3✔
684
                chanIDKey: cfg.TempChanIDSeed,
3✔
685
                activeReservations: make(
3✔
686
                        map[serializedPubKey]pendingChannels,
3✔
687
                ),
3✔
688
                signedReservations: make(
3✔
689
                        map[lnwire.ChannelID][32]byte,
3✔
690
                ),
3✔
691
                fundingMsgs: make(
3✔
692
                        chan *fundingMsg, msgBufferSize,
3✔
693
                ),
3✔
694
                fundingRequests: make(
3✔
695
                        chan *InitFundingMsg, msgBufferSize,
3✔
696
                ),
3✔
697
                localDiscoverySignals: &lnutils.SyncMap[
3✔
698
                        lnwire.ChannelID, chan struct{},
3✔
699
                ]{},
3✔
700
                handleChannelReadyBarriers: &lnutils.SyncMap[
3✔
701
                        lnwire.ChannelID, struct{},
3✔
702
                ]{},
3✔
703
                pendingMusigNonces: make(
3✔
704
                        map[lnwire.ChannelID]*musig2.Nonces,
3✔
705
                ),
3✔
706
                quit: make(chan struct{}),
3✔
707
        }, nil
3✔
708
}
3✔
709

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

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

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

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

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

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

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

×
UNCOV
764
                        // Rebroadcast the funding transaction for unconfirmed
×
UNCOV
765
                        // zero-conf channels if we have the funding tx and are
×
UNCOV
766
                        // also the initiator.
×
UNCOV
767
                        f.rebroadcastFundingTx(channel)
×
UNCOV
768
                }
×
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)
3✔
775
                go f.advanceFundingState(channel, chanID, nil)
3✔
776
        }
777

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

3✔
781
        return nil
3✔
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 {
3✔
787
        f.stopped.Do(func() {
6✔
788
                log.Info("Funding manager shutting down...")
3✔
789
                defer log.Debug("Funding manager shutdown complete")
3✔
790

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

795
        return nil
3✔
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 {
3✔
835
        // Obtain a fresh nonce. We do this by encoding the incremented nonce.
3✔
836
        nextNonce := f.chanIDNonce.Add(1)
3✔
837

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

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

3✔
851
        return nextChanID
3✔
852
}
3✔
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) {
3✔
858
        log.Debugf("Cancelling all reservations for peer %x", nodePub[:])
3✔
859

3✔
860
        f.resMtx.Lock()
3✔
861
        defer f.resMtx.Unlock()
3✔
862

3✔
863
        // We'll attempt to look up this node in the set of active
3✔
864
        // reservations.  If they don't have any, then there's no further work
3✔
865
        // to be done.
3✔
866
        nodeReservations, ok := f.activeReservations[nodePub]
3✔
867
        if !ok {
6✔
868
                log.Debugf("No active reservations for node: %x", nodePub[:])
3✔
869
                return
3✔
870
        }
3✔
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 {
3✔
915
        return &chanIdentifier{
3✔
916
                tempChanID: tempChanID,
3✔
917
        }
3✔
918
}
3✔
919

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

926
// hasChanID returns true if the active channel ID has been set.
927
func (c *chanIdentifier) hasChanID() bool {
3✔
928
        return c.chanIDSet
3✔
929
}
3✔
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) {
3✔
940

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

3✔
944
        // First, notify Brontide to remove the pending channel.
3✔
945
        //
3✔
946
        // NOTE: depending on where we fail the flow, we may not have the
3✔
947
        // active channel ID yet.
3✔
948
        if cid.hasChanID() {
6✔
949
                err := peer.RemovePendingChannel(cid.chanID)
3✔
950
                if err != nil {
3✔
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(
3✔
958
                peer.IdentityKey(), cid.tempChanID, false,
3✔
959
        )
3✔
960
        if err != nil {
6✔
961
                log.Errorf("unable to cancel reservation: %v", err)
3✔
962
        }
3✔
963

964
        // In case the case where the reservation existed, send the funding
965
        // error on the error channel.
966
        if ctx != nil {
6✔
967
                ctx.err <- fundingErr
3✔
968
        }
3✔
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
3✔
973
        switch e := fundingErr.(type) {
3✔
974
        // Let the actual error message be sent to the remote for the
975
        // whitelisted types.
976
        case lnwallet.ReservationError:
3✔
977
                msg = lnwire.ErrorData(e.Error())
3✔
978
        case lnwire.FundingError:
3✔
979
                msg = lnwire.ErrorData(e.Error())
3✔
980
        case chanacceptor.ChanAcceptError:
3✔
981
                msg = lnwire.ErrorData(e.Error())
3✔
982

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

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

3✔
993
        log.Debugf("Sending funding error to peer (%x): %v",
3✔
994
                peer.IdentityKey().SerializeCompressed(), spew.Sdump(errMsg))
3✔
995
        if err := peer.SendMessage(false, errMsg); err != nil {
3✔
UNCOV
996
                log.Errorf("unable to send error message to peer %v", err)
×
UNCOV
997
        }
×
998
}
999

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

×
1005
        msg := fundingErr.Error()
×
1006

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

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

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

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

3✔
1029
        zombieSweepTicker := time.NewTicker(f.cfg.ZombieSweeperInterval)
3✔
1030
        defer zombieSweepTicker.Stop()
3✔
1031

3✔
1032
        for {
6✔
1033
                select {
3✔
1034
                case fmsg := <-f.fundingMsgs:
3✔
1035
                        switch msg := fmsg.msg.(type) {
3✔
1036
                        case *lnwire.OpenChannel:
3✔
1037
                                f.fundeeProcessOpenChannel(fmsg.peer, msg)
3✔
1038

1039
                        case *lnwire.AcceptChannel:
3✔
1040
                                f.funderProcessAcceptChannel(fmsg.peer, msg)
3✔
1041

1042
                        case *lnwire.FundingCreated:
3✔
1043
                                f.fundeeProcessFundingCreated(fmsg.peer, msg)
3✔
1044

1045
                        case *lnwire.FundingSigned:
3✔
1046
                                f.funderProcessFundingSigned(fmsg.peer, msg)
3✔
1047

1048
                        case *lnwire.ChannelReady:
3✔
1049
                                f.wg.Add(1)
3✔
1050
                                go f.handleChannelReady(fmsg.peer, msg)
3✔
1051

UNCOV
1052
                        case *lnwire.Warning:
×
UNCOV
1053
                                f.handleWarningMsg(fmsg.peer, msg)
×
1054

1055
                        case *lnwire.Error:
3✔
1056
                                f.handleErrorMsg(fmsg.peer, msg)
3✔
1057
                        }
1058
                case req := <-f.fundingRequests:
3✔
1059
                        f.handleInitFundingMsg(req)
3✔
1060

1061
                case <-zombieSweepTicker.C:
3✔
1062
                        f.pruneZombieReservations()
3✔
1063

1064
                case <-f.quit:
3✔
1065
                        return
3✔
1066
                }
1067
        }
1068
}
1069

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

3✔
1082
        defer f.wg.Done()
3✔
1083

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

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

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

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

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

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

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

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

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

1192
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
3✔
1193
                        "sent ChannelReady", chanID, shortChanID)
3✔
1194

3✔
1195
                return nil
3✔
1196

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

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

1220
                        return nil
3✔
1221
                }
1222

1223
                return f.handleChannelReadyReceived(
3✔
1224
                        channel, shortChanID, pendingChanID, updateChan,
3✔
1225
                )
3✔
1226

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

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

1246
                err := f.annAfterSixConfs(channel, shortChanID)
3✔
1247
                if err != nil {
6✔
1248
                        return fmt.Errorf("error sending channel "+
3✔
1249
                                "announcement: %v", err)
3✔
1250
                }
3✔
1251

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

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

1273
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
3✔
1274
                        "announced", chanID, shortChanID)
3✔
1275

3✔
1276
                return nil
3✔
1277
        }
1278

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

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

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

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

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

1319
                // Inform the ChannelNotifier that the channel has transitioned
1320
                // from pending open to open.
1321
                f.cfg.NotifyOpenChannelEvent(channel.FundingOutpoint)
3✔
1322

3✔
1323
                // Find and close the discoverySignal for this channel such
3✔
1324
                // that ChannelReady messages will be processed.
3✔
1325
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
3✔
1326
                discoverySignal, ok := f.localDiscoverySignals.Load(chanID)
3✔
1327
                if ok {
6✔
1328
                        close(discoverySignal)
3✔
1329
                }
3✔
1330

1331
                return nil
3✔
1332
        }
1333

1334
        confChannel, err := f.waitForFundingWithTimeout(channel)
3✔
1335
        if err == ErrConfirmationTimeout {
6✔
1336
                return f.fundingTimeout(channel, pendingChanID)
3✔
1337
        } else if err != nil {
9✔
1338
                return fmt.Errorf("error waiting for funding "+
3✔
1339
                        "confirmation for ChannelPoint(%v): %v",
3✔
1340
                        channel.FundingOutpoint, err)
3✔
1341
        }
3✔
1342

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

×
UNCOV
1350
                if channel.NumConfsRequired > maturity {
×
1351
                        numCoinbaseConfs = uint32(channel.NumConfsRequired)
×
1352
                }
×
1353

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

×
1361
                        return err
×
1362
                }
×
1363

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

×
1373
                        return err
×
1374
                }
×
1375

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

1385
                case <-f.quit:
×
1386
                        return ErrFundingManagerShuttingDown
×
1387
                }
1388
        }
1389

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

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

1402
        return nil
3✔
1403
}
1404

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

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

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

3✔
1432
        amt := msg.FundingAmount
3✔
1433

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

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

3✔
1450
        // Create the channel identifier.
3✔
1451
        cid := newChanIdentifier(msg.PendingChannelID)
3✔
1452

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

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

1473
        // TODO(roasbeef): modify to only accept a _single_ pending channel per
1474
        // block unless white listed
1475
        if numPending >= f.cfg.MaxPendingChannels {
6✔
1476
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
3✔
1477

3✔
1478
                return
3✔
1479
        }
3✔
1480

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

1488
        if len(pendingChans) > pendingChansLimit {
3✔
1489
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
×
1490
                return
×
1491
        }
×
1492

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

1506
        // Ensure that the remote party respects our maximum channel size.
1507
        if amt > f.cfg.MaxChanSize {
6✔
1508
                f.failFundingFlow(
3✔
1509
                        peer, cid,
3✔
1510
                        lnwallet.ErrChanTooLarge(amt, f.cfg.MaxChanSize),
3✔
1511
                )
3✔
1512
                return
3✔
1513
        }
3✔
1514

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

1525
        // If request specifies non-zero push amount and 'rejectpush' is set,
1526
        // signal an error.
1527
        if f.cfg.RejectPush && msg.PushAmount > 0 {
3✔
UNCOV
1528
                f.failFundingFlow(peer, cid, lnwallet.ErrNonZeroPushAmount())
×
UNCOV
1529
                return
×
UNCOV
1530
        }
×
1531

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

3✔
1539
        // Query our channel acceptor to determine whether we should reject
3✔
1540
        // the channel.
3✔
1541
        acceptorResp := f.cfg.OpenChannelPredicate.Accept(chanReq)
3✔
1542
        if acceptorResp.RejectChannel() {
6✔
1543
                f.failFundingFlow(peer, cid, acceptorResp.ChanAcceptError)
3✔
1544
                return
3✔
1545
        }
3✔
1546

1547
        log.Infof("Recv'd fundingRequest(amt=%v, push=%v, delay=%v, "+
3✔
1548
                "pendingId=%x) from peer(%x)", amt, msg.PushAmount,
3✔
1549
                msg.CsvDelay, msg.PendingChannelID,
3✔
1550
                peer.IdentityKey().SerializeCompressed())
3✔
1551

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

1573
        var scidFeatureVal bool
3✔
1574
        if hasFeatures(
3✔
1575
                peer.LocalFeatures(), peer.RemoteFeatures(),
3✔
1576
                lnwire.ScidAliasOptional,
3✔
1577
        ) {
6✔
1578

3✔
1579
                scidFeatureVal = true
3✔
1580
        }
3✔
1581

1582
        var (
3✔
1583
                zeroConf bool
3✔
1584
                scid     bool
3✔
1585
        )
3✔
1586

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

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

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

1625
                        // Set zeroConf to true to enable the zero-conf flow.
1626
                        zeroConf = true
×
1627
                }
1628
        }
1629

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

×
1641
                return
×
1642

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

×
1651
                return
×
1652
        }
1653

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

×
1668
                return
×
1669
        }
×
1670

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

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

1697
        log.Debugf("Initialized channel reservation: zeroConf=%v, psbt=%v, "+
3✔
1698
                "cannedShim=%v", reservation.IsZeroConf(),
3✔
1699
                reservation.IsPsbt(), reservation.IsCannedShim())
3✔
1700

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

1711
                reservation.AddAlias(aliasScid)
3✔
1712
        }
1713

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

1725
        // We'll ignore the min_depth calculated above if this is a zero-conf
1726
        // channel.
1727
        if zeroConf {
6✔
1728
                numConfsReq = 0
3✔
1729
        }
3✔
1730

1731
        reservation.SetNumConfsRequired(numConfsReq)
3✔
1732

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

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

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

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

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

1795
        log.Infof("Requiring %v confirmations for pendingChan(%x): "+
3✔
1796
                "amt=%v, push_amt=%v, committype=%v, upfrontShutdown=%x",
3✔
1797
                numConfsReq, msg.PendingChannelID, amt, msg.PushAmount,
3✔
1798
                commitType, msg.UpfrontShutdownScript)
3✔
1799

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

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

1819
        chanReserve := f.cfg.RequiredRemoteChanReserve(amt, maxDustLimit)
3✔
1820
        if acceptorResp.Reserve != 0 {
3✔
1821
                chanReserve = acceptorResp.Reserve
×
1822
        }
×
1823

1824
        remoteMaxValue := f.cfg.RequiredRemoteMaxValue(amt)
3✔
1825
        if acceptorResp.InFlightTotal != 0 {
3✔
1826
                remoteMaxValue = acceptorResp.InFlightTotal
×
1827
        }
×
1828

1829
        maxHtlcs := f.cfg.RequiredRemoteMaxHTLCs(amt)
3✔
1830
        if acceptorResp.HtlcLimit != 0 {
3✔
1831
                maxHtlcs = acceptorResp.HtlcLimit
×
1832
        }
×
1833

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

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

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

3✔
1873
        // Update the timestamp once the fundingOpenMsg has been handled.
3✔
1874
        defer resCtx.updateTimestamp()
3✔
1875

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

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

3✔
1913
        if resCtx.reservation.IsTaproot() {
6✔
1914
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
3✔
1915
                if err != nil {
3✔
1916
                        log.Error(errNoLocalNonce)
×
1917

×
1918
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
1919

×
1920
                        return
×
1921
                }
×
1922

1923
                remoteContribution.LocalNonce = &musig2.Nonces{
3✔
1924
                        PubNonce: localNonce,
3✔
1925
                }
3✔
1926
        }
1927

1928
        err = reservation.ProcessSingleContribution(remoteContribution)
3✔
1929
        if err != nil {
3✔
UNCOV
1930
                log.Errorf("unable to add contribution reservation: %v", err)
×
UNCOV
1931
                f.failFundingFlow(peer, cid, err)
×
UNCOV
1932
                return
×
UNCOV
1933
        }
×
1934

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

3✔
1944
        reservation.SetState(lnwallet.SentAcceptChannel)
3✔
1945

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

3✔
1968
        if commitType.IsTaproot() {
6✔
1969
                fundingAccept.LocalNonce = lnwire.SomeMusig2Nonce(
3✔
1970
                        ourContribution.LocalNonce.PubNonce,
3✔
1971
                )
3✔
1972
        }
3✔
1973

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

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

3✔
1989
        pendingChanID := msg.PendingChannelID
3✔
1990
        peerKey := peer.IdentityKey()
3✔
1991
        var peerKeyBytes []byte
3✔
1992
        if peerKey != nil {
6✔
1993
                peerKeyBytes = peerKey.SerializeCompressed()
3✔
1994
        }
3✔
1995

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

2003
        // Update the timestamp once the fundingAcceptMsg has been handled.
2004
        defer resCtx.updateTimestamp()
3✔
2005

3✔
2006
        if resCtx.reservation.State() != lnwallet.SentOpenChannel {
3✔
2007
                return
×
2008
        }
×
2009

2010
        log.Infof("Recv'd fundingResponse for pending_id(%x)",
3✔
2011
                pendingChanID[:])
3✔
2012

3✔
2013
        // Create the channel identifier.
3✔
2014
        cid := newChanIdentifier(msg.PendingChannelID)
3✔
2015

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

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

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

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

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

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

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

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

×
2109
                minDepth = 1
×
2110
        }
×
2111

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

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

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

3✔
2173
        if resCtx.reservation.IsTaproot() {
6✔
2174
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
3✔
2175
                if err != nil {
3✔
2176
                        log.Error(errNoLocalNonce)
×
2177

×
2178
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
2179

×
2180
                        return
×
2181
                }
×
2182

2183
                remoteContribution.LocalNonce = &musig2.Nonces{
3✔
2184
                        PubNonce: localNonce,
3✔
2185
                }
3✔
2186
        }
2187

2188
        err = resCtx.reservation.ProcessContribution(remoteContribution)
3✔
2189

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

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

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

3✔
2251
                        f.waitForPsbt(psbtIntent, resCtx, cid)
3✔
2252
                }()
3✔
2253

2254
                // With the new goroutine spawned, we can now exit to unblock
2255
                // the main event loop.
2256
                return
3✔
2257
        }
2258

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

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

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

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

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

2304
                // Nil error means the flow continues normally now.
2305
                case nil:
3✔
2306

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

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

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

2346
                // We are now ready to continue the funding flow.
2347
                f.continueFundingAccept(resCtx, cid)
3✔
2348

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

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

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

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

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

3✔
2387
        log.Infof("Generated ChannelPoint(%v) for pending_id(%x)", outPoint,
3✔
2388
                cid.tempChanID[:])
3✔
2389

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

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

3✔
2404
        // Send the FundingCreated msg.
3✔
2405
        fundingCreated := &lnwire.FundingCreated{
3✔
2406
                PendingChannelID: cid.tempChanID,
3✔
2407
                FundingPoint:     *outPoint,
3✔
2408
        }
3✔
2409

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

×
2420
                        return
×
2421
                }
×
2422

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

2435
        resCtx.reservation.SetState(lnwallet.SentFundingCreated)
3✔
2436

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

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

3✔
2454
        peerKey := peer.IdentityKey()
3✔
2455
        pendingChanID := msg.PendingChannelID
3✔
2456

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

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

3✔
2472
        if resCtx.reservation.State() != lnwallet.SentAcceptChannel {
3✔
2473
                return
×
2474
        }
×
2475

2476
        // Create the channel identifier without setting the active channel ID.
2477
        cid := newChanIdentifier(pendingChanID)
3✔
2478

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

×
2488
                        return
×
2489
                }
×
2490

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

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

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

2540
        // Get forwarding policy before deleting the reservation context.
2541
        forwardingPolicy := resCtx.forwardingPolicy
3✔
2542

3✔
2543
        // The channel is marked IsPending in the database, and can be removed
3✔
2544
        // from the set of active reservations.
3✔
2545
        f.deleteReservationCtx(peerKey, cid.tempChanID)
3✔
2546

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

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

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

3✔
2581
        fundingSigned := &lnwire.FundingSigned{}
3✔
2582

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

×
2595
                        return
×
2596
                }
×
2597

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

×
2608
                        return
×
2609
                }
×
2610
        }
2611

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

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

3✔
2625
        fundingSigned.ChanID = cid.chanID
3✔
2626

3✔
2627
        log.Infof("sending FundingSigned for pending_id(%x) over "+
3✔
2628
                "ChannelPoint(%v)", pendingChanID[:], fundingOut)
3✔
2629

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

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

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

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

3✔
2660
        // Inform the ChannelNotifier that the channel has entered
3✔
2661
        // pending open state.
3✔
2662
        f.cfg.NotifyPendingOpenChannelEvent(fundingOut, completeChan)
3✔
2663

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

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

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

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

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

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

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

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

×
2740
                return
×
2741
        }
×
2742

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

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

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

×
2769
                        return
×
2770
                }
×
2771

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

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

2794
        // The channel is now marked IsPending in the database, and we can
2795
        // delete it from our set of active reservations.
2796
        f.deleteReservationCtx(peerKey, pendingChanID)
3✔
2797

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

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

2813
                log.Infof("Broadcasting funding tx for ChannelPoint(%v): %x",
3✔
2814
                        completeChan.FundingOutpoint, fundingTxBuf.Bytes())
3✔
2815

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

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

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

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

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

2862
        log.Infof("Finalizing pending_id(%x) over ChannelPoint(%v), "+
3✔
2863
                "waiting for channel open on-chain", pendingChanID[:],
3✔
2864
                fundingPoint)
3✔
2865

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

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

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

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

2902
        // fundingTx is the funding transaction that created the channel.
2903
        fundingTx *wire.MsgTx
2904
}
2905

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

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

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

2938
        timeoutErr := fmt.Errorf("timeout waiting for funding tx (%v) to "+
3✔
2939
                "confirm", c.FundingOutpoint)
3✔
2940

3✔
2941
        // When the peer comes online, we'll notify it that we are now
3✔
2942
        // considering the channel flow canceled.
3✔
2943
        f.wg.Add(1)
3✔
2944
        go func() {
6✔
2945
                defer f.wg.Done()
3✔
2946

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

2953
                // nil error means we continue on.
2954
                case nil:
3✔
2955

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

2963
                // Create channel identifier and set the channel ID.
2964
                cid := newChanIdentifier(pendingID)
3✔
2965
                cid.setChanID(lnwire.NewChanIDFromOutPoint(c.FundingOutpoint))
3✔
2966

3✔
2967
                // TODO(halseth): should this send be made
3✔
2968
                // reliable?
3✔
2969

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

2975
        return timeoutErr
3✔
2976
}
2977

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

3✔
2986
        confChan := make(chan *confirmedChannel)
3✔
2987
        timeoutChan := make(chan error, 1)
3✔
2988
        cancelChan := make(chan struct{})
3✔
2989

3✔
2990
        f.wg.Add(1)
3✔
2991
        go f.waitForFundingConfirmation(ch, cancelChan, confChan)
3✔
2992

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

3✔
3002
        select {
3✔
3003
        case err := <-timeoutChan:
3✔
3004
                if err != nil {
3✔
3005
                        return nil, err
×
3006
                }
×
3007
                return nil, ErrConfirmationTimeout
3✔
3008

3009
        case <-f.quit:
3✔
3010
                // The fundingManager is shutting down, and will resume wait on
3✔
3011
                // startup.
3✔
3012
                return nil, ErrFundingManagerShuttingDown
3✔
3013

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

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

3✔
3029
        if channel.ChanType.IsTaproot() {
6✔
3030
                pkScript, _, err := input.GenTaprootFundingScript(
3✔
3031
                        localKey, remoteKey, int64(channel.Capacity),
3✔
3032
                        channel.TapscriptRoot,
3✔
3033
                )
3✔
3034
                if err != nil {
3✔
3035
                        return nil, err
×
3036
                }
×
3037

3038
                return pkScript, nil
3✔
3039
        }
3040

3041
        multiSigScript, err := input.GenMultiSigScript(
3✔
3042
                localKey.SerializeCompressed(),
3✔
3043
                remoteKey.SerializeCompressed(),
3✔
3044
        )
3✔
3045
        if err != nil {
3✔
3046
                return nil, err
×
3047
        }
×
3048

3049
        return input.WitnessScriptHash(multiSigScript)
3✔
3050
}
3051

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

3✔
3065
        defer f.wg.Done()
3✔
3066
        defer close(confChan)
3✔
3067

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

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

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

3097
        log.Infof("Waiting for funding tx (%v) to reach %v confirmations",
3✔
3098
                txid, numConfs)
3✔
3099

3✔
3100
        var confDetails *chainntnfs.TxConfirmation
3✔
3101
        var ok bool
3✔
3102

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

3109
        case <-cancelChan:
3✔
3110
                log.Warnf("canceled waiting for funding confirmation, "+
3✔
3111
                        "stopping funding flow for ChannelPoint(%v)",
3✔
3112
                        completeChan.FundingOutpoint)
3✔
3113
                return
3✔
3114

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

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

3129
        fundingPoint := completeChan.FundingOutpoint
3✔
3130
        log.Infof("ChannelPoint(%v) is now active: ChannelID(%v)",
3✔
3131
                fundingPoint, lnwire.NewChanIDFromOutPoint(fundingPoint))
3✔
3132

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

3✔
3142
        select {
3✔
3143
        case confChan <- &confirmedChannel{
3144
                shortChanID: shortChanID,
3145
                fundingTx:   confDetails.Tx,
3146
        }:
3✔
3147
        case <-f.quit:
×
3148
                return
×
3149
        }
3150
}
3151

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

3✔
3162
        defer f.wg.Done()
3✔
3163

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

3171
        defer epochClient.Cancel()
3✔
3172

3✔
3173
        // For the maxWaitNumBlocksFundingConf different values are set
3✔
3174
        // in case we are in a dev environment so enhance test
3✔
3175
        // capabilities.
3✔
3176
        maxWaitNumBlocksFundingConf := MaxWaitNumBlocksFundingConf
3✔
3177

3✔
3178
        // Get the maxWaitNumBlocksFundingConf. If we are not in
3✔
3179
        // development mode, this would be nil.
3✔
3180
        if lncfg.IsDevBuild() {
6✔
3181
                maxWaitNumBlocksFundingConf = f.cfg.Dev.
3✔
3182
                        MaxWaitNumBlocksFundingConf
3✔
3183
        }
3✔
3184

3185
        // On block maxHeight we will cancel the funding confirmation wait.
3186
        broadcastHeight := completeChan.BroadcastHeight()
3✔
3187
        maxHeight := broadcastHeight + uint32(maxWaitNumBlocksFundingConf)
3✔
3188
        for {
6✔
3189
                select {
3✔
3190
                case epoch, ok := <-epochClient.Epochs:
3✔
3191
                        if !ok {
3✔
3192
                                timeoutChan <- fmt.Errorf("epoch client " +
×
3193
                                        "shutting down")
×
3194
                                return
×
3195
                        }
×
3196

3197
                        // Close the timeout channel and exit if the block is
3198
                        // above the max height.
3199
                        if uint32(epoch.Height) >= maxHeight {
6✔
3200
                                log.Warnf("Waited for %v blocks without "+
3✔
3201
                                        "seeing funding transaction confirmed,"+
3✔
3202
                                        " cancelling.",
3✔
3203
                                        maxWaitNumBlocksFundingConf)
3✔
3204

3✔
3205
                                // Notify the caller of the timeout.
3✔
3206
                                close(timeoutChan)
3✔
3207
                                return
3✔
3208
                        }
3✔
3209

3210
                        // TODO: If we are the channel initiator implement
3211
                        // a method for recovering the funds from the funding
3212
                        // transaction
3213

3214
                case <-cancelChan:
3✔
3215
                        return
3✔
3216

3217
                case <-f.quit:
3✔
3218
                        // The fundingManager is shutting down, will resume
3✔
3219
                        // waiting for the funding transaction on startup.
3✔
3220
                        return
3✔
3221
                }
3222
        }
3223
}
3224

3225
// makeLabelForTx updates the label for the confirmed funding transaction. If
3226
// we opened the channel, and lnd's wallet published our funding tx (which is
3227
// not the case for some channels) then we update our transaction label with
3228
// our short channel ID, which is known now that our funding transaction has
3229
// confirmed. We do not label transactions we did not publish, because our
3230
// wallet has no knowledge of them.
3231
func (f *Manager) makeLabelForTx(c *channeldb.OpenChannel) {
3✔
3232
        if c.IsInitiator && c.ChanType.HasFundingTx() {
6✔
3233
                shortChanID := c.ShortChanID()
3✔
3234

3✔
3235
                // For zero-conf channels, we'll use the actually-confirmed
3✔
3236
                // short channel id.
3✔
3237
                if c.IsZeroConf() {
6✔
3238
                        shortChanID = c.ZeroConfRealScid()
3✔
3239
                }
3✔
3240

3241
                label := labels.MakeLabel(
3✔
3242
                        labels.LabelTypeChannelOpen, &shortChanID,
3✔
3243
                )
3✔
3244

3✔
3245
                err := f.cfg.UpdateLabel(c.FundingOutpoint.Hash, label)
3✔
3246
                if err != nil {
3✔
3247
                        log.Errorf("unable to update label: %v", err)
×
3248
                }
×
3249
        }
3250
}
3251

3252
// handleFundingConfirmation marks a channel as open in the database, and set
3253
// the channelOpeningState markedOpen. In addition it will report the now
3254
// decided short channel ID to the switch, and close the local discovery signal
3255
// for this channel.
3256
func (f *Manager) handleFundingConfirmation(
3257
        completeChan *channeldb.OpenChannel,
3258
        confChannel *confirmedChannel) error {
3✔
3259

3✔
3260
        fundingPoint := completeChan.FundingOutpoint
3✔
3261
        chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
3✔
3262

3✔
3263
        // TODO(roasbeef): ideally persistent state update for chan above
3✔
3264
        // should be abstracted
3✔
3265

3✔
3266
        // Now that that the channel has been fully confirmed, we'll request
3✔
3267
        // that the wallet fully verify this channel to ensure that it can be
3✔
3268
        // used.
3✔
3269
        err := f.cfg.Wallet.ValidateChannel(completeChan, confChannel.fundingTx)
3✔
3270
        if err != nil {
3✔
3271
                // TODO(roasbeef): delete chan state?
×
3272
                return fmt.Errorf("unable to validate channel: %w", err)
×
3273
        }
×
3274

3275
        // Now that the channel has been validated, we'll persist an alias for
3276
        // this channel if the option-scid-alias feature-bit was negotiated.
3277
        if completeChan.NegotiatedAliasFeature() {
6✔
3278
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
3✔
3279
                if err != nil {
3✔
3280
                        return fmt.Errorf("unable to request alias: %w", err)
×
3281
                }
×
3282

3283
                err = f.cfg.AliasManager.AddLocalAlias(
3✔
3284
                        aliasScid, confChannel.shortChanID, true, false,
3✔
3285
                )
3✔
3286
                if err != nil {
3✔
3287
                        return fmt.Errorf("unable to request alias: %w", err)
×
3288
                }
×
3289
        }
3290

3291
        // The funding transaction now being confirmed, we add this channel to
3292
        // the fundingManager's internal persistent state machine that we use
3293
        // to track the remaining process of the channel opening. This is
3294
        // useful to resume the opening process in case of restarts. We set the
3295
        // opening state before we mark the channel opened in the database,
3296
        // such that we can receover from one of the db writes failing.
3297
        err = f.saveChannelOpeningState(
3✔
3298
                &fundingPoint, markedOpen, &confChannel.shortChanID,
3✔
3299
        )
3✔
3300
        if err != nil {
3✔
3301
                return fmt.Errorf("error setting channel state to "+
×
3302
                        "markedOpen: %v", err)
×
3303
        }
×
3304

3305
        // Now that the channel has been fully confirmed and we successfully
3306
        // saved the opening state, we'll mark it as open within the database.
3307
        err = completeChan.MarkAsOpen(confChannel.shortChanID)
3✔
3308
        if err != nil {
3✔
3309
                return fmt.Errorf("error setting channel pending flag to "+
×
3310
                        "false:        %v", err)
×
3311
        }
×
3312

3313
        // Update the confirmed funding transaction label.
3314
        f.makeLabelForTx(completeChan)
3✔
3315

3✔
3316
        // Inform the ChannelNotifier that the channel has transitioned from
3✔
3317
        // pending open to open.
3✔
3318
        f.cfg.NotifyOpenChannelEvent(completeChan.FundingOutpoint)
3✔
3319

3✔
3320
        // Close the discoverySignal channel, indicating to a separate
3✔
3321
        // goroutine that the channel now is marked as open in the database
3✔
3322
        // and that it is acceptable to process channel_ready messages
3✔
3323
        // from the peer.
3✔
3324
        if discoverySignal, ok := f.localDiscoverySignals.Load(chanID); ok {
6✔
3325
                close(discoverySignal)
3✔
3326
        }
3✔
3327

3328
        return nil
3✔
3329
}
3330

3331
// sendChannelReady creates and sends the channelReady message.
3332
// This should be called after the funding transaction has been confirmed,
3333
// and the channelState is 'markedOpen'.
3334
func (f *Manager) sendChannelReady(completeChan *channeldb.OpenChannel,
3335
        channel *lnwallet.LightningChannel) error {
3✔
3336

3✔
3337
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
3✔
3338

3✔
3339
        var peerKey [33]byte
3✔
3340
        copy(peerKey[:], completeChan.IdentityPub.SerializeCompressed())
3✔
3341

3✔
3342
        // Next, we'll send over the channel_ready message which marks that we
3✔
3343
        // consider the channel open by presenting the remote party with our
3✔
3344
        // next revocation key. Without the revocation key, the remote party
3✔
3345
        // will be unable to propose state transitions.
3✔
3346
        nextRevocation, err := channel.NextRevocationKey()
3✔
3347
        if err != nil {
3✔
3348
                return fmt.Errorf("unable to create next revocation: %w", err)
×
3349
        }
×
3350
        channelReadyMsg := lnwire.NewChannelReady(chanID, nextRevocation)
3✔
3351

3✔
3352
        // If this is a taproot channel, then we also need to send along our
3✔
3353
        // set of musig2 nonces as well.
3✔
3354
        if completeChan.ChanType.IsTaproot() {
6✔
3355
                log.Infof("ChanID(%v): generating musig2 nonces...",
3✔
3356
                        chanID)
3✔
3357

3✔
3358
                f.nonceMtx.Lock()
3✔
3359
                localNonce, ok := f.pendingMusigNonces[chanID]
3✔
3360
                if !ok {
6✔
3361
                        // If we don't have any nonces generated yet for this
3✔
3362
                        // first state, then we'll generate them now and stow
3✔
3363
                        // them away.  When we receive the funding locked
3✔
3364
                        // message, we'll then pass along this same set of
3✔
3365
                        // nonces.
3✔
3366
                        newNonce, err := channel.GenMusigNonces()
3✔
3367
                        if err != nil {
3✔
3368
                                f.nonceMtx.Unlock()
×
3369
                                return err
×
3370
                        }
×
3371

3372
                        // Now that we've generated the nonce for this channel,
3373
                        // we'll store it in the set of pending nonces.
3374
                        localNonce = newNonce
3✔
3375
                        f.pendingMusigNonces[chanID] = localNonce
3✔
3376
                }
3377
                f.nonceMtx.Unlock()
3✔
3378

3✔
3379
                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce(
3✔
3380
                        localNonce.PubNonce,
3✔
3381
                )
3✔
3382
        }
3383

3384
        // If the channel negotiated the option-scid-alias feature bit, we'll
3385
        // send a TLV segment that includes an alias the peer can use in their
3386
        // invoice hop hints. We'll send the first alias we find for the
3387
        // channel since it does not matter which alias we send. We'll error
3388
        // out in the odd case that no aliases are found.
3389
        if completeChan.NegotiatedAliasFeature() {
6✔
3390
                aliases := f.cfg.AliasManager.GetAliases(
3✔
3391
                        completeChan.ShortChanID(),
3✔
3392
                )
3✔
3393
                if len(aliases) == 0 {
3✔
3394
                        return fmt.Errorf("no aliases found")
×
3395
                }
×
3396

3397
                // We can use a pointer to aliases since GetAliases returns a
3398
                // copy of the alias slice.
3399
                channelReadyMsg.AliasScid = &aliases[0]
3✔
3400
        }
3401

3402
        // If the peer has disconnected before we reach this point, we will need
3403
        // to wait for him to come back online before sending the channelReady
3404
        // message. This is special for channelReady, since failing to send any
3405
        // of the previous messages in the funding flow just cancels the flow.
3406
        // But now the funding transaction is confirmed, the channel is open
3407
        // and we have to make sure the peer gets the channelReady message when
3408
        // it comes back online. This is also crucial during restart of lnd,
3409
        // where we might try to resend the channelReady message before the
3410
        // server has had the time to connect to the peer. We keep trying to
3411
        // send channelReady until we succeed, or the fundingManager is shut
3412
        // down.
3413
        for {
6✔
3414
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
3✔
3415
                if err != nil {
3✔
UNCOV
3416
                        return err
×
UNCOV
3417
                }
×
3418

3419
                localAlias := peer.LocalFeatures().HasFeature(
3✔
3420
                        lnwire.ScidAliasOptional,
3✔
3421
                )
3✔
3422
                remoteAlias := peer.RemoteFeatures().HasFeature(
3✔
3423
                        lnwire.ScidAliasOptional,
3✔
3424
                )
3✔
3425

3✔
3426
                // We could also refresh the channel state instead of checking
3✔
3427
                // whether the feature was negotiated, but this saves us a
3✔
3428
                // database read.
3✔
3429
                if channelReadyMsg.AliasScid == nil && localAlias &&
3✔
3430
                        remoteAlias {
3✔
3431

×
3432
                        // If an alias was not assigned above and the scid
×
3433
                        // alias feature was negotiated, check if we already
×
3434
                        // have an alias stored in case handleChannelReady was
×
3435
                        // called before this. If an alias exists, use that in
×
3436
                        // channel_ready. Otherwise, request and store an
×
3437
                        // alias and use that.
×
3438
                        aliases := f.cfg.AliasManager.GetAliases(
×
3439
                                completeChan.ShortChannelID,
×
3440
                        )
×
3441
                        if len(aliases) == 0 {
×
3442
                                // No aliases were found.
×
3443
                                alias, err := f.cfg.AliasManager.RequestAlias()
×
3444
                                if err != nil {
×
3445
                                        return err
×
3446
                                }
×
3447

3448
                                err = f.cfg.AliasManager.AddLocalAlias(
×
3449
                                        alias, completeChan.ShortChannelID,
×
3450
                                        false, false,
×
3451
                                )
×
3452
                                if err != nil {
×
3453
                                        return err
×
3454
                                }
×
3455

3456
                                channelReadyMsg.AliasScid = &alias
×
3457
                        } else {
×
3458
                                channelReadyMsg.AliasScid = &aliases[0]
×
3459
                        }
×
3460
                }
3461

3462
                log.Infof("Peer(%x) is online, sending ChannelReady "+
3✔
3463
                        "for ChannelID(%v)", peerKey, chanID)
3✔
3464

3✔
3465
                if err := peer.SendMessage(true, channelReadyMsg); err == nil {
6✔
3466
                        // Sending succeeded, we can break out and continue the
3✔
3467
                        // funding flow.
3✔
3468
                        break
3✔
3469
                }
3470

3471
                log.Warnf("Unable to send channelReady to peer %x: %v. "+
×
3472
                        "Will retry when online", peerKey, err)
×
3473
        }
3474

3475
        return nil
3✔
3476
}
3477

3478
// receivedChannelReady checks whether or not we've received a ChannelReady
3479
// from the remote peer. If we have, RemoteNextRevocation will be set.
3480
func (f *Manager) receivedChannelReady(node *btcec.PublicKey,
3481
        chanID lnwire.ChannelID) (bool, error) {
3✔
3482

3✔
3483
        // If the funding manager has exited, return an error to stop looping.
3✔
3484
        // Note that the peer may appear as online while the funding manager
3✔
3485
        // has stopped due to the shutdown order in the server.
3✔
3486
        select {
3✔
UNCOV
3487
        case <-f.quit:
×
UNCOV
3488
                return false, ErrFundingManagerShuttingDown
×
3489
        default:
3✔
3490
        }
3491

3492
        // Avoid a tight loop if peer is offline.
3493
        if _, err := f.waitForPeerOnline(node); err != nil {
4✔
3494
                log.Errorf("Wait for peer online failed: %v", err)
1✔
3495
                return false, err
1✔
3496
        }
1✔
3497

3498
        // If we cannot find the channel, then we haven't processed the
3499
        // remote's channelReady message.
3500
        channel, err := f.cfg.FindChannel(node, chanID)
3✔
3501
        if err != nil {
3✔
3502
                log.Errorf("Unable to locate ChannelID(%v) to determine if "+
×
3503
                        "ChannelReady was received", chanID)
×
3504
                return false, err
×
3505
        }
×
3506

3507
        // If we haven't insert the next revocation point, we haven't finished
3508
        // processing the channel ready message.
3509
        if channel.RemoteNextRevocation == nil {
6✔
3510
                return false, nil
3✔
3511
        }
3✔
3512

3513
        // Finally, the barrier signal is removed once we finish
3514
        // `handleChannelReady`. If we can still find the signal, we haven't
3515
        // finished processing it yet.
3516
        _, loaded := f.handleChannelReadyBarriers.Load(chanID)
3✔
3517

3✔
3518
        return !loaded, nil
3✔
3519
}
3520

3521
// extractAnnounceParams extracts the various channel announcement and update
3522
// parameters that will be needed to construct a ChannelAnnouncement and a
3523
// ChannelUpdate.
3524
func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) (
3525
        lnwire.MilliSatoshi, lnwire.MilliSatoshi) {
3✔
3526

3✔
3527
        // We'll obtain the min HTLC value we can forward in our direction, as
3✔
3528
        // we'll use this value within our ChannelUpdate. This constraint is
3✔
3529
        // originally set by the remote node, as it will be the one that will
3✔
3530
        // need to determine the smallest HTLC it deems economically relevant.
3✔
3531
        fwdMinHTLC := c.LocalChanCfg.MinHTLC
3✔
3532

3✔
3533
        // We don't necessarily want to go as low as the remote party allows.
3✔
3534
        // Check it against our default forwarding policy.
3✔
3535
        if fwdMinHTLC < f.cfg.DefaultRoutingPolicy.MinHTLCOut {
6✔
3536
                fwdMinHTLC = f.cfg.DefaultRoutingPolicy.MinHTLCOut
3✔
3537
        }
3✔
3538

3539
        // We'll obtain the max HTLC value we can forward in our direction, as
3540
        // we'll use this value within our ChannelUpdate. This value must be <=
3541
        // channel capacity and <= the maximum in-flight msats set by the peer.
3542
        fwdMaxHTLC := c.LocalChanCfg.MaxPendingAmount
3✔
3543
        capacityMSat := lnwire.NewMSatFromSatoshis(c.Capacity)
3✔
3544
        if fwdMaxHTLC > capacityMSat {
3✔
3545
                fwdMaxHTLC = capacityMSat
×
3546
        }
×
3547

3548
        return fwdMinHTLC, fwdMaxHTLC
3✔
3549
}
3550

3551
// addToGraph sends a ChannelAnnouncement and a ChannelUpdate to the
3552
// gossiper so that the channel is added to the graph builder's internal graph.
3553
// These announcement messages are NOT broadcasted to the greater network,
3554
// only to the channel counter party. The proofs required to announce the
3555
// channel to the greater network will be created and sent in annAfterSixConfs.
3556
// The peerAlias is used for zero-conf channels to give the counter-party a
3557
// ChannelUpdate they understand. ourPolicy may be set for various
3558
// option-scid-alias channels to re-use the same policy.
3559
func (f *Manager) addToGraph(completeChan *channeldb.OpenChannel,
3560
        shortChanID *lnwire.ShortChannelID,
3561
        peerAlias *lnwire.ShortChannelID,
3562
        ourPolicy *models.ChannelEdgePolicy) error {
3✔
3563

3✔
3564
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
3✔
3565

3✔
3566
        fwdMinHTLC, fwdMaxHTLC := f.extractAnnounceParams(completeChan)
3✔
3567

3✔
3568
        ann, err := f.newChanAnnouncement(
3✔
3569
                f.cfg.IDKey, completeChan.IdentityPub,
3✔
3570
                &completeChan.LocalChanCfg.MultiSigKey,
3✔
3571
                completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
3✔
3572
                chanID, fwdMinHTLC, fwdMaxHTLC, ourPolicy,
3✔
3573
                completeChan.ChanType,
3✔
3574
        )
3✔
3575
        if err != nil {
3✔
3576
                return fmt.Errorf("error generating channel "+
×
3577
                        "announcement: %v", err)
×
3578
        }
×
3579

3580
        // Send ChannelAnnouncement and ChannelUpdate to the gossiper to add
3581
        // to the Router's topology.
3582
        errChan := f.cfg.SendAnnouncement(
3✔
3583
                ann.chanAnn, discovery.ChannelCapacity(completeChan.Capacity),
3✔
3584
                discovery.ChannelPoint(completeChan.FundingOutpoint),
3✔
3585
                discovery.TapscriptRoot(completeChan.TapscriptRoot),
3✔
3586
        )
3✔
3587
        select {
3✔
3588
        case err := <-errChan:
3✔
3589
                if err != nil {
3✔
3590
                        if graph.IsError(err, graph.ErrOutdated,
×
3591
                                graph.ErrIgnored) {
×
3592

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

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

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

3624
        return nil
3✔
3625
}
3626

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

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

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

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

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

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

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

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

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

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

3720
                fundingPoint := completeChan.FundingOutpoint
3✔
3721
                chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
3✔
3722

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

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

3740
                        // We'll delete the edge and add it again via
3741
                        // addToGraph. This is because the peer may have
3742
                        // sent us a ChannelUpdate with an alias and we don't
3743
                        // want to relay this.
3744
                        ourPolicy, err := f.cfg.DeleteAliasEdge(baseScid)
3✔
3745
                        if err != nil {
3✔
3746
                                return fmt.Errorf("failed deleting real edge "+
×
3747
                                        "for alias channel from graph: %v",
×
3748
                                        err)
×
3749
                        }
×
3750

3751
                        err = f.addToGraph(
3✔
3752
                                completeChan, &baseScid, nil, ourPolicy,
3✔
3753
                        )
3✔
3754
                        if err != nil {
3✔
3755
                                return fmt.Errorf("failed to re-add to "+
×
3756
                                        "graph: %v", err)
×
3757
                        }
×
3758
                }
3759

3760
                // Create and broadcast the proofs required to make this channel
3761
                // public and usable for other nodes for routing.
3762
                err = f.announceChannel(
3✔
3763
                        f.cfg.IDKey, completeChan.IdentityPub,
3✔
3764
                        &completeChan.LocalChanCfg.MultiSigKey,
3✔
3765
                        completeChan.RemoteChanCfg.MultiSigKey.PubKey,
3✔
3766
                        *shortChanID, chanID, completeChan.ChanType,
3✔
3767
                )
3✔
3768
                if err != nil {
6✔
3769
                        return fmt.Errorf("channel announcement failed: %w",
3✔
3770
                                err)
3✔
3771
                }
3✔
3772

3773
                log.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
3✔
3774
                        "sent to gossiper", &fundingPoint, shortChanID)
3✔
3775
        }
3776

3777
        return nil
3✔
3778
}
3779

3780
// waitForZeroConfChannel is called when the state is addedToGraph with
3781
// a zero-conf channel. This will wait for the real confirmation, add the
3782
// confirmed SCID to the router graph, and then announce after six confs.
3783
func (f *Manager) waitForZeroConfChannel(c *channeldb.OpenChannel) error {
3✔
3784
        // First we'll check whether the channel is confirmed on-chain. If it
3✔
3785
        // is already confirmed, the chainntnfs subsystem will return with the
3✔
3786
        // confirmed tx. Otherwise, we'll wait here until confirmation occurs.
3✔
3787
        confChan, err := f.waitForFundingWithTimeout(c)
3✔
3788
        if err != nil {
6✔
3789
                return fmt.Errorf("error waiting for zero-conf funding "+
3✔
3790
                        "confirmation for ChannelPoint(%v): %v",
3✔
3791
                        c.FundingOutpoint, err)
3✔
3792
        }
3✔
3793

3794
        // We'll need to refresh the channel state so that things are properly
3795
        // populated when validating the channel state. Otherwise, a panic may
3796
        // occur due to inconsistency in the OpenChannel struct.
3797
        err = c.Refresh()
3✔
3798
        if err != nil {
6✔
3799
                return fmt.Errorf("unable to refresh channel state: %w", err)
3✔
3800
        }
3✔
3801

3802
        // Now that we have the confirmed transaction and the proper SCID,
3803
        // we'll call ValidateChannel to ensure the confirmed tx is properly
3804
        // formatted.
3805
        err = f.cfg.Wallet.ValidateChannel(c, confChan.fundingTx)
3✔
3806
        if err != nil {
3✔
3807
                return fmt.Errorf("unable to validate zero-conf channel: "+
×
3808
                        "%v", err)
×
3809
        }
×
3810

3811
        // Once we know the confirmed ShortChannelID, we'll need to save it to
3812
        // the database and refresh the OpenChannel struct with it.
3813
        err = c.MarkRealScid(confChan.shortChanID)
3✔
3814
        if err != nil {
3✔
3815
                return fmt.Errorf("unable to set confirmed SCID for zero "+
×
3816
                        "channel: %v", err)
×
3817
        }
×
3818

3819
        // Six confirmations have been reached. If this channel is public,
3820
        // we'll delete some of the alias mappings the gossiper uses.
3821
        isPublic := c.ChannelFlags&lnwire.FFAnnounceChannel != 0
3✔
3822
        if isPublic {
6✔
3823
                err = f.cfg.AliasManager.DeleteSixConfs(c.ShortChannelID)
3✔
3824
                if err != nil {
3✔
3825
                        return fmt.Errorf("unable to delete base alias after "+
×
3826
                                "six confirmations: %v", err)
×
3827
                }
×
3828

3829
                // TODO: Make this atomic!
3830
                ourPolicy, err := f.cfg.DeleteAliasEdge(c.ShortChanID())
3✔
3831
                if err != nil {
3✔
3832
                        return fmt.Errorf("unable to delete alias edge from "+
×
3833
                                "graph: %v", err)
×
3834
                }
×
3835

3836
                // We'll need to update the graph with the new ShortChannelID
3837
                // via an addToGraph call. We don't pass in the peer's
3838
                // alias since we'll be using the confirmed SCID from now on
3839
                // regardless if it's public or not.
3840
                err = f.addToGraph(
3✔
3841
                        c, &confChan.shortChanID, nil, ourPolicy,
3✔
3842
                )
3✔
3843
                if err != nil {
3✔
3844
                        return fmt.Errorf("failed adding confirmed zero-conf "+
×
3845
                                "SCID to graph: %v", err)
×
3846
                }
×
3847
        }
3848

3849
        // Since we have now marked down the confirmed SCID, we'll also need to
3850
        // tell the Switch to refresh the relevant ChannelLink so that forwards
3851
        // under the confirmed SCID are possible if this is a public channel.
3852
        err = f.cfg.ReportShortChanID(c.FundingOutpoint)
3✔
3853
        if err != nil {
3✔
3854
                // This should only fail if the link is not found in the
×
3855
                // Switch's linkIndex map. If this is the case, then the peer
×
3856
                // has gone offline and the next time the link is loaded, it
×
3857
                // will have a refreshed state. Just log an error here.
×
3858
                log.Errorf("unable to report scid for zero-conf channel "+
×
3859
                        "channel: %v", err)
×
3860
        }
×
3861

3862
        // Update the confirmed transaction's label.
3863
        f.makeLabelForTx(c)
3✔
3864

3✔
3865
        return nil
3✔
3866
}
3867

3868
// genFirstStateMusigNonce generates a nonces for the "first" local state. This
3869
// is the verification nonce for the state created for us after the initial
3870
// commitment transaction signed as part of the funding flow.
3871
func genFirstStateMusigNonce(channel *channeldb.OpenChannel,
3872
) (*musig2.Nonces, error) {
3✔
3873

3✔
3874
        musig2ShaChain, err := channeldb.DeriveMusig2Shachain(
3✔
3875
                channel.RevocationProducer,
3✔
3876
        )
3✔
3877
        if err != nil {
3✔
3878
                return nil, fmt.Errorf("unable to generate musig channel "+
×
3879
                        "nonces: %v", err)
×
3880
        }
×
3881

3882
        // We use the _next_ commitment height here as we need to generate the
3883
        // nonce for the next state the remote party will sign for us.
3884
        verNonce, err := channeldb.NewMusigVerificationNonce(
3✔
3885
                channel.LocalChanCfg.MultiSigKey.PubKey,
3✔
3886
                channel.LocalCommitment.CommitHeight+1,
3✔
3887
                musig2ShaChain,
3✔
3888
        )
3✔
3889
        if err != nil {
3✔
3890
                return nil, fmt.Errorf("unable to generate musig channel "+
×
3891
                        "nonces: %v", err)
×
3892
        }
×
3893

3894
        return verNonce, nil
3✔
3895
}
3896

3897
// handleChannelReady finalizes the channel funding process and enables the
3898
// channel to enter normal operating mode.
3899
func (f *Manager) handleChannelReady(peer lnpeer.Peer, //nolint:funlen
3900
        msg *lnwire.ChannelReady) {
3✔
3901

3✔
3902
        defer f.wg.Done()
3✔
3903

3✔
3904
        // If we are in development mode, we'll wait for specified duration
3✔
3905
        // before processing the channel ready message.
3✔
3906
        if f.cfg.Dev != nil {
6✔
3907
                duration := f.cfg.Dev.ProcessChannelReadyWait
3✔
3908
                log.Warnf("Channel(%v): sleeping %v before processing "+
3✔
3909
                        "channel_ready", msg.ChanID, duration)
3✔
3910

3✔
3911
                select {
3✔
3912
                case <-time.After(duration):
3✔
3913
                        log.Warnf("Channel(%v): slept %v before processing "+
3✔
3914
                                "channel_ready", msg.ChanID, duration)
3✔
3915
                case <-f.quit:
×
3916
                        log.Warnf("Channel(%v): quit sleeping", msg.ChanID)
×
3917
                        return
×
3918
                }
3919
        }
3920

3921
        log.Debugf("Received ChannelReady for ChannelID(%v) from "+
3✔
3922
                "peer %x", msg.ChanID,
3✔
3923
                peer.IdentityKey().SerializeCompressed())
3✔
3924

3✔
3925
        // We now load or create a new channel barrier for this channel.
3✔
3926
        _, loaded := f.handleChannelReadyBarriers.LoadOrStore(
3✔
3927
                msg.ChanID, struct{}{},
3✔
3928
        )
3✔
3929

3✔
3930
        // If we are currently in the process of handling a channel_ready
3✔
3931
        // message for this channel, ignore.
3✔
3932
        if loaded {
5✔
3933
                log.Infof("Already handling channelReady for "+
2✔
3934
                        "ChannelID(%v), ignoring.", msg.ChanID)
2✔
3935
                return
2✔
3936
        }
2✔
3937

3938
        // If not already handling channelReady for this channel, then the
3939
        // `LoadOrStore` has set up a barrier, and it will be removed once this
3940
        // function exits.
3941
        defer f.handleChannelReadyBarriers.Delete(msg.ChanID)
3✔
3942

3✔
3943
        localDiscoverySignal, ok := f.localDiscoverySignals.Load(msg.ChanID)
3✔
3944
        if ok {
6✔
3945
                // Before we proceed with processing the channel_ready
3✔
3946
                // message, we'll wait for the local waitForFundingConfirmation
3✔
3947
                // goroutine to signal that it has the necessary state in
3✔
3948
                // place. Otherwise, we may be missing critical information
3✔
3949
                // required to handle forwarded HTLC's.
3✔
3950
                select {
3✔
3951
                case <-localDiscoverySignal:
3✔
3952
                        // Fallthrough
3953
                case <-f.quit:
3✔
3954
                        return
3✔
3955
                }
3956

3957
                // With the signal received, we can now safely delete the entry
3958
                // from the map.
3959
                f.localDiscoverySignals.Delete(msg.ChanID)
3✔
3960
        }
3961

3962
        // First, we'll attempt to locate the channel whose funding workflow is
3963
        // being finalized by this message. We go to the database rather than
3964
        // our reservation map as we may have restarted, mid funding flow. Also
3965
        // provide the node's public key to make the search faster.
3966
        chanID := msg.ChanID
3✔
3967
        channel, err := f.cfg.FindChannel(peer.IdentityKey(), chanID)
3✔
3968
        if err != nil {
3✔
3969
                log.Errorf("Unable to locate ChannelID(%v), cannot complete "+
×
3970
                        "funding", chanID)
×
3971
                return
×
3972
        }
×
3973

3974
        // If this is a taproot channel, then we can generate the set of nonces
3975
        // the remote party needs to send the next remote commitment here.
3976
        var firstVerNonce *musig2.Nonces
3✔
3977
        if channel.ChanType.IsTaproot() {
6✔
3978
                firstVerNonce, err = genFirstStateMusigNonce(channel)
3✔
3979
                if err != nil {
3✔
3980
                        log.Error(err)
×
3981
                        return
×
3982
                }
×
3983
        }
3984

3985
        // We'll need to store the received TLV alias if the option_scid_alias
3986
        // feature was negotiated. This will be used to provide route hints
3987
        // during invoice creation. In the zero-conf case, it is also used to
3988
        // provide a ChannelUpdate to the remote peer. This is done before the
3989
        // call to InsertNextRevocation in case the call to PutPeerAlias fails.
3990
        // If it were to fail on the first call to handleChannelReady, we
3991
        // wouldn't want the channel to be usable yet.
3992
        if channel.NegotiatedAliasFeature() {
6✔
3993
                // If the AliasScid field is nil, we must fail out. We will
3✔
3994
                // most likely not be able to route through the peer.
3✔
3995
                if msg.AliasScid == nil {
3✔
3996
                        log.Debugf("Consider closing ChannelID(%v), peer "+
×
3997
                                "does not implement the option-scid-alias "+
×
3998
                                "feature properly", chanID)
×
3999
                        return
×
4000
                }
×
4001

4002
                // We'll store the AliasScid so that invoice creation can use
4003
                // it.
4004
                err = f.cfg.AliasManager.PutPeerAlias(chanID, *msg.AliasScid)
3✔
4005
                if err != nil {
3✔
4006
                        log.Errorf("unable to store peer's alias: %v", err)
×
4007
                        return
×
4008
                }
×
4009

4010
                // If we do not have an alias stored, we'll create one now.
4011
                // This is only used in the upgrade case where a user toggles
4012
                // the option-scid-alias feature-bit to on. We'll also send the
4013
                // channel_ready message here in case the link is created
4014
                // before sendChannelReady is called.
4015
                aliases := f.cfg.AliasManager.GetAliases(
3✔
4016
                        channel.ShortChannelID,
3✔
4017
                )
3✔
4018
                if len(aliases) == 0 {
3✔
4019
                        // No aliases were found so we'll request and store an
×
4020
                        // alias and use it in the channel_ready message.
×
4021
                        alias, err := f.cfg.AliasManager.RequestAlias()
×
4022
                        if err != nil {
×
4023
                                log.Errorf("unable to request alias: %v", err)
×
4024
                                return
×
4025
                        }
×
4026

4027
                        err = f.cfg.AliasManager.AddLocalAlias(
×
4028
                                alias, channel.ShortChannelID, false, false,
×
4029
                        )
×
4030
                        if err != nil {
×
4031
                                log.Errorf("unable to add local alias: %v",
×
4032
                                        err)
×
4033
                                return
×
4034
                        }
×
4035

4036
                        secondPoint, err := channel.SecondCommitmentPoint()
×
4037
                        if err != nil {
×
4038
                                log.Errorf("unable to fetch second "+
×
4039
                                        "commitment point: %v", err)
×
4040
                                return
×
4041
                        }
×
4042

4043
                        channelReadyMsg := lnwire.NewChannelReady(
×
4044
                                chanID, secondPoint,
×
4045
                        )
×
4046
                        channelReadyMsg.AliasScid = &alias
×
4047

×
4048
                        if firstVerNonce != nil {
×
4049
                                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce( //nolint:ll
×
4050
                                        firstVerNonce.PubNonce,
×
4051
                                )
×
4052
                        }
×
4053

4054
                        err = peer.SendMessage(true, channelReadyMsg)
×
4055
                        if err != nil {
×
4056
                                log.Errorf("unable to send channel_ready: %v",
×
4057
                                        err)
×
4058
                                return
×
4059
                        }
×
4060
                }
4061
        }
4062

4063
        // If the RemoteNextRevocation is non-nil, it means that we have
4064
        // already processed channelReady for this channel, so ignore. This
4065
        // check is after the alias logic so we store the peer's most recent
4066
        // alias. The spec requires us to validate that subsequent
4067
        // channel_ready messages use the same per commitment point (the
4068
        // second), but it is not actually necessary since we'll just end up
4069
        // ignoring it. We are, however, required to *send* the same per
4070
        // commitment point, since another pedantic implementation might
4071
        // verify it.
4072
        if channel.RemoteNextRevocation != nil {
6✔
4073
                log.Infof("Received duplicate channelReady for "+
3✔
4074
                        "ChannelID(%v), ignoring.", chanID)
3✔
4075
                return
3✔
4076
        }
3✔
4077

4078
        // If this is a taproot channel, then we'll need to map the received
4079
        // nonces to a nonce pair, and also fetch our pending nonces, which are
4080
        // required in order to make the channel whole.
4081
        var chanOpts []lnwallet.ChannelOpt
3✔
4082
        if channel.ChanType.IsTaproot() {
6✔
4083
                f.nonceMtx.Lock()
3✔
4084
                localNonce, ok := f.pendingMusigNonces[chanID]
3✔
4085
                if !ok {
6✔
4086
                        // If there's no pending nonce for this channel ID,
3✔
4087
                        // we'll use the one generated above.
3✔
4088
                        localNonce = firstVerNonce
3✔
4089
                        f.pendingMusigNonces[chanID] = firstVerNonce
3✔
4090
                }
3✔
4091
                f.nonceMtx.Unlock()
3✔
4092

3✔
4093
                log.Infof("ChanID(%v): applying local+remote musig2 nonces",
3✔
4094
                        chanID)
3✔
4095

3✔
4096
                remoteNonce, err := msg.NextLocalNonce.UnwrapOrErrV(
3✔
4097
                        errNoLocalNonce,
3✔
4098
                )
3✔
4099
                if err != nil {
3✔
4100
                        cid := newChanIdentifier(msg.ChanID)
×
4101
                        f.sendWarning(peer, cid, err)
×
4102

×
4103
                        return
×
4104
                }
×
4105

4106
                chanOpts = append(
3✔
4107
                        chanOpts,
3✔
4108
                        lnwallet.WithLocalMusigNonces(localNonce),
3✔
4109
                        lnwallet.WithRemoteMusigNonces(&musig2.Nonces{
3✔
4110
                                PubNonce: remoteNonce,
3✔
4111
                        }),
3✔
4112
                )
3✔
4113

3✔
4114
                // Inform the aux funding controller that the liquidity in the
3✔
4115
                // custom channel is now ready to be advertised. We potentially
3✔
4116
                // haven't sent our own channel ready message yet, but other
3✔
4117
                // than that the channel is ready to count toward available
3✔
4118
                // liquidity.
3✔
4119
                err = fn.MapOptionZ(
3✔
4120
                        f.cfg.AuxFundingController,
3✔
4121
                        func(controller AuxFundingController) error {
3✔
4122
                                return controller.ChannelReady(
×
4123
                                        lnwallet.NewAuxChanState(channel),
×
4124
                                )
×
4125
                        },
×
4126
                )
4127
                if err != nil {
3✔
4128
                        cid := newChanIdentifier(msg.ChanID)
×
4129
                        f.sendWarning(peer, cid, err)
×
4130

×
4131
                        return
×
4132
                }
×
4133
        }
4134

4135
        // The channel_ready message contains the next commitment point we'll
4136
        // need to create the next commitment state for the remote party. So
4137
        // we'll insert that into the channel now before passing it along to
4138
        // other sub-systems.
4139
        err = channel.InsertNextRevocation(msg.NextPerCommitmentPoint)
3✔
4140
        if err != nil {
3✔
4141
                log.Errorf("unable to insert next commitment point: %v", err)
×
4142
                return
×
4143
        }
×
4144

4145
        // Before we can add the channel to the peer, we'll need to ensure that
4146
        // we have an initial forwarding policy set.
4147
        if err := f.ensureInitialForwardingPolicy(chanID, channel); err != nil {
3✔
4148
                log.Errorf("Unable to ensure initial forwarding policy: %v",
×
4149
                        err)
×
4150
        }
×
4151

4152
        err = peer.AddNewChannel(&lnpeer.NewChannel{
3✔
4153
                OpenChannel: channel,
3✔
4154
                ChanOpts:    chanOpts,
3✔
4155
        }, f.quit)
3✔
4156
        if err != nil {
3✔
4157
                log.Errorf("Unable to add new channel %v with peer %x: %v",
×
4158
                        channel.FundingOutpoint,
×
4159
                        peer.IdentityKey().SerializeCompressed(), err,
×
4160
                )
×
4161
        }
×
4162
}
4163

4164
// handleChannelReadyReceived is called once the remote's channelReady message
4165
// is received and processed. At this stage, we must have sent out our
4166
// channelReady message, once the remote's channelReady is processed, the
4167
// channel is now active, thus we change its state to `addedToGraph` to
4168
// let the channel start handling routing.
4169
func (f *Manager) handleChannelReadyReceived(channel *channeldb.OpenChannel,
4170
        scid *lnwire.ShortChannelID, pendingChanID PendingChanID,
4171
        updateChan chan<- *lnrpc.OpenStatusUpdate) error {
3✔
4172

3✔
4173
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
3✔
4174

3✔
4175
        // Since we've sent+received funding locked at this point, we
3✔
4176
        // can clean up the pending musig2 nonce state.
3✔
4177
        f.nonceMtx.Lock()
3✔
4178
        delete(f.pendingMusigNonces, chanID)
3✔
4179
        f.nonceMtx.Unlock()
3✔
4180

3✔
4181
        var peerAlias *lnwire.ShortChannelID
3✔
4182
        if channel.IsZeroConf() {
6✔
4183
                // We'll need to wait until channel_ready has been received and
3✔
4184
                // the peer lets us know the alias they want to use for the
3✔
4185
                // channel. With this information, we can then construct a
3✔
4186
                // ChannelUpdate for them.  If an alias does not yet exist,
3✔
4187
                // we'll just return, letting the next iteration of the loop
3✔
4188
                // check again.
3✔
4189
                var defaultAlias lnwire.ShortChannelID
3✔
4190
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
3✔
4191
                foundAlias, _ := f.cfg.AliasManager.GetPeerAlias(chanID)
3✔
4192
                if foundAlias == defaultAlias {
3✔
4193
                        return nil
×
4194
                }
×
4195

4196
                peerAlias = &foundAlias
3✔
4197
        }
4198

4199
        err := f.addToGraph(channel, scid, peerAlias, nil)
3✔
4200
        if err != nil {
3✔
4201
                return fmt.Errorf("failed adding to graph: %w", err)
×
4202
        }
×
4203

4204
        // As the channel is now added to the ChannelRouter's topology, the
4205
        // channel is moved to the next state of the state machine. It will be
4206
        // moved to the last state (actually deleted from the database) after
4207
        // the channel is finally announced.
4208
        err = f.saveChannelOpeningState(
3✔
4209
                &channel.FundingOutpoint, addedToGraph, scid,
3✔
4210
        )
3✔
4211
        if err != nil {
3✔
4212
                return fmt.Errorf("error setting channel state to"+
×
4213
                        " addedToGraph: %w", err)
×
4214
        }
×
4215

4216
        log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
3✔
4217
                "added to graph", chanID, scid)
3✔
4218

3✔
4219
        err = fn.MapOptionZ(
3✔
4220
                f.cfg.AuxFundingController,
3✔
4221
                func(controller AuxFundingController) error {
3✔
4222
                        return controller.ChannelReady(
×
4223
                                lnwallet.NewAuxChanState(channel),
×
4224
                        )
×
4225
                },
×
4226
        )
4227
        if err != nil {
3✔
4228
                return fmt.Errorf("failed notifying aux funding controller "+
×
4229
                        "about channel ready: %w", err)
×
4230
        }
×
4231

4232
        // Give the caller a final update notifying them that the channel is
4233
        fundingPoint := channel.FundingOutpoint
3✔
4234
        cp := &lnrpc.ChannelPoint{
3✔
4235
                FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
3✔
4236
                        FundingTxidBytes: fundingPoint.Hash[:],
3✔
4237
                },
3✔
4238
                OutputIndex: fundingPoint.Index,
3✔
4239
        }
3✔
4240

3✔
4241
        if updateChan != nil {
6✔
4242
                upd := &lnrpc.OpenStatusUpdate{
3✔
4243
                        Update: &lnrpc.OpenStatusUpdate_ChanOpen{
3✔
4244
                                ChanOpen: &lnrpc.ChannelOpenUpdate{
3✔
4245
                                        ChannelPoint: cp,
3✔
4246
                                },
3✔
4247
                        },
3✔
4248
                        PendingChanId: pendingChanID[:],
3✔
4249
                }
3✔
4250

3✔
4251
                select {
3✔
4252
                case updateChan <- upd:
3✔
4253
                case <-f.quit:
×
4254
                        return ErrFundingManagerShuttingDown
×
4255
                }
4256
        }
4257

4258
        return nil
3✔
4259
}
4260

4261
// ensureInitialForwardingPolicy ensures that we have an initial forwarding
4262
// policy set for the given channel. If we don't, we'll fall back to the default
4263
// values.
4264
func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID,
4265
        channel *channeldb.OpenChannel) error {
3✔
4266

3✔
4267
        // Before we can add the channel to the peer, we'll need to ensure that
3✔
4268
        // we have an initial forwarding policy set. This should always be the
3✔
4269
        // case except for a channel that was created with lnd <= 0.15.5 and
3✔
4270
        // is still pending while updating to this version.
3✔
4271
        var needDBUpdate bool
3✔
4272
        forwardingPolicy, err := f.getInitialForwardingPolicy(chanID)
3✔
4273
        if err != nil {
3✔
4274
                log.Errorf("Unable to fetch initial forwarding policy, "+
×
4275
                        "falling back to default values: %v", err)
×
4276

×
4277
                forwardingPolicy = f.defaultForwardingPolicy(
×
4278
                        channel.LocalChanCfg.ChannelStateBounds,
×
4279
                )
×
4280
                needDBUpdate = true
×
4281
        }
×
4282

4283
        // We only started storing the actual values for MinHTLCOut and MaxHTLC
4284
        // after 0.16.x, so if a channel was opened with such a version and is
4285
        // still pending while updating to this version, we'll need to set the
4286
        // values to the default values.
4287
        if forwardingPolicy.MinHTLCOut == 0 {
6✔
4288
                forwardingPolicy.MinHTLCOut = channel.LocalChanCfg.MinHTLC
3✔
4289
                needDBUpdate = true
3✔
4290
        }
3✔
4291
        if forwardingPolicy.MaxHTLC == 0 {
6✔
4292
                forwardingPolicy.MaxHTLC = channel.LocalChanCfg.MaxPendingAmount
3✔
4293
                needDBUpdate = true
3✔
4294
        }
3✔
4295

4296
        // And finally, if we found that the values currently stored aren't
4297
        // sufficient for the link, we'll update the database.
4298
        if needDBUpdate {
6✔
4299
                err := f.saveInitialForwardingPolicy(chanID, forwardingPolicy)
3✔
4300
                if err != nil {
3✔
4301
                        return fmt.Errorf("unable to update initial "+
×
4302
                                "forwarding policy: %v", err)
×
4303
                }
×
4304
        }
4305

4306
        return nil
3✔
4307
}
4308

4309
// chanAnnouncement encapsulates the two authenticated announcements that we
4310
// send out to the network after a new channel has been created locally.
4311
type chanAnnouncement struct {
4312
        chanAnn       *lnwire.ChannelAnnouncement1
4313
        chanUpdateAnn *lnwire.ChannelUpdate1
4314
        chanProof     *lnwire.AnnounceSignatures1
4315
}
4316

4317
// newChanAnnouncement creates the authenticated channel announcement messages
4318
// required to broadcast a newly created channel to the network. The
4319
// announcement is two part: the first part authenticates the existence of the
4320
// channel and contains four signatures binding the funding pub keys and
4321
// identity pub keys of both parties to the channel, and the second segment is
4322
// authenticated only by us and contains our directional routing policy for the
4323
// channel. ourPolicy may be set in order to re-use an existing, non-default
4324
// policy.
4325
func (f *Manager) newChanAnnouncement(localPubKey,
4326
        remotePubKey *btcec.PublicKey, localFundingKey *keychain.KeyDescriptor,
4327
        remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
4328
        chanID lnwire.ChannelID, fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi,
4329
        ourPolicy *models.ChannelEdgePolicy,
4330
        chanType channeldb.ChannelType) (*chanAnnouncement, error) {
3✔
4331

3✔
4332
        chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
3✔
4333

3✔
4334
        // The unconditional section of the announcement is the ShortChannelID
3✔
4335
        // itself which compactly encodes the location of the funding output
3✔
4336
        // within the blockchain.
3✔
4337
        chanAnn := &lnwire.ChannelAnnouncement1{
3✔
4338
                ShortChannelID: shortChanID,
3✔
4339
                Features:       lnwire.NewRawFeatureVector(),
3✔
4340
                ChainHash:      chainHash,
3✔
4341
        }
3✔
4342

3✔
4343
        // If this is a taproot channel, then we'll set a special bit in the
3✔
4344
        // feature vector to indicate to the routing layer that this needs a
3✔
4345
        // slightly different type of validation.
3✔
4346
        //
3✔
4347
        // TODO(roasbeef): temp, remove after gossip 1.5
3✔
4348
        if chanType.IsTaproot() {
6✔
4349
                log.Debugf("Applying taproot feature bit to "+
3✔
4350
                        "ChannelAnnouncement for %v", chanID)
3✔
4351

3✔
4352
                chanAnn.Features.Set(
3✔
4353
                        lnwire.SimpleTaprootChannelsRequiredStaging,
3✔
4354
                )
3✔
4355
        }
3✔
4356

4357
        // The chanFlags field indicates which directed edge of the channel is
4358
        // being updated within the ChannelUpdateAnnouncement announcement
4359
        // below. A value of zero means it's the edge of the "first" node and 1
4360
        // being the other node.
4361
        var chanFlags lnwire.ChanUpdateChanFlags
3✔
4362

3✔
4363
        // The lexicographical ordering of the two identity public keys of the
3✔
4364
        // nodes indicates which of the nodes is "first". If our serialized
3✔
4365
        // identity key is lower than theirs then we're the "first" node and
3✔
4366
        // second otherwise.
3✔
4367
        selfBytes := localPubKey.SerializeCompressed()
3✔
4368
        remoteBytes := remotePubKey.SerializeCompressed()
3✔
4369
        if bytes.Compare(selfBytes, remoteBytes) == -1 {
6✔
4370
                copy(chanAnn.NodeID1[:], localPubKey.SerializeCompressed())
3✔
4371
                copy(chanAnn.NodeID2[:], remotePubKey.SerializeCompressed())
3✔
4372
                copy(
3✔
4373
                        chanAnn.BitcoinKey1[:],
3✔
4374
                        localFundingKey.PubKey.SerializeCompressed(),
3✔
4375
                )
3✔
4376
                copy(
3✔
4377
                        chanAnn.BitcoinKey2[:],
3✔
4378
                        remoteFundingKey.SerializeCompressed(),
3✔
4379
                )
3✔
4380

3✔
4381
                // If we're the first node then update the chanFlags to
3✔
4382
                // indicate the "direction" of the update.
3✔
4383
                chanFlags = 0
3✔
4384
        } else {
6✔
4385
                copy(chanAnn.NodeID1[:], remotePubKey.SerializeCompressed())
3✔
4386
                copy(chanAnn.NodeID2[:], localPubKey.SerializeCompressed())
3✔
4387
                copy(
3✔
4388
                        chanAnn.BitcoinKey1[:],
3✔
4389
                        remoteFundingKey.SerializeCompressed(),
3✔
4390
                )
3✔
4391
                copy(
3✔
4392
                        chanAnn.BitcoinKey2[:],
3✔
4393
                        localFundingKey.PubKey.SerializeCompressed(),
3✔
4394
                )
3✔
4395

3✔
4396
                // If we're the second node then update the chanFlags to
3✔
4397
                // indicate the "direction" of the update.
3✔
4398
                chanFlags = 1
3✔
4399
        }
3✔
4400

4401
        // Our channel update message flags will signal that we support the
4402
        // max_htlc field.
4403
        msgFlags := lnwire.ChanUpdateRequiredMaxHtlc
3✔
4404

3✔
4405
        // We announce the channel with the default values. Some of
3✔
4406
        // these values can later be changed by crafting a new ChannelUpdate.
3✔
4407
        chanUpdateAnn := &lnwire.ChannelUpdate1{
3✔
4408
                ShortChannelID: shortChanID,
3✔
4409
                ChainHash:      chainHash,
3✔
4410
                Timestamp:      uint32(time.Now().Unix()),
3✔
4411
                MessageFlags:   msgFlags,
3✔
4412
                ChannelFlags:   chanFlags,
3✔
4413
                TimeLockDelta: uint16(
3✔
4414
                        f.cfg.DefaultRoutingPolicy.TimeLockDelta,
3✔
4415
                ),
3✔
4416
                HtlcMinimumMsat: fwdMinHTLC,
3✔
4417
                HtlcMaximumMsat: fwdMaxHTLC,
3✔
4418
        }
3✔
4419

3✔
4420
        // The caller of newChanAnnouncement is expected to provide the initial
3✔
4421
        // forwarding policy to be announced. If no persisted initial policy
3✔
4422
        // values are found, then we will use the default policy values in the
3✔
4423
        // channel announcement.
3✔
4424
        storedFwdingPolicy, err := f.getInitialForwardingPolicy(chanID)
3✔
4425
        if err != nil && !errors.Is(err, channeldb.ErrChannelNotFound) {
3✔
4426
                return nil, errors.Errorf("unable to generate channel "+
×
4427
                        "update announcement: %v", err)
×
4428
        }
×
4429

4430
        switch {
3✔
4431
        case ourPolicy != nil:
3✔
4432
                // If ourPolicy is non-nil, modify the default parameters of the
3✔
4433
                // ChannelUpdate.
3✔
4434
                chanUpdateAnn.MessageFlags = ourPolicy.MessageFlags
3✔
4435
                chanUpdateAnn.ChannelFlags = ourPolicy.ChannelFlags
3✔
4436
                chanUpdateAnn.TimeLockDelta = ourPolicy.TimeLockDelta
3✔
4437
                chanUpdateAnn.HtlcMinimumMsat = ourPolicy.MinHTLC
3✔
4438
                chanUpdateAnn.HtlcMaximumMsat = ourPolicy.MaxHTLC
3✔
4439
                chanUpdateAnn.BaseFee = uint32(ourPolicy.FeeBaseMSat)
3✔
4440
                chanUpdateAnn.FeeRate = uint32(
3✔
4441
                        ourPolicy.FeeProportionalMillionths,
3✔
4442
                )
3✔
4443

4444
        case storedFwdingPolicy != nil:
3✔
4445
                chanUpdateAnn.BaseFee = uint32(storedFwdingPolicy.BaseFee)
3✔
4446
                chanUpdateAnn.FeeRate = uint32(storedFwdingPolicy.FeeRate)
3✔
4447

4448
        default:
×
4449
                log.Infof("No channel forwarding policy specified for channel "+
×
4450
                        "announcement of ChannelID(%v). "+
×
4451
                        "Assuming default fee parameters.", chanID)
×
4452
                chanUpdateAnn.BaseFee = uint32(
×
4453
                        f.cfg.DefaultRoutingPolicy.BaseFee,
×
4454
                )
×
4455
                chanUpdateAnn.FeeRate = uint32(
×
4456
                        f.cfg.DefaultRoutingPolicy.FeeRate,
×
4457
                )
×
4458
        }
4459

4460
        // With the channel update announcement constructed, we'll generate a
4461
        // signature that signs a double-sha digest of the announcement.
4462
        // This'll serve to authenticate this announcement and any other future
4463
        // updates we may send.
4464
        chanUpdateMsg, err := chanUpdateAnn.DataToSign()
3✔
4465
        if err != nil {
3✔
4466
                return nil, err
×
4467
        }
×
4468
        sig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanUpdateMsg, true)
3✔
4469
        if err != nil {
3✔
4470
                return nil, errors.Errorf("unable to generate channel "+
×
4471
                        "update announcement signature: %v", err)
×
4472
        }
×
4473
        chanUpdateAnn.Signature, err = lnwire.NewSigFromSignature(sig)
3✔
4474
        if err != nil {
3✔
4475
                return nil, errors.Errorf("unable to generate channel "+
×
4476
                        "update announcement signature: %v", err)
×
4477
        }
×
4478

4479
        // The channel existence proofs itself is currently announced in
4480
        // distinct message. In order to properly authenticate this message, we
4481
        // need two signatures: one under the identity public key used which
4482
        // signs the message itself and another signature of the identity
4483
        // public key under the funding key itself.
4484
        //
4485
        // TODO(roasbeef): use SignAnnouncement here instead?
4486
        chanAnnMsg, err := chanAnn.DataToSign()
3✔
4487
        if err != nil {
3✔
4488
                return nil, err
×
4489
        }
×
4490
        nodeSig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanAnnMsg, true)
3✔
4491
        if err != nil {
3✔
4492
                return nil, errors.Errorf("unable to generate node "+
×
4493
                        "signature for channel announcement: %v", err)
×
4494
        }
×
4495
        bitcoinSig, err := f.cfg.SignMessage(
3✔
4496
                localFundingKey.KeyLocator, chanAnnMsg, true,
3✔
4497
        )
3✔
4498
        if err != nil {
3✔
4499
                return nil, errors.Errorf("unable to generate bitcoin "+
×
4500
                        "signature for node public key: %v", err)
×
4501
        }
×
4502

4503
        // Finally, we'll generate the announcement proof which we'll use to
4504
        // provide the other side with the necessary signatures required to
4505
        // allow them to reconstruct the full channel announcement.
4506
        proof := &lnwire.AnnounceSignatures1{
3✔
4507
                ChannelID:      chanID,
3✔
4508
                ShortChannelID: shortChanID,
3✔
4509
        }
3✔
4510
        proof.NodeSignature, err = lnwire.NewSigFromSignature(nodeSig)
3✔
4511
        if err != nil {
3✔
4512
                return nil, err
×
4513
        }
×
4514
        proof.BitcoinSignature, err = lnwire.NewSigFromSignature(bitcoinSig)
3✔
4515
        if err != nil {
3✔
4516
                return nil, err
×
4517
        }
×
4518

4519
        return &chanAnnouncement{
3✔
4520
                chanAnn:       chanAnn,
3✔
4521
                chanUpdateAnn: chanUpdateAnn,
3✔
4522
                chanProof:     proof,
3✔
4523
        }, nil
3✔
4524
}
4525

4526
// announceChannel announces a newly created channel to the rest of the network
4527
// by crafting the two authenticated announcements required for the peers on
4528
// the network to recognize the legitimacy of the channel. The crafted
4529
// announcements are then sent to the channel router to handle broadcasting to
4530
// the network during its next trickle.
4531
// This method is synchronous and will return when all the network requests
4532
// finish, either successfully or with an error.
4533
func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
4534
        localFundingKey *keychain.KeyDescriptor,
4535
        remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
4536
        chanID lnwire.ChannelID, chanType channeldb.ChannelType) error {
3✔
4537

3✔
4538
        // First, we'll create the batch of announcements to be sent upon
3✔
4539
        // initial channel creation. This includes the channel announcement
3✔
4540
        // itself, the channel update announcement, and our half of the channel
3✔
4541
        // proof needed to fully authenticate the channel.
3✔
4542
        //
3✔
4543
        // We can pass in zeroes for the min and max htlc policy, because we
3✔
4544
        // only use the channel announcement message from the returned struct.
3✔
4545
        ann, err := f.newChanAnnouncement(
3✔
4546
                localIDKey, remoteIDKey, localFundingKey, remoteFundingKey,
3✔
4547
                shortChanID, chanID, 0, 0, nil, chanType,
3✔
4548
        )
3✔
4549
        if err != nil {
3✔
4550
                log.Errorf("can't generate channel announcement: %v", err)
×
4551
                return err
×
4552
        }
×
4553

4554
        // We only send the channel proof announcement and the node announcement
4555
        // because addToGraph previously sent the ChannelAnnouncement and
4556
        // the ChannelUpdate announcement messages. The channel proof and node
4557
        // announcements are broadcast to the greater network.
4558
        errChan := f.cfg.SendAnnouncement(ann.chanProof)
3✔
4559
        select {
3✔
4560
        case err := <-errChan:
3✔
4561
                if err != nil {
6✔
4562
                        if graph.IsError(err, graph.ErrOutdated,
3✔
4563
                                graph.ErrIgnored) {
3✔
4564

×
4565
                                log.Debugf("Graph rejected "+
×
4566
                                        "AnnounceSignatures: %v", err)
×
4567
                        } else {
3✔
4568
                                log.Errorf("Unable to send channel "+
3✔
4569
                                        "proof: %v", err)
3✔
4570
                                return err
3✔
4571
                        }
3✔
4572
                }
4573

4574
        case <-f.quit:
×
4575
                return ErrFundingManagerShuttingDown
×
4576
        }
4577

4578
        // Now that the channel is announced to the network, we will also
4579
        // obtain and send a node announcement. This is done since a node
4580
        // announcement is only accepted after a channel is known for that
4581
        // particular node, and this might be our first channel.
4582
        nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
3✔
4583
        if err != nil {
3✔
4584
                log.Errorf("can't generate node announcement: %v", err)
×
4585
                return err
×
4586
        }
×
4587

4588
        errChan = f.cfg.SendAnnouncement(&nodeAnn)
3✔
4589
        select {
3✔
4590
        case err := <-errChan:
3✔
4591
                if err != nil {
6✔
4592
                        if graph.IsError(err, graph.ErrOutdated,
3✔
4593
                                graph.ErrIgnored) {
6✔
4594

3✔
4595
                                log.Debugf("Graph rejected "+
3✔
4596
                                        "NodeAnnouncement: %v", err)
3✔
4597
                        } else {
3✔
4598
                                log.Errorf("Unable to send node "+
×
4599
                                        "announcement: %v", err)
×
4600
                                return err
×
4601
                        }
×
4602
                }
4603

4604
        case <-f.quit:
×
4605
                return ErrFundingManagerShuttingDown
×
4606
        }
4607

4608
        return nil
3✔
4609
}
4610

4611
// InitFundingWorkflow sends a message to the funding manager instructing it
4612
// to initiate a single funder workflow with the source peer.
4613
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
3✔
4614
        f.fundingRequests <- msg
3✔
4615
}
3✔
4616

4617
// getUpfrontShutdownScript takes a user provided script and a getScript
4618
// function which can be used to generate an upfront shutdown script. If our
4619
// peer does not support the feature, this function will error if a non-zero
4620
// script was provided by the user, and return an empty script otherwise. If
4621
// our peer does support the feature, we will return the user provided script
4622
// if non-zero, or a freshly generated script if our node is configured to set
4623
// upfront shutdown scripts automatically.
4624
func getUpfrontShutdownScript(enableUpfrontShutdown bool, peer lnpeer.Peer,
4625
        script lnwire.DeliveryAddress,
4626
        getScript func(bool) (lnwire.DeliveryAddress, error)) (lnwire.DeliveryAddress,
4627
        error) {
3✔
4628

3✔
4629
        // Check whether the remote peer supports upfront shutdown scripts.
3✔
4630
        remoteUpfrontShutdown := peer.RemoteFeatures().HasFeature(
3✔
4631
                lnwire.UpfrontShutdownScriptOptional,
3✔
4632
        )
3✔
4633

3✔
4634
        // If the peer does not support upfront shutdown scripts, and one has been
3✔
4635
        // provided, return an error because the feature is not supported.
3✔
4636
        if !remoteUpfrontShutdown && len(script) != 0 {
3✔
UNCOV
4637
                return nil, errUpfrontShutdownScriptNotSupported
×
UNCOV
4638
        }
×
4639

4640
        // If the peer does not support upfront shutdown, return an empty address.
4641
        if !remoteUpfrontShutdown {
3✔
UNCOV
4642
                return nil, nil
×
UNCOV
4643
        }
×
4644

4645
        // If the user has provided an script and the peer supports the feature,
4646
        // return it. Note that user set scripts override the enable upfront
4647
        // shutdown flag.
4648
        if len(script) > 0 {
6✔
4649
                return script, nil
3✔
4650
        }
3✔
4651

4652
        // If we do not have setting of upfront shutdown script enabled, return
4653
        // an empty script.
4654
        if !enableUpfrontShutdown {
6✔
4655
                return nil, nil
3✔
4656
        }
3✔
4657

4658
        // We can safely send a taproot address iff, both sides have negotiated
4659
        // the shutdown-any-segwit feature.
UNCOV
4660
        taprootOK := peer.RemoteFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) &&
×
UNCOV
4661
                peer.LocalFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional)
×
UNCOV
4662

×
UNCOV
4663
        return getScript(taprootOK)
×
4664
}
4665

4666
// handleInitFundingMsg creates a channel reservation within the daemon's
4667
// wallet, then sends a funding request to the remote peer kicking off the
4668
// funding workflow.
4669
func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
3✔
4670
        var (
3✔
4671
                peerKey        = msg.Peer.IdentityKey()
3✔
4672
                localAmt       = msg.LocalFundingAmt
3✔
4673
                baseFee        = msg.BaseFee
3✔
4674
                feeRate        = msg.FeeRate
3✔
4675
                minHtlcIn      = msg.MinHtlcIn
3✔
4676
                remoteCsvDelay = msg.RemoteCsvDelay
3✔
4677
                maxValue       = msg.MaxValueInFlight
3✔
4678
                maxHtlcs       = msg.MaxHtlcs
3✔
4679
                maxCSV         = msg.MaxLocalCsv
3✔
4680
                chanReserve    = msg.RemoteChanReserve
3✔
4681
                outpoints      = msg.Outpoints
3✔
4682
        )
3✔
4683

3✔
4684
        // If no maximum CSV delay was set for this channel, we use our default
3✔
4685
        // value.
3✔
4686
        if maxCSV == 0 {
6✔
4687
                maxCSV = f.cfg.MaxLocalCSVDelay
3✔
4688
        }
3✔
4689

4690
        log.Infof("Initiating fundingRequest(local_amt=%v "+
3✔
4691
                "(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
3✔
4692
                "min_confs=%v)", localAmt, msg.SubtractFees, msg.PushAmt,
3✔
4693
                msg.ChainHash, peerKey.SerializeCompressed(), msg.MinConfs)
3✔
4694

3✔
4695
        // We set the channel flags to indicate whether we want this channel to
3✔
4696
        // be announced to the network.
3✔
4697
        var channelFlags lnwire.FundingFlag
3✔
4698
        if !msg.Private {
6✔
4699
                // This channel will be announced.
3✔
4700
                channelFlags = lnwire.FFAnnounceChannel
3✔
4701
        }
3✔
4702

4703
        // If the caller specified their own channel ID, then we'll use that.
4704
        // Otherwise we'll generate a fresh one as normal.  This will be used
4705
        // to track this reservation throughout its lifetime.
4706
        var chanID PendingChanID
3✔
4707
        if msg.PendingChanID == zeroID {
6✔
4708
                chanID = f.nextPendingChanID()
3✔
4709
        } else {
6✔
4710
                // If the user specified their own pending channel ID, then
3✔
4711
                // we'll ensure it doesn't collide with any existing pending
3✔
4712
                // channel ID.
3✔
4713
                chanID = msg.PendingChanID
3✔
4714
                if _, err := f.getReservationCtx(peerKey, chanID); err == nil {
3✔
4715
                        msg.Err <- fmt.Errorf("pendingChannelID(%x) "+
×
4716
                                "already present", chanID[:])
×
4717
                        return
×
4718
                }
×
4719
        }
4720

4721
        // Check whether the peer supports upfront shutdown, and get an address
4722
        // which should be used (either a user specified address or a new
4723
        // address from the wallet if our node is configured to set shutdown
4724
        // address by default).
4725
        shutdown, err := getUpfrontShutdownScript(
3✔
4726
                f.cfg.EnableUpfrontShutdown, msg.Peer, msg.ShutdownScript,
3✔
4727
                f.selectShutdownScript,
3✔
4728
        )
3✔
4729
        if err != nil {
3✔
4730
                msg.Err <- err
×
4731
                return
×
4732
        }
×
4733

4734
        // Initialize a funding reservation with the local wallet. If the
4735
        // wallet doesn't have enough funds to commit to this channel, then the
4736
        // request will fail, and be aborted.
4737
        //
4738
        // Before we init the channel, we'll also check to see what commitment
4739
        // format we can use with this peer. This is dependent on *both* us and
4740
        // the remote peer are signaling the proper feature bit.
4741
        chanType, commitType, err := negotiateCommitmentType(
3✔
4742
                msg.ChannelType, msg.Peer.LocalFeatures(),
3✔
4743
                msg.Peer.RemoteFeatures(),
3✔
4744
        )
3✔
4745
        if err != nil {
6✔
4746
                log.Errorf("channel type negotiation failed: %v", err)
3✔
4747
                msg.Err <- err
3✔
4748
                return
3✔
4749
        }
3✔
4750

4751
        var (
3✔
4752
                zeroConf bool
3✔
4753
                scid     bool
3✔
4754
        )
3✔
4755

3✔
4756
        if chanType != nil {
6✔
4757
                // Check if the returned chanType includes either the zero-conf
3✔
4758
                // or scid-alias bits.
3✔
4759
                featureVec := lnwire.RawFeatureVector(*chanType)
3✔
4760
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
3✔
4761
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
3✔
4762

3✔
4763
                // The option-scid-alias channel type for a public channel is
3✔
4764
                // disallowed.
3✔
4765
                if scid && !msg.Private {
3✔
4766
                        err = fmt.Errorf("option-scid-alias chantype for " +
×
4767
                                "public channel")
×
4768
                        log.Error(err)
×
4769
                        msg.Err <- err
×
4770

×
4771
                        return
×
4772
                }
×
4773
        }
4774

4775
        // First, we'll query the fee estimator for a fee that should get the
4776
        // commitment transaction confirmed by the next few blocks (conf target
4777
        // of 3). We target the near blocks here to ensure that we'll be able
4778
        // to execute a timely unilateral channel closure if needed.
4779
        commitFeePerKw, err := f.cfg.FeeEstimator.EstimateFeePerKW(3)
3✔
4780
        if err != nil {
3✔
4781
                msg.Err <- err
×
4782
                return
×
4783
        }
×
4784

4785
        // For anchor channels cap the initial commit fee rate at our defined
4786
        // maximum.
4787
        if commitType.HasAnchors() &&
3✔
4788
                commitFeePerKw > f.cfg.MaxAnchorsCommitFeeRate {
6✔
4789

3✔
4790
                commitFeePerKw = f.cfg.MaxAnchorsCommitFeeRate
3✔
4791
        }
3✔
4792

4793
        var scidFeatureVal bool
3✔
4794
        if hasFeatures(
3✔
4795
                msg.Peer.LocalFeatures(), msg.Peer.RemoteFeatures(),
3✔
4796
                lnwire.ScidAliasOptional,
3✔
4797
        ) {
6✔
4798

3✔
4799
                scidFeatureVal = true
3✔
4800
        }
3✔
4801

4802
        // At this point, if we have an AuxFundingController active, we'll check
4803
        // to see if we have a special tapscript root to use in our MuSig2
4804
        // funding output.
4805
        tapscriptRoot, err := fn.MapOptionZ(
3✔
4806
                f.cfg.AuxFundingController,
3✔
4807
                func(c AuxFundingController) AuxTapscriptResult {
3✔
4808
                        return c.DeriveTapscriptRoot(chanID)
×
4809
                },
×
4810
        ).Unpack()
4811
        if err != nil {
3✔
4812
                err = fmt.Errorf("error deriving tapscript root: %w", err)
×
4813
                log.Error(err)
×
4814
                msg.Err <- err
×
4815

×
4816
                return
×
4817
        }
×
4818

4819
        req := &lnwallet.InitFundingReserveMsg{
3✔
4820
                ChainHash:         &msg.ChainHash,
3✔
4821
                PendingChanID:     chanID,
3✔
4822
                NodeID:            peerKey,
3✔
4823
                NodeAddr:          msg.Peer.Address(),
3✔
4824
                SubtractFees:      msg.SubtractFees,
3✔
4825
                LocalFundingAmt:   localAmt,
3✔
4826
                RemoteFundingAmt:  0,
3✔
4827
                FundUpToMaxAmt:    msg.FundUpToMaxAmt,
3✔
4828
                MinFundAmt:        msg.MinFundAmt,
3✔
4829
                RemoteChanReserve: chanReserve,
3✔
4830
                Outpoints:         outpoints,
3✔
4831
                CommitFeePerKw:    commitFeePerKw,
3✔
4832
                FundingFeePerKw:   msg.FundingFeePerKw,
3✔
4833
                PushMSat:          msg.PushAmt,
3✔
4834
                Flags:             channelFlags,
3✔
4835
                MinConfs:          msg.MinConfs,
3✔
4836
                CommitType:        commitType,
3✔
4837
                ChanFunder:        msg.ChanFunder,
3✔
4838
                // Unconfirmed Utxos which are marked by the sweeper subsystem
3✔
4839
                // are excluded from the coin selection because they are not
3✔
4840
                // final and can be RBFed by the sweeper subsystem.
3✔
4841
                AllowUtxoForFunding: func(u lnwallet.Utxo) bool {
6✔
4842
                        // Utxos with at least 1 confirmation are safe to use
3✔
4843
                        // for channel openings because they don't bare the risk
3✔
4844
                        // of being replaced (BIP 125 RBF).
3✔
4845
                        if u.Confirmations > 0 {
6✔
4846
                                return true
3✔
4847
                        }
3✔
4848

4849
                        // Query the sweeper storage to make sure we don't use
4850
                        // an unconfirmed utxo still in use by the sweeper
4851
                        // subsystem.
4852
                        return !f.cfg.IsSweeperOutpoint(u.OutPoint)
3✔
4853
                },
4854
                ZeroConf:         zeroConf,
4855
                OptionScidAlias:  scid,
4856
                ScidAliasFeature: scidFeatureVal,
4857
                Memo:             msg.Memo,
4858
                TapscriptRoot:    tapscriptRoot,
4859
        }
4860

4861
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
3✔
4862
        if err != nil {
6✔
4863
                msg.Err <- err
3✔
4864
                return
3✔
4865
        }
3✔
4866

4867
        if zeroConf {
6✔
4868
                // Store the alias for zero-conf channels in the underlying
3✔
4869
                // partial channel state.
3✔
4870
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
3✔
4871
                if err != nil {
3✔
4872
                        msg.Err <- err
×
4873
                        return
×
4874
                }
×
4875

4876
                reservation.AddAlias(aliasScid)
3✔
4877
        }
4878

4879
        // Set our upfront shutdown address in the existing reservation.
4880
        reservation.SetOurUpfrontShutdown(shutdown)
3✔
4881

3✔
4882
        // Now that we have successfully reserved funds for this channel in the
3✔
4883
        // wallet, we can fetch the final channel capacity. This is done at
3✔
4884
        // this point since the final capacity might change in case of
3✔
4885
        // SubtractFees=true.
3✔
4886
        capacity := reservation.Capacity()
3✔
4887

3✔
4888
        log.Infof("Target commit tx sat/kw for pendingID(%x): %v", chanID,
3✔
4889
                int64(commitFeePerKw))
3✔
4890

3✔
4891
        // If the remote CSV delay was not set in the open channel request,
3✔
4892
        // we'll use the RequiredRemoteDelay closure to compute the delay we
3✔
4893
        // require given the total amount of funds within the channel.
3✔
4894
        if remoteCsvDelay == 0 {
6✔
4895
                remoteCsvDelay = f.cfg.RequiredRemoteDelay(capacity)
3✔
4896
        }
3✔
4897

4898
        // If no minimum HTLC value was specified, use the default one.
4899
        if minHtlcIn == 0 {
6✔
4900
                minHtlcIn = f.cfg.DefaultMinHtlcIn
3✔
4901
        }
3✔
4902

4903
        // If no max value was specified, use the default one.
4904
        if maxValue == 0 {
6✔
4905
                maxValue = f.cfg.RequiredRemoteMaxValue(capacity)
3✔
4906
        }
3✔
4907

4908
        if maxHtlcs == 0 {
6✔
4909
                maxHtlcs = f.cfg.RequiredRemoteMaxHTLCs(capacity)
3✔
4910
        }
3✔
4911

4912
        // Once the reservation has been created, and indexed, queue a funding
4913
        // request to the remote peer, kicking off the funding workflow.
4914
        ourContribution := reservation.OurContribution()
3✔
4915

3✔
4916
        // Prepare the optional channel fee values from the initFundingMsg. If
3✔
4917
        // useBaseFee or useFeeRate are false the client did not provide fee
3✔
4918
        // values hence we assume default fee settings from the config.
3✔
4919
        forwardingPolicy := f.defaultForwardingPolicy(
3✔
4920
                ourContribution.ChannelStateBounds,
3✔
4921
        )
3✔
4922
        if baseFee != nil {
6✔
4923
                forwardingPolicy.BaseFee = lnwire.MilliSatoshi(*baseFee)
3✔
4924
        }
3✔
4925

4926
        if feeRate != nil {
6✔
4927
                forwardingPolicy.FeeRate = lnwire.MilliSatoshi(*feeRate)
3✔
4928
        }
3✔
4929

4930
        // Fetch our dust limit which is part of the default channel
4931
        // constraints, and log it.
4932
        ourDustLimit := ourContribution.DustLimit
3✔
4933

3✔
4934
        log.Infof("Dust limit for pendingID(%x): %v", chanID, ourDustLimit)
3✔
4935

3✔
4936
        // If the channel reserve is not specified, then we calculate an
3✔
4937
        // appropriate amount here.
3✔
4938
        if chanReserve == 0 {
6✔
4939
                chanReserve = f.cfg.RequiredRemoteChanReserve(
3✔
4940
                        capacity, ourDustLimit,
3✔
4941
                )
3✔
4942
        }
3✔
4943

4944
        // If a pending channel map for this peer isn't already created, then
4945
        // we create one, ultimately allowing us to track this pending
4946
        // reservation within the target peer.
4947
        peerIDKey := newSerializedKey(peerKey)
3✔
4948
        f.resMtx.Lock()
3✔
4949
        if _, ok := f.activeReservations[peerIDKey]; !ok {
6✔
4950
                f.activeReservations[peerIDKey] = make(pendingChannels)
3✔
4951
        }
3✔
4952

4953
        resCtx := &reservationWithCtx{
3✔
4954
                chanAmt:           capacity,
3✔
4955
                forwardingPolicy:  *forwardingPolicy,
3✔
4956
                remoteCsvDelay:    remoteCsvDelay,
3✔
4957
                remoteMinHtlc:     minHtlcIn,
3✔
4958
                remoteMaxValue:    maxValue,
3✔
4959
                remoteMaxHtlcs:    maxHtlcs,
3✔
4960
                remoteChanReserve: chanReserve,
3✔
4961
                maxLocalCsv:       maxCSV,
3✔
4962
                channelType:       chanType,
3✔
4963
                reservation:       reservation,
3✔
4964
                peer:              msg.Peer,
3✔
4965
                updates:           msg.Updates,
3✔
4966
                err:               msg.Err,
3✔
4967
        }
3✔
4968
        f.activeReservations[peerIDKey][chanID] = resCtx
3✔
4969
        f.resMtx.Unlock()
3✔
4970

3✔
4971
        // Update the timestamp once the InitFundingMsg has been handled.
3✔
4972
        defer resCtx.updateTimestamp()
3✔
4973

3✔
4974
        // Check the sanity of the selected channel constraints.
3✔
4975
        bounds := &channeldb.ChannelStateBounds{
3✔
4976
                ChanReserve:      chanReserve,
3✔
4977
                MaxPendingAmount: maxValue,
3✔
4978
                MinHTLC:          minHtlcIn,
3✔
4979
                MaxAcceptedHtlcs: maxHtlcs,
3✔
4980
        }
3✔
4981
        commitParams := &channeldb.CommitmentParams{
3✔
4982
                DustLimit: ourDustLimit,
3✔
4983
                CsvDelay:  remoteCsvDelay,
3✔
4984
        }
3✔
4985
        err = lnwallet.VerifyConstraints(
3✔
4986
                bounds, commitParams, resCtx.maxLocalCsv, capacity,
3✔
4987
        )
3✔
4988
        if err != nil {
3✔
UNCOV
4989
                _, reserveErr := f.cancelReservationCtx(peerKey, chanID, false)
×
UNCOV
4990
                if reserveErr != nil {
×
4991
                        log.Errorf("unable to cancel reservation: %v",
×
4992
                                reserveErr)
×
4993
                }
×
4994

UNCOV
4995
                msg.Err <- err
×
UNCOV
4996
                return
×
4997
        }
4998

4999
        // When opening a script enforced channel lease, include the required
5000
        // expiry TLV record in our proposal.
5001
        var leaseExpiry *lnwire.LeaseExpiry
3✔
5002
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
6✔
5003
                leaseExpiry = new(lnwire.LeaseExpiry)
3✔
5004
                *leaseExpiry = lnwire.LeaseExpiry(reservation.LeaseExpiry())
3✔
5005
        }
3✔
5006

5007
        log.Infof("Starting funding workflow with %v for pending_id(%x), "+
3✔
5008
                "committype=%v", msg.Peer.Address(), chanID, commitType)
3✔
5009

3✔
5010
        reservation.SetState(lnwallet.SentOpenChannel)
3✔
5011

3✔
5012
        fundingOpen := lnwire.OpenChannel{
3✔
5013
                ChainHash:             *f.cfg.Wallet.Cfg.NetParams.GenesisHash,
3✔
5014
                PendingChannelID:      chanID,
3✔
5015
                FundingAmount:         capacity,
3✔
5016
                PushAmount:            msg.PushAmt,
3✔
5017
                DustLimit:             ourDustLimit,
3✔
5018
                MaxValueInFlight:      maxValue,
3✔
5019
                ChannelReserve:        chanReserve,
3✔
5020
                HtlcMinimum:           minHtlcIn,
3✔
5021
                FeePerKiloWeight:      uint32(commitFeePerKw),
3✔
5022
                CsvDelay:              remoteCsvDelay,
3✔
5023
                MaxAcceptedHTLCs:      maxHtlcs,
3✔
5024
                FundingKey:            ourContribution.MultiSigKey.PubKey,
3✔
5025
                RevocationPoint:       ourContribution.RevocationBasePoint.PubKey,
3✔
5026
                PaymentPoint:          ourContribution.PaymentBasePoint.PubKey,
3✔
5027
                HtlcPoint:             ourContribution.HtlcBasePoint.PubKey,
3✔
5028
                DelayedPaymentPoint:   ourContribution.DelayBasePoint.PubKey,
3✔
5029
                FirstCommitmentPoint:  ourContribution.FirstCommitmentPoint,
3✔
5030
                ChannelFlags:          channelFlags,
3✔
5031
                UpfrontShutdownScript: shutdown,
3✔
5032
                ChannelType:           chanType,
3✔
5033
                LeaseExpiry:           leaseExpiry,
3✔
5034
        }
3✔
5035

3✔
5036
        if commitType.IsTaproot() {
6✔
5037
                fundingOpen.LocalNonce = lnwire.SomeMusig2Nonce(
3✔
5038
                        ourContribution.LocalNonce.PubNonce,
3✔
5039
                )
3✔
5040
        }
3✔
5041

5042
        if err := msg.Peer.SendMessage(true, &fundingOpen); err != nil {
3✔
5043
                e := fmt.Errorf("unable to send funding request message: %w",
×
5044
                        err)
×
5045
                log.Errorf(e.Error())
×
5046

×
5047
                // Since we were unable to send the initial message to the peer
×
5048
                // and start the funding flow, we'll cancel this reservation.
×
5049
                _, err := f.cancelReservationCtx(peerKey, chanID, false)
×
5050
                if err != nil {
×
5051
                        log.Errorf("unable to cancel reservation: %v", err)
×
5052
                }
×
5053

5054
                msg.Err <- e
×
5055
                return
×
5056
        }
5057
}
5058

5059
// handleWarningMsg processes the warning which was received from remote peer.
UNCOV
5060
func (f *Manager) handleWarningMsg(peer lnpeer.Peer, msg *lnwire.Warning) {
×
UNCOV
5061
        log.Warnf("received warning message from peer %x: %v",
×
UNCOV
5062
                peer.IdentityKey().SerializeCompressed(), msg.Warning())
×
UNCOV
5063
}
×
5064

5065
// handleErrorMsg processes the error which was received from remote peer,
5066
// depending on the type of error we should do different clean up steps and
5067
// inform the user about it.
5068
func (f *Manager) handleErrorMsg(peer lnpeer.Peer, msg *lnwire.Error) {
3✔
5069
        chanID := msg.ChanID
3✔
5070
        peerKey := peer.IdentityKey()
3✔
5071

3✔
5072
        // First, we'll attempt to retrieve and cancel the funding workflow
3✔
5073
        // that this error was tied to. If we're unable to do so, then we'll
3✔
5074
        // exit early as this was an unwarranted error.
3✔
5075
        resCtx, err := f.cancelReservationCtx(peerKey, chanID, true)
3✔
5076
        if err != nil {
3✔
5077
                log.Warnf("Received error for non-existent funding "+
×
5078
                        "flow: %v (%v)", err, msg.Error())
×
5079
                return
×
5080
        }
×
5081

5082
        // If we did indeed find the funding workflow, then we'll return the
5083
        // error back to the caller (if any), and cancel the workflow itself.
5084
        fundingErr := fmt.Errorf("received funding error from %x: %v",
3✔
5085
                peerKey.SerializeCompressed(), msg.Error(),
3✔
5086
        )
3✔
5087
        log.Errorf(fundingErr.Error())
3✔
5088

3✔
5089
        // If this was a PSBT funding flow, the remote likely timed out because
3✔
5090
        // we waited too long. Return a nice error message to the user in that
3✔
5091
        // case so the user knows what's the problem.
3✔
5092
        if resCtx.reservation.IsPsbt() {
6✔
5093
                fundingErr = fmt.Errorf("%w: %v", chanfunding.ErrRemoteCanceled,
3✔
5094
                        fundingErr)
3✔
5095
        }
3✔
5096

5097
        resCtx.err <- fundingErr
3✔
5098
}
5099

5100
// pruneZombieReservations loops through all pending reservations and fails the
5101
// funding flow for any reservations that have not been updated since the
5102
// ReservationTimeout and are not locked waiting for the funding transaction.
5103
func (f *Manager) pruneZombieReservations() {
3✔
5104
        zombieReservations := make(pendingChannels)
3✔
5105

3✔
5106
        f.resMtx.RLock()
3✔
5107
        for _, pendingReservations := range f.activeReservations {
6✔
5108
                for pendingChanID, resCtx := range pendingReservations {
6✔
5109
                        if resCtx.isLocked() {
3✔
5110
                                continue
×
5111
                        }
5112

5113
                        // We don't want to expire PSBT funding reservations.
5114
                        // These reservations are always initiated by us and the
5115
                        // remote peer is likely going to cancel them after some
5116
                        // idle time anyway. So no need for us to also prune
5117
                        // them.
5118
                        sinceLastUpdate := time.Since(resCtx.lastUpdated)
3✔
5119
                        isExpired := sinceLastUpdate > f.cfg.ReservationTimeout
3✔
5120
                        if !resCtx.reservation.IsPsbt() && isExpired {
6✔
5121
                                zombieReservations[pendingChanID] = resCtx
3✔
5122
                        }
3✔
5123
                }
5124
        }
5125
        f.resMtx.RUnlock()
3✔
5126

3✔
5127
        for pendingChanID, resCtx := range zombieReservations {
6✔
5128
                err := fmt.Errorf("reservation timed out waiting for peer "+
3✔
5129
                        "(peer_id:%x, chan_id:%x)",
3✔
5130
                        resCtx.peer.IdentityKey().SerializeCompressed(),
3✔
5131
                        pendingChanID[:])
3✔
5132
                log.Warnf(err.Error())
3✔
5133

3✔
5134
                chanID := lnwire.NewChanIDFromOutPoint(
3✔
5135
                        *resCtx.reservation.FundingOutpoint(),
3✔
5136
                )
3✔
5137

3✔
5138
                // Create channel identifier and set the channel ID.
3✔
5139
                cid := newChanIdentifier(pendingChanID)
3✔
5140
                cid.setChanID(chanID)
3✔
5141

3✔
5142
                f.failFundingFlow(resCtx.peer, cid, err)
3✔
5143
        }
3✔
5144
}
5145

5146
// cancelReservationCtx does all needed work in order to securely cancel the
5147
// reservation.
5148
func (f *Manager) cancelReservationCtx(peerKey *btcec.PublicKey,
5149
        pendingChanID PendingChanID,
5150
        byRemote bool) (*reservationWithCtx, error) {
3✔
5151

3✔
5152
        log.Infof("Cancelling funding reservation for node_key=%x, "+
3✔
5153
                "chan_id=%x", peerKey.SerializeCompressed(), pendingChanID[:])
3✔
5154

3✔
5155
        peerIDKey := newSerializedKey(peerKey)
3✔
5156
        f.resMtx.Lock()
3✔
5157
        defer f.resMtx.Unlock()
3✔
5158

3✔
5159
        nodeReservations, ok := f.activeReservations[peerIDKey]
3✔
5160
        if !ok {
6✔
5161
                // No reservations for this node.
3✔
5162
                return nil, errors.Errorf("no active reservations for peer(%x)",
3✔
5163
                        peerIDKey[:])
3✔
5164
        }
3✔
5165

5166
        ctx, ok := nodeReservations[pendingChanID]
3✔
5167
        if !ok {
3✔
UNCOV
5168
                return nil, errors.Errorf("unknown channel (id: %x) for "+
×
UNCOV
5169
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
×
UNCOV
5170
        }
×
5171

5172
        // If the reservation was a PSBT funding flow and it was canceled by the
5173
        // remote peer, then we need to thread through a different error message
5174
        // to the subroutine that's waiting for the user input so it can return
5175
        // a nice error message to the user.
5176
        if ctx.reservation.IsPsbt() && byRemote {
6✔
5177
                ctx.reservation.RemoteCanceled()
3✔
5178
        }
3✔
5179

5180
        if err := ctx.reservation.Cancel(); err != nil {
3✔
5181
                return nil, errors.Errorf("unable to cancel reservation: %v",
×
5182
                        err)
×
5183
        }
×
5184

5185
        delete(nodeReservations, pendingChanID)
3✔
5186

3✔
5187
        // If this was the last active reservation for this peer, delete the
3✔
5188
        // peer's entry altogether.
3✔
5189
        if len(nodeReservations) == 0 {
6✔
5190
                delete(f.activeReservations, peerIDKey)
3✔
5191
        }
3✔
5192
        return ctx, nil
3✔
5193
}
5194

5195
// deleteReservationCtx deletes the reservation uniquely identified by the
5196
// target public key of the peer, and the specified pending channel ID.
5197
func (f *Manager) deleteReservationCtx(peerKey *btcec.PublicKey,
5198
        pendingChanID PendingChanID) {
3✔
5199

3✔
5200
        peerIDKey := newSerializedKey(peerKey)
3✔
5201
        f.resMtx.Lock()
3✔
5202
        defer f.resMtx.Unlock()
3✔
5203

3✔
5204
        nodeReservations, ok := f.activeReservations[peerIDKey]
3✔
5205
        if !ok {
3✔
5206
                // No reservations for this node.
×
5207
                return
×
5208
        }
×
5209
        delete(nodeReservations, pendingChanID)
3✔
5210

3✔
5211
        // If this was the last active reservation for this peer, delete the
3✔
5212
        // peer's entry altogether.
3✔
5213
        if len(nodeReservations) == 0 {
6✔
5214
                delete(f.activeReservations, peerIDKey)
3✔
5215
        }
3✔
5216
}
5217

5218
// getReservationCtx returns the reservation context for a particular pending
5219
// channel ID for a target peer.
5220
func (f *Manager) getReservationCtx(peerKey *btcec.PublicKey,
5221
        pendingChanID PendingChanID) (*reservationWithCtx, error) {
3✔
5222

3✔
5223
        peerIDKey := newSerializedKey(peerKey)
3✔
5224
        f.resMtx.RLock()
3✔
5225
        resCtx, ok := f.activeReservations[peerIDKey][pendingChanID]
3✔
5226
        f.resMtx.RUnlock()
3✔
5227

3✔
5228
        if !ok {
6✔
5229
                return nil, errors.Errorf("unknown channel (id: %x) for "+
3✔
5230
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
3✔
5231
        }
3✔
5232

5233
        return resCtx, nil
3✔
5234
}
5235

5236
// IsPendingChannel returns a boolean indicating whether the channel identified
5237
// by the pendingChanID and given peer is pending, meaning it is in the process
5238
// of being funded. After the funding transaction has been confirmed, the
5239
// channel will receive a new, permanent channel ID, and will no longer be
5240
// considered pending.
5241
func (f *Manager) IsPendingChannel(pendingChanID PendingChanID,
5242
        peer lnpeer.Peer) bool {
3✔
5243

3✔
5244
        peerIDKey := newSerializedKey(peer.IdentityKey())
3✔
5245
        f.resMtx.RLock()
3✔
5246
        _, ok := f.activeReservations[peerIDKey][pendingChanID]
3✔
5247
        f.resMtx.RUnlock()
3✔
5248

3✔
5249
        return ok
3✔
5250
}
3✔
5251

5252
func copyPubKey(pub *btcec.PublicKey) *btcec.PublicKey {
3✔
5253
        var tmp btcec.JacobianPoint
3✔
5254
        pub.AsJacobian(&tmp)
3✔
5255
        tmp.ToAffine()
3✔
5256
        return btcec.NewPublicKey(&tmp.X, &tmp.Y)
3✔
5257
}
3✔
5258

5259
// defaultForwardingPolicy returns the default forwarding policy based on the
5260
// default routing policy and our local channel constraints.
5261
func (f *Manager) defaultForwardingPolicy(
5262
        bounds channeldb.ChannelStateBounds) *models.ForwardingPolicy {
3✔
5263

3✔
5264
        return &models.ForwardingPolicy{
3✔
5265
                MinHTLCOut:    bounds.MinHTLC,
3✔
5266
                MaxHTLC:       bounds.MaxPendingAmount,
3✔
5267
                BaseFee:       f.cfg.DefaultRoutingPolicy.BaseFee,
3✔
5268
                FeeRate:       f.cfg.DefaultRoutingPolicy.FeeRate,
3✔
5269
                TimeLockDelta: f.cfg.DefaultRoutingPolicy.TimeLockDelta,
3✔
5270
        }
3✔
5271
}
3✔
5272

5273
// saveInitialForwardingPolicy saves the forwarding policy for the provided
5274
// chanPoint in the channelOpeningStateBucket.
5275
func (f *Manager) saveInitialForwardingPolicy(chanID lnwire.ChannelID,
5276
        forwardingPolicy *models.ForwardingPolicy) error {
3✔
5277

3✔
5278
        return f.cfg.ChannelDB.SaveInitialForwardingPolicy(
3✔
5279
                chanID, forwardingPolicy,
3✔
5280
        )
3✔
5281
}
3✔
5282

5283
// getInitialForwardingPolicy fetches the initial forwarding policy for a given
5284
// channel id from the database which will be applied during the channel
5285
// announcement phase.
5286
func (f *Manager) getInitialForwardingPolicy(
5287
        chanID lnwire.ChannelID) (*models.ForwardingPolicy, error) {
3✔
5288

3✔
5289
        return f.cfg.ChannelDB.GetInitialForwardingPolicy(chanID)
3✔
5290
}
3✔
5291

5292
// deleteInitialForwardingPolicy removes channel fees for this chanID from
5293
// the database.
5294
func (f *Manager) deleteInitialForwardingPolicy(chanID lnwire.ChannelID) error {
3✔
5295
        return f.cfg.ChannelDB.DeleteInitialForwardingPolicy(chanID)
3✔
5296
}
3✔
5297

5298
// saveChannelOpeningState saves the channelOpeningState for the provided
5299
// chanPoint to the channelOpeningStateBucket.
5300
func (f *Manager) saveChannelOpeningState(chanPoint *wire.OutPoint,
5301
        state channelOpeningState, shortChanID *lnwire.ShortChannelID) error {
3✔
5302

3✔
5303
        var outpointBytes bytes.Buffer
3✔
5304
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
3✔
5305
                return err
×
5306
        }
×
5307

5308
        // Save state and the uint64 representation of the shortChanID
5309
        // for later use.
5310
        scratch := make([]byte, 10)
3✔
5311
        byteOrder.PutUint16(scratch[:2], uint16(state))
3✔
5312
        byteOrder.PutUint64(scratch[2:], shortChanID.ToUint64())
3✔
5313

3✔
5314
        return f.cfg.ChannelDB.SaveChannelOpeningState(
3✔
5315
                outpointBytes.Bytes(), scratch,
3✔
5316
        )
3✔
5317
}
5318

5319
// getChannelOpeningState fetches the channelOpeningState for the provided
5320
// chanPoint from the database, or returns ErrChannelNotFound if the channel
5321
// is not found.
5322
func (f *Manager) getChannelOpeningState(chanPoint *wire.OutPoint) (
5323
        channelOpeningState, *lnwire.ShortChannelID, error) {
3✔
5324

3✔
5325
        var outpointBytes bytes.Buffer
3✔
5326
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
3✔
5327
                return 0, nil, err
×
5328
        }
×
5329

5330
        value, err := f.cfg.ChannelDB.GetChannelOpeningState(
3✔
5331
                outpointBytes.Bytes(),
3✔
5332
        )
3✔
5333
        if err != nil {
6✔
5334
                return 0, nil, err
3✔
5335
        }
3✔
5336

5337
        state := channelOpeningState(byteOrder.Uint16(value[:2]))
3✔
5338
        shortChanID := lnwire.NewShortChanIDFromInt(byteOrder.Uint64(value[2:]))
3✔
5339
        return state, &shortChanID, nil
3✔
5340
}
5341

5342
// deleteChannelOpeningState removes any state for chanPoint from the database.
5343
func (f *Manager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error {
3✔
5344
        var outpointBytes bytes.Buffer
3✔
5345
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
3✔
5346
                return err
×
5347
        }
×
5348

5349
        return f.cfg.ChannelDB.DeleteChannelOpeningState(
3✔
5350
                outpointBytes.Bytes(),
3✔
5351
        )
3✔
5352
}
5353

5354
// selectShutdownScript selects the shutdown script we should send to the peer.
5355
// If we can use taproot, then we prefer that, otherwise we'll use a p2wkh
5356
// script.
5357
func (f *Manager) selectShutdownScript(taprootOK bool,
5358
) (lnwire.DeliveryAddress, error) {
×
5359

×
5360
        addrType := lnwallet.WitnessPubKey
×
5361
        if taprootOK {
×
5362
                addrType = lnwallet.TaprootPubkey
×
5363
        }
×
5364

5365
        addr, err := f.cfg.Wallet.NewAddress(
×
5366
                addrType, false, lnwallet.DefaultAccountName,
×
5367
        )
×
5368
        if err != nil {
×
5369
                return nil, err
×
5370
        }
×
5371

5372
        return txscript.PayToAddrScript(addr)
×
5373
}
5374

5375
// waitForPeerOnline blocks until the peer specified by peerPubkey comes online
5376
// and then returns the online peer.
5377
func (f *Manager) waitForPeerOnline(peerPubkey *btcec.PublicKey) (lnpeer.Peer,
5378
        error) {
3✔
5379

3✔
5380
        peerChan := make(chan lnpeer.Peer, 1)
3✔
5381

3✔
5382
        var peerKey [33]byte
3✔
5383
        copy(peerKey[:], peerPubkey.SerializeCompressed())
3✔
5384

3✔
5385
        f.cfg.NotifyWhenOnline(peerKey, peerChan)
3✔
5386

3✔
5387
        var peer lnpeer.Peer
3✔
5388
        select {
3✔
5389
        case peer = <-peerChan:
3✔
5390
        case <-f.quit:
1✔
5391
                return peer, ErrFundingManagerShuttingDown
1✔
5392
        }
5393
        return peer, nil
3✔
5394
}
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