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

lightningnetwork / lnd / 13792009373

11 Mar 2025 03:33PM UTC coverage: 68.646% (+0.03%) from 68.612%
13792009373

push

github

web-flow
Merge pull request #9595 from yyforyongyu/fix-gossip-syncer

multi: fix flakes and gossip syncer

14 of 16 new or added lines in 2 files covered. (87.5%)

28 existing lines in 12 files now uncovered.

130062 of 189468 relevant lines covered (68.65%)

23591.14 hits per line

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

74.2
/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 {
371✔
67
        scratch := make([]byte, 4)
371✔
68

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

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

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

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

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

130
        zeroID [32]byte
131
)
132

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

146
        chanAmt btcutil.Amount
147

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

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

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

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

165
        updateMtx   sync.RWMutex
166
        lastUpdated time.Time
167

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

339
        // MaxWaitNumBlocksFundingConf is the maximum number of blocks to wait
340
        // for the funding transaction to be confirmed before forgetting
341
        // channels that aren't initiated by us.
342
        MaxWaitNumBlocksFundingConf uint32
343
}
344

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

728
        for _, channel := range allChannels {
122✔
729
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
12✔
730

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

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

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

4✔
752
                                f.rebroadcastFundingTx(channel)
4✔
753
                        }
4✔
754
                } else if channel.ChanType.IsSingleFunder() &&
11✔
755
                        channel.ChanType.HasFundingTx() &&
11✔
756
                        channel.IsZeroConf() && channel.IsInitiator &&
11✔
757
                        !channel.ZeroConfConfirmed() {
13✔
758

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

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

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

110✔
776
        return nil
110✔
777
}
778

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

106✔
786
                close(f.quit)
106✔
787
                f.wg.Wait()
106✔
788
        })
106✔
789

790
        return nil
107✔
791
}
792

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

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

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

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

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

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

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

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

59✔
846
        return nextChanID
59✔
847
}
59✔
848

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

3✔
855
        f.resMtx.Lock()
3✔
856
        defer f.resMtx.Unlock()
3✔
857

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

110✔
1027
        for {
485✔
1028
                select {
375✔
1029
                case fmsg := <-f.fundingMsgs:
212✔
1030
                        switch msg := fmsg.msg.(type) {
212✔
1031
                        case *lnwire.OpenChannel:
56✔
1032
                                f.fundeeProcessOpenChannel(fmsg.peer, msg)
56✔
1033

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

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

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

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

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

1050
                        case *lnwire.Error:
3✔
1051
                                f.handleErrorMsg(fmsg.peer, msg)
3✔
1052
                        }
1053
                case req := <-f.fundingRequests:
59✔
1054
                        f.handleInitFundingMsg(req)
59✔
1055

1056
                case <-zombieSweepTicker.C:
3✔
1057
                        f.pruneZombieReservations()
3✔
1058

1059
                case <-f.quit:
106✔
1060
                        return
106✔
1061
                }
1062
        }
1063
}
1064

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

66✔
1077
        defer f.wg.Done()
66✔
1078

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

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

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

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

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

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

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

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

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

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

37✔
1190
                return nil
37✔
1191

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

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

1215
                        return nil
27✔
1216
                }
1217

1218
                return f.handleChannelReadyReceived(
27✔
1219
                        channel, shortChanID, pendingChanID, updateChan,
27✔
1220
                )
27✔
1221

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

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

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

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

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

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

27✔
1271
                return nil
27✔
1272
        }
1273

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

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

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

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

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

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

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

1326
                return nil
7✔
1327
        }
1328

1329
        confChannel, err := f.waitForFundingWithTimeout(channel)
54✔
1330
        if err == ErrConfirmationTimeout {
59✔
1331
                return f.fundingTimeout(channel, pendingChanID)
5✔
1332
        } else if err != nil {
79✔
1333
                return fmt.Errorf("error waiting for funding "+
22✔
1334
                        "confirmation for ChannelPoint(%v): %v",
22✔
1335
                        channel.FundingOutpoint, err)
22✔
1336
        }
22✔
1337

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

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

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

×
1356
                        return err
×
1357
                }
×
1358

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

×
1368
                        return err
×
1369
                }
×
1370

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

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

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

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

1397
        return nil
33✔
1398
}
1399

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

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

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

56✔
1427
        amt := msg.FundingAmount
56✔
1428

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

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

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

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

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

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

7✔
1473
                return
7✔
1474
        }
7✔
1475

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

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

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

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

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

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

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

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

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

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

1568
        var scidFeatureVal bool
49✔
1569
        if hasFeatures(
49✔
1570
                peer.LocalFeatures(), peer.RemoteFeatures(),
49✔
1571
                lnwire.ScidAliasOptional,
49✔
1572
        ) {
55✔
1573

6✔
1574
                scidFeatureVal = true
6✔
1575
        }
6✔
1576

1577
        var (
49✔
1578
                zeroConf bool
49✔
1579
                scid     bool
49✔
1580
        )
49✔
1581

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

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

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

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

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

×
1636
                return
×
1637

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

×
1646
                return
×
1647
        }
1648

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

×
1663
                return
×
1664
        }
×
1665

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

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

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

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

1706
                reservation.AddAlias(aliasScid)
5✔
1707
        }
1708

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

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

1726
        reservation.SetNumConfsRequired(numConfsReq)
49✔
1727

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

49✔
1908
        if resCtx.reservation.IsTaproot() {
54✔
1909
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
5✔
1910
                if err != nil {
5✔
1911
                        log.Error(errNoLocalNonce)
×
1912

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

×
1915
                        return
×
1916
                }
×
1917

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

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

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

43✔
1939
        reservation.SetState(lnwallet.SentAcceptChannel)
43✔
1940

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

43✔
1963
        if commitType.IsTaproot() {
48✔
1964
                fundingAccept.LocalNonce = lnwire.SomeMusig2Nonce(
5✔
1965
                        ourContribution.LocalNonce.PubNonce,
5✔
1966
                )
5✔
1967
        }
5✔
1968

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

×
2104
                minDepth = 1
×
2105
        }
×
2106

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

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

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

32✔
2168
        if resCtx.reservation.IsTaproot() {
37✔
2169
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
5✔
2170
                if err != nil {
5✔
2171
                        log.Error(errNoLocalNonce)
×
2172

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

×
2175
                        return
×
2176
                }
×
2177

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

2183
        err = resCtx.reservation.ProcessContribution(remoteContribution)
32✔
2184

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

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

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

3✔
2246
                        f.waitForPsbt(psbtIntent, resCtx, cid)
3✔
2247
                }()
3✔
2248

2249
                // With the new goroutine spawned, we can now exit to unblock
2250
                // the main event loop.
2251
                return
3✔
2252
        }
2253

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

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

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

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

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

2299
                // Nil error means the flow continues normally now.
2300
                case nil:
3✔
2301

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

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

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

2341
                // We are now ready to continue the funding flow.
2342
                f.continueFundingAccept(resCtx, cid)
3✔
2343

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

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

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

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

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

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

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

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

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

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

×
2415
                        return
×
2416
                }
×
2417

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

2430
        resCtx.reservation.SetState(lnwallet.SentFundingCreated)
32✔
2431

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

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

30✔
2449
        peerKey := peer.IdentityKey()
30✔
2450
        pendingChanID := msg.PendingChannelID
30✔
2451

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

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

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

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

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

×
2483
                        return
×
2484
                }
×
2485

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

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

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

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

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

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

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

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

30✔
2576
        fundingSigned := &lnwire.FundingSigned{}
30✔
2577

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

×
2590
                        return
×
2591
                }
×
2592

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

×
2603
                        return
×
2604
                }
×
2605
        }
2606

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

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

30✔
2620
        fundingSigned.ChanID = cid.chanID
30✔
2621

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

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

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

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

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

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

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

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

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

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

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

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

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

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

×
2735
                return
×
2736
        }
×
2737

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

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

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

×
2764
                        return
×
2765
                }
×
2766

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2948
                // nil error means we continue on.
2949
                case nil:
5✔
2950

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

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

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

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

2970
        return timeoutErr
5✔
2971
}
2972

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

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

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

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

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

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

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

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

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

3033
                return pkScript, nil
8✔
3034
        }
3035

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

3044
        return input.WitnessScriptHash(multiSigScript)
75✔
3045
}
3046

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

60✔
3060
        defer f.wg.Done()
60✔
3061
        defer close(confChan)
60✔
3062

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

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

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

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

60✔
3095
        var confDetails *chainntnfs.TxConfirmation
60✔
3096
        var ok bool
60✔
3097

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

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

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

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

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

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

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

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

28✔
3157
        defer f.wg.Done()
28✔
3158

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

3166
        defer epochClient.Cancel()
28✔
3167

28✔
3168
        // The value of waitBlocksForFundingConf is adjusted in a development
28✔
3169
        // environment to enhance test capabilities. Otherwise, it is set to
28✔
3170
        // DefaultMaxWaitNumBlocksFundingConf.
28✔
3171
        waitBlocksForFundingConf := uint32(
28✔
3172
                lncfg.DefaultMaxWaitNumBlocksFundingConf,
28✔
3173
        )
28✔
3174

28✔
3175
        if lncfg.IsDevBuild() {
31✔
3176
                waitBlocksForFundingConf =
3✔
3177
                        f.cfg.Dev.MaxWaitNumBlocksFundingConf
3✔
3178
        }
3✔
3179

3180
        // On block maxHeight we will cancel the funding confirmation wait.
3181
        broadcastHeight := completeChan.BroadcastHeight()
28✔
3182
        maxHeight := broadcastHeight + waitBlocksForFundingConf
28✔
3183
        for {
58✔
3184
                select {
30✔
3185
                case epoch, ok := <-epochClient.Epochs:
7✔
3186
                        if !ok {
7✔
3187
                                timeoutChan <- fmt.Errorf("epoch client " +
×
3188
                                        "shutting down")
×
3189
                                return
×
3190
                        }
×
3191

3192
                        // Close the timeout channel and exit if the block is
3193
                        // above the max height.
3194
                        if uint32(epoch.Height) >= maxHeight {
12✔
3195
                                log.Warnf("Waited for %v blocks without "+
5✔
3196
                                        "seeing funding transaction confirmed,"+
5✔
3197
                                        " cancelling.",
5✔
3198
                                        waitBlocksForFundingConf)
5✔
3199

5✔
3200
                                // Notify the caller of the timeout.
5✔
3201
                                close(timeoutChan)
5✔
3202
                                return
5✔
3203
                        }
5✔
3204

3205
                        // TODO: If we are the channel initiator implement
3206
                        // a method for recovering the funds from the funding
3207
                        // transaction
3208

3209
                case <-cancelChan:
18✔
3210
                        return
18✔
3211

3212
                case <-f.quit:
11✔
3213
                        // The fundingManager is shutting down, will resume
11✔
3214
                        // waiting for the funding transaction on startup.
11✔
3215
                        return
11✔
3216
                }
3217
        }
3218
}
3219

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

19✔
3230
                // For zero-conf channels, we'll use the actually-confirmed
19✔
3231
                // short channel id.
19✔
3232
                if c.IsZeroConf() {
24✔
3233
                        shortChanID = c.ZeroConfRealScid()
5✔
3234
                }
5✔
3235

3236
                label := labels.MakeLabel(
19✔
3237
                        labels.LabelTypeChannelOpen, &shortChanID,
19✔
3238
                )
19✔
3239

19✔
3240
                err := f.cfg.UpdateLabel(c.FundingOutpoint.Hash, label)
19✔
3241
                if err != nil {
19✔
3242
                        log.Errorf("unable to update label: %v", err)
×
3243
                }
×
3244
        }
3245
}
3246

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

33✔
3255
        fundingPoint := completeChan.FundingOutpoint
33✔
3256
        chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
33✔
3257

33✔
3258
        // TODO(roasbeef): ideally persistent state update for chan above
33✔
3259
        // should be abstracted
33✔
3260

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

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

3278
                err = f.cfg.AliasManager.AddLocalAlias(
5✔
3279
                        aliasScid, confChannel.shortChanID, true, false,
5✔
3280
                )
5✔
3281
                if err != nil {
5✔
3282
                        return fmt.Errorf("unable to request alias: %w", err)
×
3283
                }
×
3284
        }
3285

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

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

3308
        // Update the confirmed funding transaction label.
3309
        f.makeLabelForTx(completeChan)
33✔
3310

33✔
3311
        // Inform the ChannelNotifier that the channel has transitioned from
33✔
3312
        // pending open to open.
33✔
3313
        f.cfg.NotifyOpenChannelEvent(completeChan.FundingOutpoint)
33✔
3314

33✔
3315
        // Close the discoverySignal channel, indicating to a separate
33✔
3316
        // goroutine that the channel now is marked as open in the database
33✔
3317
        // and that it is acceptable to process channel_ready messages
33✔
3318
        // from the peer.
33✔
3319
        if discoverySignal, ok := f.localDiscoverySignals.Load(chanID); ok {
66✔
3320
                close(discoverySignal)
33✔
3321
        }
33✔
3322

3323
        return nil
33✔
3324
}
3325

3326
// sendChannelReady creates and sends the channelReady message.
3327
// This should be called after the funding transaction has been confirmed,
3328
// and the channelState is 'markedOpen'.
3329
func (f *Manager) sendChannelReady(completeChan *channeldb.OpenChannel,
3330
        channel *lnwallet.LightningChannel) error {
38✔
3331

38✔
3332
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
38✔
3333

38✔
3334
        var peerKey [33]byte
38✔
3335
        copy(peerKey[:], completeChan.IdentityPub.SerializeCompressed())
38✔
3336

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

38✔
3347
        // If this is a taproot channel, then we also need to send along our
38✔
3348
        // set of musig2 nonces as well.
38✔
3349
        if completeChan.ChanType.IsTaproot() {
45✔
3350
                log.Infof("ChanID(%v): generating musig2 nonces...",
7✔
3351
                        chanID)
7✔
3352

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

3367
                        // Now that we've generated the nonce for this channel,
3368
                        // we'll store it in the set of pending nonces.
3369
                        localNonce = newNonce
7✔
3370
                        f.pendingMusigNonces[chanID] = localNonce
7✔
3371
                }
3372
                f.nonceMtx.Unlock()
7✔
3373

7✔
3374
                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce(
7✔
3375
                        localNonce.PubNonce,
7✔
3376
                )
7✔
3377
        }
3378

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

3392
                // We can use a pointer to aliases since GetAliases returns a
3393
                // copy of the alias slice.
3394
                channelReadyMsg.AliasScid = &aliases[0]
9✔
3395
        }
3396

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

3414
                localAlias := peer.LocalFeatures().HasFeature(
37✔
3415
                        lnwire.ScidAliasOptional,
37✔
3416
                )
37✔
3417
                remoteAlias := peer.RemoteFeatures().HasFeature(
37✔
3418
                        lnwire.ScidAliasOptional,
37✔
3419
                )
37✔
3420

37✔
3421
                // We could also refresh the channel state instead of checking
37✔
3422
                // whether the feature was negotiated, but this saves us a
37✔
3423
                // database read.
37✔
3424
                if channelReadyMsg.AliasScid == nil && localAlias &&
37✔
3425
                        remoteAlias {
37✔
3426

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

3443
                                err = f.cfg.AliasManager.AddLocalAlias(
×
3444
                                        alias, completeChan.ShortChannelID,
×
3445
                                        false, false,
×
3446
                                )
×
3447
                                if err != nil {
×
3448
                                        return err
×
3449
                                }
×
3450

3451
                                channelReadyMsg.AliasScid = &alias
×
3452
                        } else {
×
3453
                                channelReadyMsg.AliasScid = &aliases[0]
×
3454
                        }
×
3455
                }
3456

3457
                log.Infof("Peer(%x) is online, sending ChannelReady "+
37✔
3458
                        "for ChannelID(%v)", peerKey, chanID)
37✔
3459

37✔
3460
                if err := peer.SendMessage(true, channelReadyMsg); err == nil {
74✔
3461
                        // Sending succeeded, we can break out and continue the
37✔
3462
                        // funding flow.
37✔
3463
                        break
37✔
3464
                }
3465

3466
                log.Warnf("Unable to send channelReady to peer %x: %v. "+
×
3467
                        "Will retry when online", peerKey, err)
×
3468
        }
3469

3470
        return nil
37✔
3471
}
3472

3473
// receivedChannelReady checks whether or not we've received a ChannelReady
3474
// from the remote peer. If we have, RemoteNextRevocation will be set.
3475
func (f *Manager) receivedChannelReady(node *btcec.PublicKey,
3476
        chanID lnwire.ChannelID) (bool, error) {
63✔
3477

63✔
3478
        // If the funding manager has exited, return an error to stop looping.
63✔
3479
        // Note that the peer may appear as online while the funding manager
63✔
3480
        // has stopped due to the shutdown order in the server.
63✔
3481
        select {
63✔
3482
        case <-f.quit:
×
3483
                return false, ErrFundingManagerShuttingDown
×
3484
        default:
63✔
3485
        }
3486

3487
        // Avoid a tight loop if peer is offline.
3488
        if _, err := f.waitForPeerOnline(node); err != nil {
64✔
3489
                log.Errorf("Wait for peer online failed: %v", err)
1✔
3490
                return false, err
1✔
3491
        }
1✔
3492

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

3502
        // If we haven't insert the next revocation point, we haven't finished
3503
        // processing the channel ready message.
3504
        if channel.RemoteNextRevocation == nil {
101✔
3505
                return false, nil
38✔
3506
        }
38✔
3507

3508
        // Finally, the barrier signal is removed once we finish
3509
        // `handleChannelReady`. If we can still find the signal, we haven't
3510
        // finished processing it yet.
3511
        _, loaded := f.handleChannelReadyBarriers.Load(chanID)
28✔
3512

28✔
3513
        return !loaded, nil
28✔
3514
}
3515

3516
// extractAnnounceParams extracts the various channel announcement and update
3517
// parameters that will be needed to construct a ChannelAnnouncement and a
3518
// ChannelUpdate.
3519
func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) (
3520
        lnwire.MilliSatoshi, lnwire.MilliSatoshi) {
29✔
3521

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

29✔
3528
        // We don't necessarily want to go as low as the remote party allows.
29✔
3529
        // Check it against our default forwarding policy.
29✔
3530
        if fwdMinHTLC < f.cfg.DefaultRoutingPolicy.MinHTLCOut {
32✔
3531
                fwdMinHTLC = f.cfg.DefaultRoutingPolicy.MinHTLCOut
3✔
3532
        }
3✔
3533

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

3543
        return fwdMinHTLC, fwdMaxHTLC
29✔
3544
}
3545

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

29✔
3559
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
29✔
3560

29✔
3561
        fwdMinHTLC, fwdMaxHTLC := f.extractAnnounceParams(completeChan)
29✔
3562

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

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

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

3599
        errChan = f.cfg.SendAnnouncement(
29✔
3600
                ann.chanUpdateAnn, discovery.RemoteAlias(peerAlias),
29✔
3601
        )
29✔
3602
        select {
29✔
3603
        case err := <-errChan:
29✔
3604
                if err != nil {
29✔
3605
                        if graph.IsError(err, graph.ErrOutdated,
×
3606
                                graph.ErrIgnored) {
×
3607

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

3619
        return nil
29✔
3620
}
3621

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

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

11✔
3639
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
11✔
3640
                if err != nil {
11✔
3641
                        return err
×
3642
                }
×
3643

3644
                nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
11✔
3645
                if err != nil {
11✔
3646
                        return fmt.Errorf("unable to retrieve current node "+
×
3647
                                "announcement: %v", err)
×
3648
                }
×
3649

3650
                chanID := lnwire.NewChanIDFromOutPoint(
11✔
3651
                        completeChan.FundingOutpoint,
11✔
3652
                )
11✔
3653
                pubKey := peer.PubKey()
11✔
3654
                log.Debugf("Sending our NodeAnnouncement for "+
11✔
3655
                        "ChannelID(%v) to %x", chanID, pubKey)
11✔
3656

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

21✔
3677
                fundingScript, err := makeFundingScript(completeChan)
21✔
3678
                if err != nil {
21✔
3679
                        return fmt.Errorf("unable to create funding script "+
×
3680
                                "for ChannelPoint(%v): %v",
×
3681
                                completeChan.FundingOutpoint, err)
×
3682
                }
×
3683

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

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

3708
                case <-f.quit:
5✔
3709
                        return fmt.Errorf("%v, stopping funding flow for "+
5✔
3710
                                "ChannelPoint(%v)",
5✔
3711
                                ErrFundingManagerShuttingDown,
5✔
3712
                                completeChan.FundingOutpoint)
5✔
3713
                }
3714

3715
                fundingPoint := completeChan.FundingOutpoint
19✔
3716
                chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
19✔
3717

19✔
3718
                log.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
19✔
3719
                        &fundingPoint, shortChanID)
19✔
3720

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

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

3746
                        err = f.addToGraph(
3✔
3747
                                completeChan, &baseScid, nil, ourPolicy,
3✔
3748
                        )
3✔
3749
                        if err != nil {
3✔
3750
                                return fmt.Errorf("failed to re-add to "+
×
3751
                                        "graph: %v", err)
×
3752
                        }
×
3753
                }
3754

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

3768
                log.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
19✔
3769
                        "sent to gossiper", &fundingPoint, shortChanID)
19✔
3770
        }
3771

3772
        return nil
27✔
3773
}
3774

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

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

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

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

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

3824
                // TODO: Make this atomic!
3825
                ourPolicy, err := f.cfg.DeleteAliasEdge(c.ShortChanID())
5✔
3826
                if err != nil {
5✔
3827
                        return fmt.Errorf("unable to delete alias edge from "+
×
3828
                                "graph: %v", err)
×
3829
                }
×
3830

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

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

3857
        // Update the confirmed transaction's label.
3858
        f.makeLabelForTx(c)
7✔
3859

7✔
3860
        return nil
7✔
3861
}
3862

3863
// genFirstStateMusigNonce generates a nonces for the "first" local state. This
3864
// is the verification nonce for the state created for us after the initial
3865
// commitment transaction signed as part of the funding flow.
3866
func genFirstStateMusigNonce(channel *channeldb.OpenChannel,
3867
) (*musig2.Nonces, error) {
7✔
3868

7✔
3869
        musig2ShaChain, err := channeldb.DeriveMusig2Shachain(
7✔
3870
                channel.RevocationProducer,
7✔
3871
        )
7✔
3872
        if err != nil {
7✔
3873
                return nil, fmt.Errorf("unable to generate musig channel "+
×
3874
                        "nonces: %v", err)
×
3875
        }
×
3876

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

3889
        return verNonce, nil
7✔
3890
}
3891

3892
// handleChannelReady finalizes the channel funding process and enables the
3893
// channel to enter normal operating mode.
3894
func (f *Manager) handleChannelReady(peer lnpeer.Peer, //nolint:funlen
3895
        msg *lnwire.ChannelReady) {
31✔
3896

31✔
3897
        defer f.wg.Done()
31✔
3898

31✔
3899
        // If we are in development mode, we'll wait for specified duration
31✔
3900
        // before processing the channel ready message.
31✔
3901
        if f.cfg.Dev != nil {
34✔
3902
                duration := f.cfg.Dev.ProcessChannelReadyWait
3✔
3903
                log.Warnf("Channel(%v): sleeping %v before processing "+
3✔
3904
                        "channel_ready", msg.ChanID, duration)
3✔
3905

3✔
3906
                select {
3✔
3907
                case <-time.After(duration):
3✔
3908
                        log.Warnf("Channel(%v): slept %v before processing "+
3✔
3909
                                "channel_ready", msg.ChanID, duration)
3✔
3910
                case <-f.quit:
×
3911
                        log.Warnf("Channel(%v): quit sleeping", msg.ChanID)
×
3912
                        return
×
3913
                }
3914
        }
3915

3916
        log.Debugf("Received ChannelReady for ChannelID(%v) from "+
31✔
3917
                "peer %x", msg.ChanID,
31✔
3918
                peer.IdentityKey().SerializeCompressed())
31✔
3919

31✔
3920
        // We now load or create a new channel barrier for this channel.
31✔
3921
        _, loaded := f.handleChannelReadyBarriers.LoadOrStore(
31✔
3922
                msg.ChanID, struct{}{},
31✔
3923
        )
31✔
3924

31✔
3925
        // If we are currently in the process of handling a channel_ready
31✔
3926
        // message for this channel, ignore.
31✔
3927
        if loaded {
35✔
3928
                log.Infof("Already handling channelReady for "+
4✔
3929
                        "ChannelID(%v), ignoring.", msg.ChanID)
4✔
3930
                return
4✔
3931
        }
4✔
3932

3933
        // If not already handling channelReady for this channel, then the
3934
        // `LoadOrStore` has set up a barrier, and it will be removed once this
3935
        // function exits.
3936
        defer f.handleChannelReadyBarriers.Delete(msg.ChanID)
30✔
3937

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

3952
                // With the signal received, we can now safely delete the entry
3953
                // from the map.
3954
                f.localDiscoverySignals.Delete(msg.ChanID)
28✔
3955
        }
3956

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

3969
        // If this is a taproot channel, then we can generate the set of nonces
3970
        // the remote party needs to send the next remote commitment here.
3971
        var firstVerNonce *musig2.Nonces
30✔
3972
        if channel.ChanType.IsTaproot() {
37✔
3973
                firstVerNonce, err = genFirstStateMusigNonce(channel)
7✔
3974
                if err != nil {
7✔
3975
                        log.Error(err)
×
3976
                        return
×
3977
                }
×
3978
        }
3979

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

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

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

4022
                        err = f.cfg.AliasManager.AddLocalAlias(
×
4023
                                alias, channel.ShortChannelID, false, false,
×
4024
                        )
×
4025
                        if err != nil {
×
4026
                                log.Errorf("unable to add local alias: %v",
×
4027
                                        err)
×
4028
                                return
×
4029
                        }
×
4030

4031
                        secondPoint, err := channel.SecondCommitmentPoint()
×
4032
                        if err != nil {
×
4033
                                log.Errorf("unable to fetch second "+
×
4034
                                        "commitment point: %v", err)
×
4035
                                return
×
4036
                        }
×
4037

4038
                        channelReadyMsg := lnwire.NewChannelReady(
×
4039
                                chanID, secondPoint,
×
4040
                        )
×
4041
                        channelReadyMsg.AliasScid = &alias
×
4042

×
4043
                        if firstVerNonce != nil {
×
4044
                                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce( //nolint:ll
×
4045
                                        firstVerNonce.PubNonce,
×
4046
                                )
×
4047
                        }
×
4048

4049
                        err = peer.SendMessage(true, channelReadyMsg)
×
4050
                        if err != nil {
×
4051
                                log.Errorf("unable to send channel_ready: %v",
×
4052
                                        err)
×
4053
                                return
×
4054
                        }
×
4055
                }
4056
        }
4057

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

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

7✔
4088
                log.Infof("ChanID(%v): applying local+remote musig2 nonces",
7✔
4089
                        chanID)
7✔
4090

7✔
4091
                remoteNonce, err := msg.NextLocalNonce.UnwrapOrErrV(
7✔
4092
                        errNoLocalNonce,
7✔
4093
                )
7✔
4094
                if err != nil {
7✔
4095
                        cid := newChanIdentifier(msg.ChanID)
×
4096
                        f.sendWarning(peer, cid, err)
×
4097

×
4098
                        return
×
4099
                }
×
4100

4101
                chanOpts = append(
7✔
4102
                        chanOpts,
7✔
4103
                        lnwallet.WithLocalMusigNonces(localNonce),
7✔
4104
                        lnwallet.WithRemoteMusigNonces(&musig2.Nonces{
7✔
4105
                                PubNonce: remoteNonce,
7✔
4106
                        }),
7✔
4107
                )
7✔
4108

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

×
4126
                        return
×
4127
                }
×
4128
        }
4129

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

4140
        // Before we can add the channel to the peer, we'll need to ensure that
4141
        // we have an initial forwarding policy set.
4142
        if err := f.ensureInitialForwardingPolicy(chanID, channel); err != nil {
29✔
4143
                log.Errorf("Unable to ensure initial forwarding policy: %v",
×
4144
                        err)
×
4145
        }
×
4146

4147
        err = peer.AddNewChannel(&lnpeer.NewChannel{
29✔
4148
                OpenChannel: channel,
29✔
4149
                ChanOpts:    chanOpts,
29✔
4150
        }, f.quit)
29✔
4151
        if err != nil {
29✔
4152
                log.Errorf("Unable to add new channel %v with peer %x: %v",
×
4153
                        channel.FundingOutpoint,
×
4154
                        peer.IdentityKey().SerializeCompressed(), err,
×
4155
                )
×
4156
        }
×
4157
}
4158

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

27✔
4168
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
27✔
4169

27✔
4170
        // Since we've sent+received funding locked at this point, we
27✔
4171
        // can clean up the pending musig2 nonce state.
27✔
4172
        f.nonceMtx.Lock()
27✔
4173
        delete(f.pendingMusigNonces, chanID)
27✔
4174
        f.nonceMtx.Unlock()
27✔
4175

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

4191
                peerAlias = &foundAlias
7✔
4192
        }
4193

4194
        err := f.addToGraph(channel, scid, peerAlias, nil)
27✔
4195
        if err != nil {
27✔
4196
                return fmt.Errorf("failed adding to graph: %w", err)
×
4197
        }
×
4198

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

4211
        log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
27✔
4212
                "added to graph", chanID, scid)
27✔
4213

27✔
4214
        err = fn.MapOptionZ(
27✔
4215
                f.cfg.AuxFundingController,
27✔
4216
                func(controller AuxFundingController) error {
27✔
4217
                        return controller.ChannelReady(
×
4218
                                lnwallet.NewAuxChanState(channel),
×
4219
                        )
×
4220
                },
×
4221
        )
4222
        if err != nil {
27✔
4223
                return fmt.Errorf("failed notifying aux funding controller "+
×
4224
                        "about channel ready: %w", err)
×
4225
        }
×
4226

4227
        // Give the caller a final update notifying them that the channel is
4228
        fundingPoint := channel.FundingOutpoint
27✔
4229
        cp := &lnrpc.ChannelPoint{
27✔
4230
                FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
27✔
4231
                        FundingTxidBytes: fundingPoint.Hash[:],
27✔
4232
                },
27✔
4233
                OutputIndex: fundingPoint.Index,
27✔
4234
        }
27✔
4235

27✔
4236
        if updateChan != nil {
40✔
4237
                upd := &lnrpc.OpenStatusUpdate{
13✔
4238
                        Update: &lnrpc.OpenStatusUpdate_ChanOpen{
13✔
4239
                                ChanOpen: &lnrpc.ChannelOpenUpdate{
13✔
4240
                                        ChannelPoint: cp,
13✔
4241
                                },
13✔
4242
                        },
13✔
4243
                        PendingChanId: pendingChanID[:],
13✔
4244
                }
13✔
4245

13✔
4246
                select {
13✔
4247
                case updateChan <- upd:
13✔
4248
                case <-f.quit:
×
4249
                        return ErrFundingManagerShuttingDown
×
4250
                }
4251
        }
4252

4253
        return nil
27✔
4254
}
4255

4256
// ensureInitialForwardingPolicy ensures that we have an initial forwarding
4257
// policy set for the given channel. If we don't, we'll fall back to the default
4258
// values.
4259
func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID,
4260
        channel *channeldb.OpenChannel) error {
29✔
4261

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

×
4272
                forwardingPolicy = f.defaultForwardingPolicy(
×
4273
                        channel.LocalChanCfg.ChannelStateBounds,
×
4274
                )
×
4275
                needDBUpdate = true
×
4276
        }
×
4277

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

4291
        // And finally, if we found that the values currently stored aren't
4292
        // sufficient for the link, we'll update the database.
4293
        if needDBUpdate {
45✔
4294
                err := f.saveInitialForwardingPolicy(chanID, forwardingPolicy)
16✔
4295
                if err != nil {
16✔
4296
                        return fmt.Errorf("unable to update initial "+
×
4297
                                "forwarding policy: %v", err)
×
4298
                }
×
4299
        }
4300

4301
        return nil
29✔
4302
}
4303

4304
// chanAnnouncement encapsulates the two authenticated announcements that we
4305
// send out to the network after a new channel has been created locally.
4306
type chanAnnouncement struct {
4307
        chanAnn       *lnwire.ChannelAnnouncement1
4308
        chanUpdateAnn *lnwire.ChannelUpdate1
4309
        chanProof     *lnwire.AnnounceSignatures1
4310
}
4311

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

45✔
4327
        chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
45✔
4328

45✔
4329
        // The unconditional section of the announcement is the ShortChannelID
45✔
4330
        // itself which compactly encodes the location of the funding output
45✔
4331
        // within the blockchain.
45✔
4332
        chanAnn := &lnwire.ChannelAnnouncement1{
45✔
4333
                ShortChannelID: shortChanID,
45✔
4334
                Features:       lnwire.NewRawFeatureVector(),
45✔
4335
                ChainHash:      chainHash,
45✔
4336
        }
45✔
4337

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

7✔
4347
                chanAnn.Features.Set(
7✔
4348
                        lnwire.SimpleTaprootChannelsRequiredStaging,
7✔
4349
                )
7✔
4350
        }
7✔
4351

4352
        // The chanFlags field indicates which directed edge of the channel is
4353
        // being updated within the ChannelUpdateAnnouncement announcement
4354
        // below. A value of zero means it's the edge of the "first" node and 1
4355
        // being the other node.
4356
        var chanFlags lnwire.ChanUpdateChanFlags
45✔
4357

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

24✔
4376
                // If we're the first node then update the chanFlags to
24✔
4377
                // indicate the "direction" of the update.
24✔
4378
                chanFlags = 0
24✔
4379
        } else {
48✔
4380
                copy(chanAnn.NodeID1[:], remotePubKey.SerializeCompressed())
24✔
4381
                copy(chanAnn.NodeID2[:], localPubKey.SerializeCompressed())
24✔
4382
                copy(
24✔
4383
                        chanAnn.BitcoinKey1[:],
24✔
4384
                        remoteFundingKey.SerializeCompressed(),
24✔
4385
                )
24✔
4386
                copy(
24✔
4387
                        chanAnn.BitcoinKey2[:],
24✔
4388
                        localFundingKey.PubKey.SerializeCompressed(),
24✔
4389
                )
24✔
4390

24✔
4391
                // If we're the second node then update the chanFlags to
24✔
4392
                // indicate the "direction" of the update.
24✔
4393
                chanFlags = 1
24✔
4394
        }
24✔
4395

4396
        // Our channel update message flags will signal that we support the
4397
        // max_htlc field.
4398
        msgFlags := lnwire.ChanUpdateRequiredMaxHtlc
45✔
4399

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

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

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

4439
        case storedFwdingPolicy != nil:
45✔
4440
                chanUpdateAnn.BaseFee = uint32(storedFwdingPolicy.BaseFee)
45✔
4441
                chanUpdateAnn.FeeRate = uint32(storedFwdingPolicy.FeeRate)
45✔
4442

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

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

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

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

4514
        return &chanAnnouncement{
45✔
4515
                chanAnn:       chanAnn,
45✔
4516
                chanUpdateAnn: chanUpdateAnn,
45✔
4517
                chanProof:     proof,
45✔
4518
        }, nil
45✔
4519
}
4520

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

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

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

×
4560
                                log.Debugf("Graph rejected "+
×
4561
                                        "AnnounceSignatures: %v", err)
×
4562
                        } else {
3✔
4563
                                log.Errorf("Unable to send channel "+
3✔
4564
                                        "proof: %v", err)
3✔
4565
                                return err
3✔
4566
                        }
3✔
4567
                }
4568

4569
        case <-f.quit:
×
4570
                return ErrFundingManagerShuttingDown
×
4571
        }
4572

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

4583
        errChan = f.cfg.SendAnnouncement(&nodeAnn)
19✔
4584
        select {
19✔
4585
        case err := <-errChan:
19✔
4586
                if err != nil {
22✔
4587
                        if graph.IsError(err, graph.ErrOutdated,
3✔
4588
                                graph.ErrIgnored) {
6✔
4589

3✔
4590
                                log.Debugf("Graph rejected "+
3✔
4591
                                        "NodeAnnouncement: %v", err)
3✔
4592
                        } else {
3✔
4593
                                log.Errorf("Unable to send node "+
×
4594
                                        "announcement: %v", err)
×
4595
                                return err
×
4596
                        }
×
4597
                }
4598

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

4603
        return nil
19✔
4604
}
4605

4606
// InitFundingWorkflow sends a message to the funding manager instructing it
4607
// to initiate a single funder workflow with the source peer.
4608
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
59✔
4609
        f.fundingRequests <- msg
59✔
4610
}
59✔
4611

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

111✔
4624
        // Check whether the remote peer supports upfront shutdown scripts.
111✔
4625
        remoteUpfrontShutdown := peer.RemoteFeatures().HasFeature(
111✔
4626
                lnwire.UpfrontShutdownScriptOptional,
111✔
4627
        )
111✔
4628

111✔
4629
        // If the peer does not support upfront shutdown scripts, and one has been
111✔
4630
        // provided, return an error because the feature is not supported.
111✔
4631
        if !remoteUpfrontShutdown && len(script) != 0 {
112✔
4632
                return nil, errUpfrontShutdownScriptNotSupported
1✔
4633
        }
1✔
4634

4635
        // If the peer does not support upfront shutdown, return an empty address.
4636
        if !remoteUpfrontShutdown {
213✔
4637
                return nil, nil
103✔
4638
        }
103✔
4639

4640
        // If the user has provided an script and the peer supports the feature,
4641
        // return it. Note that user set scripts override the enable upfront
4642
        // shutdown flag.
4643
        if len(script) > 0 {
12✔
4644
                return script, nil
5✔
4645
        }
5✔
4646

4647
        // If we do not have setting of upfront shutdown script enabled, return
4648
        // an empty script.
4649
        if !enableUpfrontShutdown {
9✔
4650
                return nil, nil
4✔
4651
        }
4✔
4652

4653
        // We can safely send a taproot address iff, both sides have negotiated
4654
        // the shutdown-any-segwit feature.
4655
        taprootOK := peer.RemoteFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) &&
1✔
4656
                peer.LocalFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional)
1✔
4657

1✔
4658
        return getScript(taprootOK)
1✔
4659
}
4660

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

59✔
4679
        // If no maximum CSV delay was set for this channel, we use our default
59✔
4680
        // value.
59✔
4681
        if maxCSV == 0 {
118✔
4682
                maxCSV = f.cfg.MaxLocalCSVDelay
59✔
4683
        }
59✔
4684

4685
        log.Infof("Initiating fundingRequest(local_amt=%v "+
59✔
4686
                "(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
59✔
4687
                "min_confs=%v)", localAmt, msg.SubtractFees, msg.PushAmt,
59✔
4688
                msg.ChainHash, peerKey.SerializeCompressed(), msg.MinConfs)
59✔
4689

59✔
4690
        // We set the channel flags to indicate whether we want this channel to
59✔
4691
        // be announced to the network.
59✔
4692
        var channelFlags lnwire.FundingFlag
59✔
4693
        if !msg.Private {
113✔
4694
                // This channel will be announced.
54✔
4695
                channelFlags = lnwire.FFAnnounceChannel
54✔
4696
        }
54✔
4697

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

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

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

4746
        var (
59✔
4747
                zeroConf bool
59✔
4748
                scid     bool
59✔
4749
        )
59✔
4750

59✔
4751
        if chanType != nil {
66✔
4752
                // Check if the returned chanType includes either the zero-conf
7✔
4753
                // or scid-alias bits.
7✔
4754
                featureVec := lnwire.RawFeatureVector(*chanType)
7✔
4755
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
7✔
4756
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
7✔
4757

7✔
4758
                // The option-scid-alias channel type for a public channel is
7✔
4759
                // disallowed.
7✔
4760
                if scid && !msg.Private {
7✔
4761
                        err = fmt.Errorf("option-scid-alias chantype for " +
×
4762
                                "public channel")
×
4763
                        log.Error(err)
×
4764
                        msg.Err <- err
×
4765

×
4766
                        return
×
4767
                }
×
4768
        }
4769

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

4780
        // For anchor channels cap the initial commit fee rate at our defined
4781
        // maximum.
4782
        if commitType.HasAnchors() &&
59✔
4783
                commitFeePerKw > f.cfg.MaxAnchorsCommitFeeRate {
66✔
4784

7✔
4785
                commitFeePerKw = f.cfg.MaxAnchorsCommitFeeRate
7✔
4786
        }
7✔
4787

4788
        var scidFeatureVal bool
59✔
4789
        if hasFeatures(
59✔
4790
                msg.Peer.LocalFeatures(), msg.Peer.RemoteFeatures(),
59✔
4791
                lnwire.ScidAliasOptional,
59✔
4792
        ) {
65✔
4793

6✔
4794
                scidFeatureVal = true
6✔
4795
        }
6✔
4796

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

×
4811
                return
×
4812
        }
×
4813

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

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

4856
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
59✔
4857
        if err != nil {
62✔
4858
                msg.Err <- err
3✔
4859
                return
3✔
4860
        }
3✔
4861

4862
        if zeroConf {
64✔
4863
                // Store the alias for zero-conf channels in the underlying
5✔
4864
                // partial channel state.
5✔
4865
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
5✔
4866
                if err != nil {
5✔
4867
                        msg.Err <- err
×
4868
                        return
×
4869
                }
×
4870

4871
                reservation.AddAlias(aliasScid)
5✔
4872
        }
4873

4874
        // Set our upfront shutdown address in the existing reservation.
4875
        reservation.SetOurUpfrontShutdown(shutdown)
59✔
4876

59✔
4877
        // Now that we have successfully reserved funds for this channel in the
59✔
4878
        // wallet, we can fetch the final channel capacity. This is done at
59✔
4879
        // this point since the final capacity might change in case of
59✔
4880
        // SubtractFees=true.
59✔
4881
        capacity := reservation.Capacity()
59✔
4882

59✔
4883
        log.Infof("Target commit tx sat/kw for pendingID(%x): %v", chanID,
59✔
4884
                int64(commitFeePerKw))
59✔
4885

59✔
4886
        // If the remote CSV delay was not set in the open channel request,
59✔
4887
        // we'll use the RequiredRemoteDelay closure to compute the delay we
59✔
4888
        // require given the total amount of funds within the channel.
59✔
4889
        if remoteCsvDelay == 0 {
117✔
4890
                remoteCsvDelay = f.cfg.RequiredRemoteDelay(capacity)
58✔
4891
        }
58✔
4892

4893
        // If no minimum HTLC value was specified, use the default one.
4894
        if minHtlcIn == 0 {
117✔
4895
                minHtlcIn = f.cfg.DefaultMinHtlcIn
58✔
4896
        }
58✔
4897

4898
        // If no max value was specified, use the default one.
4899
        if maxValue == 0 {
117✔
4900
                maxValue = f.cfg.RequiredRemoteMaxValue(capacity)
58✔
4901
        }
58✔
4902

4903
        if maxHtlcs == 0 {
118✔
4904
                maxHtlcs = f.cfg.RequiredRemoteMaxHTLCs(capacity)
59✔
4905
        }
59✔
4906

4907
        // Once the reservation has been created, and indexed, queue a funding
4908
        // request to the remote peer, kicking off the funding workflow.
4909
        ourContribution := reservation.OurContribution()
59✔
4910

59✔
4911
        // Prepare the optional channel fee values from the initFundingMsg. If
59✔
4912
        // useBaseFee or useFeeRate are false the client did not provide fee
59✔
4913
        // values hence we assume default fee settings from the config.
59✔
4914
        forwardingPolicy := f.defaultForwardingPolicy(
59✔
4915
                ourContribution.ChannelStateBounds,
59✔
4916
        )
59✔
4917
        if baseFee != nil {
63✔
4918
                forwardingPolicy.BaseFee = lnwire.MilliSatoshi(*baseFee)
4✔
4919
        }
4✔
4920

4921
        if feeRate != nil {
63✔
4922
                forwardingPolicy.FeeRate = lnwire.MilliSatoshi(*feeRate)
4✔
4923
        }
4✔
4924

4925
        // Fetch our dust limit which is part of the default channel
4926
        // constraints, and log it.
4927
        ourDustLimit := ourContribution.DustLimit
59✔
4928

59✔
4929
        log.Infof("Dust limit for pendingID(%x): %v", chanID, ourDustLimit)
59✔
4930

59✔
4931
        // If the channel reserve is not specified, then we calculate an
59✔
4932
        // appropriate amount here.
59✔
4933
        if chanReserve == 0 {
114✔
4934
                chanReserve = f.cfg.RequiredRemoteChanReserve(
55✔
4935
                        capacity, ourDustLimit,
55✔
4936
                )
55✔
4937
        }
55✔
4938

4939
        // If a pending channel map for this peer isn't already created, then
4940
        // we create one, ultimately allowing us to track this pending
4941
        // reservation within the target peer.
4942
        peerIDKey := newSerializedKey(peerKey)
59✔
4943
        f.resMtx.Lock()
59✔
4944
        if _, ok := f.activeReservations[peerIDKey]; !ok {
111✔
4945
                f.activeReservations[peerIDKey] = make(pendingChannels)
52✔
4946
        }
52✔
4947

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

59✔
4966
        // Update the timestamp once the InitFundingMsg has been handled.
59✔
4967
        defer resCtx.updateTimestamp()
59✔
4968

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

4990
                msg.Err <- err
2✔
4991
                return
2✔
4992
        }
4993

4994
        // When opening a script enforced channel lease, include the required
4995
        // expiry TLV record in our proposal.
4996
        var leaseExpiry *lnwire.LeaseExpiry
57✔
4997
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
60✔
4998
                leaseExpiry = new(lnwire.LeaseExpiry)
3✔
4999
                *leaseExpiry = lnwire.LeaseExpiry(reservation.LeaseExpiry())
3✔
5000
        }
3✔
5001

5002
        log.Infof("Starting funding workflow with %v for pending_id(%x), "+
57✔
5003
                "committype=%v", msg.Peer.Address(), chanID, commitType)
57✔
5004

57✔
5005
        reservation.SetState(lnwallet.SentOpenChannel)
57✔
5006

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

57✔
5031
        if commitType.IsTaproot() {
62✔
5032
                fundingOpen.LocalNonce = lnwire.SomeMusig2Nonce(
5✔
5033
                        ourContribution.LocalNonce.PubNonce,
5✔
5034
                )
5✔
5035
        }
5✔
5036

5037
        if err := msg.Peer.SendMessage(true, &fundingOpen); err != nil {
57✔
5038
                e := fmt.Errorf("unable to send funding request message: %w",
×
5039
                        err)
×
5040
                log.Errorf(e.Error())
×
5041

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

5049
                msg.Err <- e
×
5050
                return
×
5051
        }
5052
}
5053

5054
// handleWarningMsg processes the warning which was received from remote peer.
5055
func (f *Manager) handleWarningMsg(peer lnpeer.Peer, msg *lnwire.Warning) {
42✔
5056
        log.Warnf("received warning message from peer %x: %v",
42✔
5057
                peer.IdentityKey().SerializeCompressed(), msg.Warning())
42✔
5058
}
42✔
5059

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

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

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

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

5092
        resCtx.err <- fundingErr
3✔
5093
}
5094

5095
// pruneZombieReservations loops through all pending reservations and fails the
5096
// funding flow for any reservations that have not been updated since the
5097
// ReservationTimeout and are not locked waiting for the funding transaction.
5098
func (f *Manager) pruneZombieReservations() {
6✔
5099
        zombieReservations := make(pendingChannels)
6✔
5100

6✔
5101
        f.resMtx.RLock()
6✔
5102
        for _, pendingReservations := range f.activeReservations {
12✔
5103
                for pendingChanID, resCtx := range pendingReservations {
12✔
5104
                        if resCtx.isLocked() {
6✔
5105
                                continue
×
5106
                        }
5107

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

6✔
5122
        for pendingChanID, resCtx := range zombieReservations {
12✔
5123
                err := fmt.Errorf("reservation timed out waiting for peer "+
6✔
5124
                        "(peer_id:%x, chan_id:%x)",
6✔
5125
                        resCtx.peer.IdentityKey().SerializeCompressed(),
6✔
5126
                        pendingChanID[:])
6✔
5127
                log.Warnf(err.Error())
6✔
5128

6✔
5129
                chanID := lnwire.NewChanIDFromOutPoint(
6✔
5130
                        *resCtx.reservation.FundingOutpoint(),
6✔
5131
                )
6✔
5132

6✔
5133
                // Create channel identifier and set the channel ID.
6✔
5134
                cid := newChanIdentifier(pendingChanID)
6✔
5135
                cid.setChanID(chanID)
6✔
5136

6✔
5137
                f.failFundingFlow(resCtx.peer, cid, err)
6✔
5138
        }
6✔
5139
}
5140

5141
// cancelReservationCtx does all needed work in order to securely cancel the
5142
// reservation.
5143
func (f *Manager) cancelReservationCtx(peerKey *btcec.PublicKey,
5144
        pendingChanID PendingChanID,
5145
        byRemote bool) (*reservationWithCtx, error) {
26✔
5146

26✔
5147
        log.Infof("Cancelling funding reservation for node_key=%x, "+
26✔
5148
                "chan_id=%x", peerKey.SerializeCompressed(), pendingChanID[:])
26✔
5149

26✔
5150
        peerIDKey := newSerializedKey(peerKey)
26✔
5151
        f.resMtx.Lock()
26✔
5152
        defer f.resMtx.Unlock()
26✔
5153

26✔
5154
        nodeReservations, ok := f.activeReservations[peerIDKey]
26✔
5155
        if !ok {
36✔
5156
                // No reservations for this node.
10✔
5157
                return nil, errors.Errorf("no active reservations for peer(%x)",
10✔
5158
                        peerIDKey[:])
10✔
5159
        }
10✔
5160

5161
        ctx, ok := nodeReservations[pendingChanID]
19✔
5162
        if !ok {
21✔
5163
                return nil, errors.Errorf("unknown channel (id: %x) for "+
2✔
5164
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
2✔
5165
        }
2✔
5166

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

5175
        if err := ctx.reservation.Cancel(); err != nil {
17✔
5176
                return nil, errors.Errorf("unable to cancel reservation: %v",
×
5177
                        err)
×
5178
        }
×
5179

5180
        delete(nodeReservations, pendingChanID)
17✔
5181

17✔
5182
        // If this was the last active reservation for this peer, delete the
17✔
5183
        // peer's entry altogether.
17✔
5184
        if len(nodeReservations) == 0 {
34✔
5185
                delete(f.activeReservations, peerIDKey)
17✔
5186
        }
17✔
5187
        return ctx, nil
17✔
5188
}
5189

5190
// deleteReservationCtx deletes the reservation uniquely identified by the
5191
// target public key of the peer, and the specified pending channel ID.
5192
func (f *Manager) deleteReservationCtx(peerKey *btcec.PublicKey,
5193
        pendingChanID PendingChanID) {
57✔
5194

57✔
5195
        peerIDKey := newSerializedKey(peerKey)
57✔
5196
        f.resMtx.Lock()
57✔
5197
        defer f.resMtx.Unlock()
57✔
5198

57✔
5199
        nodeReservations, ok := f.activeReservations[peerIDKey]
57✔
5200
        if !ok {
57✔
5201
                // No reservations for this node.
×
5202
                return
×
5203
        }
×
5204
        delete(nodeReservations, pendingChanID)
57✔
5205

57✔
5206
        // If this was the last active reservation for this peer, delete the
57✔
5207
        // peer's entry altogether.
57✔
5208
        if len(nodeReservations) == 0 {
107✔
5209
                delete(f.activeReservations, peerIDKey)
50✔
5210
        }
50✔
5211
}
5212

5213
// getReservationCtx returns the reservation context for a particular pending
5214
// channel ID for a target peer.
5215
func (f *Manager) getReservationCtx(peerKey *btcec.PublicKey,
5216
        pendingChanID PendingChanID) (*reservationWithCtx, error) {
91✔
5217

91✔
5218
        peerIDKey := newSerializedKey(peerKey)
91✔
5219
        f.resMtx.RLock()
91✔
5220
        resCtx, ok := f.activeReservations[peerIDKey][pendingChanID]
91✔
5221
        f.resMtx.RUnlock()
91✔
5222

91✔
5223
        if !ok {
94✔
5224
                return nil, errors.Errorf("unknown channel (id: %x) for "+
3✔
5225
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
3✔
5226
        }
3✔
5227

5228
        return resCtx, nil
91✔
5229
}
5230

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

3✔
5239
        peerIDKey := newSerializedKey(peer.IdentityKey())
3✔
5240
        f.resMtx.RLock()
3✔
5241
        _, ok := f.activeReservations[peerIDKey][pendingChanID]
3✔
5242
        f.resMtx.RUnlock()
3✔
5243

3✔
5244
        return ok
3✔
5245
}
3✔
5246

5247
func copyPubKey(pub *btcec.PublicKey) *btcec.PublicKey {
378✔
5248
        var tmp btcec.JacobianPoint
378✔
5249
        pub.AsJacobian(&tmp)
378✔
5250
        tmp.ToAffine()
378✔
5251
        return btcec.NewPublicKey(&tmp.X, &tmp.Y)
378✔
5252
}
378✔
5253

5254
// defaultForwardingPolicy returns the default forwarding policy based on the
5255
// default routing policy and our local channel constraints.
5256
func (f *Manager) defaultForwardingPolicy(
5257
        bounds channeldb.ChannelStateBounds) *models.ForwardingPolicy {
105✔
5258

105✔
5259
        return &models.ForwardingPolicy{
105✔
5260
                MinHTLCOut:    bounds.MinHTLC,
105✔
5261
                MaxHTLC:       bounds.MaxPendingAmount,
105✔
5262
                BaseFee:       f.cfg.DefaultRoutingPolicy.BaseFee,
105✔
5263
                FeeRate:       f.cfg.DefaultRoutingPolicy.FeeRate,
105✔
5264
                TimeLockDelta: f.cfg.DefaultRoutingPolicy.TimeLockDelta,
105✔
5265
        }
105✔
5266
}
105✔
5267

5268
// saveInitialForwardingPolicy saves the forwarding policy for the provided
5269
// chanPoint in the channelOpeningStateBucket.
5270
func (f *Manager) saveInitialForwardingPolicy(chanID lnwire.ChannelID,
5271
        forwardingPolicy *models.ForwardingPolicy) error {
70✔
5272

70✔
5273
        return f.cfg.ChannelDB.SaveInitialForwardingPolicy(
70✔
5274
                chanID, forwardingPolicy,
70✔
5275
        )
70✔
5276
}
70✔
5277

5278
// getInitialForwardingPolicy fetches the initial forwarding policy for a given
5279
// channel id from the database which will be applied during the channel
5280
// announcement phase.
5281
func (f *Manager) getInitialForwardingPolicy(
5282
        chanID lnwire.ChannelID) (*models.ForwardingPolicy, error) {
97✔
5283

97✔
5284
        return f.cfg.ChannelDB.GetInitialForwardingPolicy(chanID)
97✔
5285
}
97✔
5286

5287
// deleteInitialForwardingPolicy removes channel fees for this chanID from
5288
// the database.
5289
func (f *Manager) deleteInitialForwardingPolicy(chanID lnwire.ChannelID) error {
27✔
5290
        return f.cfg.ChannelDB.DeleteInitialForwardingPolicy(chanID)
27✔
5291
}
27✔
5292

5293
// saveChannelOpeningState saves the channelOpeningState for the provided
5294
// chanPoint to the channelOpeningStateBucket.
5295
func (f *Manager) saveChannelOpeningState(chanPoint *wire.OutPoint,
5296
        state channelOpeningState, shortChanID *lnwire.ShortChannelID) error {
95✔
5297

95✔
5298
        var outpointBytes bytes.Buffer
95✔
5299
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
95✔
5300
                return err
×
5301
        }
×
5302

5303
        // Save state and the uint64 representation of the shortChanID
5304
        // for later use.
5305
        scratch := make([]byte, 10)
95✔
5306
        byteOrder.PutUint16(scratch[:2], uint16(state))
95✔
5307
        byteOrder.PutUint64(scratch[2:], shortChanID.ToUint64())
95✔
5308

95✔
5309
        return f.cfg.ChannelDB.SaveChannelOpeningState(
95✔
5310
                outpointBytes.Bytes(), scratch,
95✔
5311
        )
95✔
5312
}
5313

5314
// getChannelOpeningState fetches the channelOpeningState for the provided
5315
// chanPoint from the database, or returns ErrChannelNotFound if the channel
5316
// is not found.
5317
func (f *Manager) getChannelOpeningState(chanPoint *wire.OutPoint) (
5318
        channelOpeningState, *lnwire.ShortChannelID, error) {
255✔
5319

255✔
5320
        var outpointBytes bytes.Buffer
255✔
5321
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
255✔
5322
                return 0, nil, err
×
5323
        }
×
5324

5325
        value, err := f.cfg.ChannelDB.GetChannelOpeningState(
255✔
5326
                outpointBytes.Bytes(),
255✔
5327
        )
255✔
5328
        if err != nil {
305✔
5329
                return 0, nil, err
50✔
5330
        }
50✔
5331

5332
        state := channelOpeningState(byteOrder.Uint16(value[:2]))
208✔
5333
        shortChanID := lnwire.NewShortChanIDFromInt(byteOrder.Uint64(value[2:]))
208✔
5334
        return state, &shortChanID, nil
208✔
5335
}
5336

5337
// deleteChannelOpeningState removes any state for chanPoint from the database.
5338
func (f *Manager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error {
27✔
5339
        var outpointBytes bytes.Buffer
27✔
5340
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
27✔
5341
                return err
×
5342
        }
×
5343

5344
        return f.cfg.ChannelDB.DeleteChannelOpeningState(
27✔
5345
                outpointBytes.Bytes(),
27✔
5346
        )
27✔
5347
}
5348

5349
// selectShutdownScript selects the shutdown script we should send to the peer.
5350
// If we can use taproot, then we prefer that, otherwise we'll use a p2wkh
5351
// script.
5352
func (f *Manager) selectShutdownScript(taprootOK bool,
5353
) (lnwire.DeliveryAddress, error) {
×
5354

×
5355
        addrType := lnwallet.WitnessPubKey
×
5356
        if taprootOK {
×
5357
                addrType = lnwallet.TaprootPubkey
×
5358
        }
×
5359

5360
        addr, err := f.cfg.Wallet.NewAddress(
×
5361
                addrType, false, lnwallet.DefaultAccountName,
×
5362
        )
×
5363
        if err != nil {
×
5364
                return nil, err
×
5365
        }
×
5366

5367
        return txscript.PayToAddrScript(addr)
×
5368
}
5369

5370
// waitForPeerOnline blocks until the peer specified by peerPubkey comes online
5371
// and then returns the online peer.
5372
func (f *Manager) waitForPeerOnline(peerPubkey *btcec.PublicKey) (lnpeer.Peer,
5373
        error) {
108✔
5374

108✔
5375
        peerChan := make(chan lnpeer.Peer, 1)
108✔
5376

108✔
5377
        var peerKey [33]byte
108✔
5378
        copy(peerKey[:], peerPubkey.SerializeCompressed())
108✔
5379

108✔
5380
        f.cfg.NotifyWhenOnline(peerKey, peerChan)
108✔
5381

108✔
5382
        var peer lnpeer.Peer
108✔
5383
        select {
108✔
5384
        case peer = <-peerChan:
107✔
5385
        case <-f.quit:
2✔
5386
                return peer, ErrFundingManagerShuttingDown
2✔
5387
        }
5388
        return peer, nil
107✔
5389
}
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