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

lightningnetwork / lnd / 10207481183

01 Aug 2024 11:52PM UTC coverage: 58.679% (+0.09%) from 58.591%
10207481183

push

github

web-flow
Merge pull request #8836 from hieblmi/payment-failure-reason-cancel

routing: add payment failure reason `FailureReasonCancel`

7 of 30 new or added lines in 5 files covered. (23.33%)

1662 existing lines in 21 files now uncovered.

125454 of 213798 relevant lines covered (58.68%)

28679.1 hits per line

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

74.9
/funding/manager.go
1
package funding
2

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

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

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

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

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

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

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

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

70
        byteOrder.PutUint32(scratch, o.Index)
372✔
71
        _, err := w.Write(scratch)
372✔
72
        return err
372✔
73
}
74

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

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

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

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

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

100
        // TODO(roasbeef): tune.
101
        msgBufferSize = 50
102

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

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

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

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

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

133
        zeroID [32]byte
134
)
135

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

149
        chanAmt btcutil.Amount
150

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

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

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

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

168
        updateMtx   sync.RWMutex
169
        lastUpdated time.Time
170

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

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

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

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

138✔
190
        r.lastUpdated = time.Now()
138✔
191
}
138✔
192

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

548
// Manager acts as an orchestrator/bridge between the wallet's
549
// 'ChannelReservation' workflow, and the wire protocol's funding initiation
550
// messages. Any requests to initiate the funding workflow for a channel,
551
// either kicked-off locally or remotely are handled by the funding manager.
552
// Once a channel's funding workflow has been completed, any local callers, the
553
// local peer, and possibly the remote peer are notified of the completion of
554
// the channel workflow. Additionally, any temporary or permanent access
555
// controls between the wallet and remote peers are enforced via the funding
556
// manager.
557
type Manager struct {
558
        started sync.Once
559
        stopped sync.Once
560

561
        // cfg is a copy of the configuration struct that the FundingManager
562
        // was initialized with.
563
        cfg *Config
564

565
        // chanIDKey is a cryptographically random key that's used to generate
566
        // temporary channel ID's.
567
        chanIDKey [32]byte
568

569
        // chanIDNonce is a nonce that's incremented for each new funding
570
        // reservation created.
571
        nonceMtx    sync.RWMutex
572
        chanIDNonce uint64
573

574
        // pendingMusigNonces is used to store the musig2 nonce we generate to
575
        // send funding locked until we receive a funding locked message from
576
        // the remote party. We'll use this to keep track of the nonce we
577
        // generated, so we send the local+remote nonces to the peer state
578
        // machine.
579
        //
580
        // NOTE: This map is protected by the nonceMtx above.
581
        //
582
        // TODO(roasbeef): replace w/ generic concurrent map
583
        pendingMusigNonces map[lnwire.ChannelID]*musig2.Nonces
584

585
        // activeReservations is a map which houses the state of all pending
586
        // funding workflows.
587
        activeReservations map[serializedPubKey]pendingChannels
588

589
        // signedReservations is a utility map that maps the permanent channel
590
        // ID of a funding reservation to its temporary channel ID. This is
591
        // required as mid funding flow, we switch to referencing the channel
592
        // by its full channel ID once the commitment transactions have been
593
        // signed by both parties.
594
        signedReservations map[lnwire.ChannelID][32]byte
595

596
        // resMtx guards both of the maps above to ensure that all access is
597
        // goroutine safe.
598
        resMtx sync.RWMutex
599

600
        // fundingMsgs is a channel that relays fundingMsg structs from
601
        // external sub-systems using the ProcessFundingMsg call.
602
        fundingMsgs chan *fundingMsg
603

604
        // fundingRequests is a channel used to receive channel initiation
605
        // requests from a local subsystem within the daemon.
606
        fundingRequests chan *InitFundingMsg
607

608
        localDiscoverySignals *lnutils.SyncMap[lnwire.ChannelID, chan struct{}]
609

610
        handleChannelReadyBarriers *lnutils.SyncMap[lnwire.ChannelID, struct{}]
611

612
        quit chan struct{}
613
        wg   sync.WaitGroup
614
}
615

616
// channelOpeningState represents the different states a channel can be in
617
// between the funding transaction has been confirmed and the channel is
618
// announced to the network and ready to be used.
619
type channelOpeningState uint8
620

621
const (
622
        // markedOpen is the opening state of a channel if the funding
623
        // transaction is confirmed on-chain, but channelReady is not yet
624
        // successfully sent to the other peer.
625
        markedOpen channelOpeningState = iota
626

627
        // channelReadySent is the opening state of a channel if the
628
        // channelReady message has successfully been sent to the other peer,
629
        // but we still haven't announced the channel to the network.
630
        channelReadySent
631

632
        // addedToGraph is the opening state of a channel if the channel has
633
        // been successfully added to the graph immediately after the
634
        // channelReady message has been sent, but we still haven't announced
635
        // the channel to the network.
636
        addedToGraph
637
)
638

639
func (c channelOpeningState) String() string {
4✔
640
        switch c {
4✔
641
        case markedOpen:
4✔
642
                return "markedOpen"
4✔
643
        case channelReadySent:
4✔
644
                return "channelReadySent"
4✔
645
        case addedToGraph:
4✔
646
                return "addedToGraph"
4✔
647
        default:
×
648
                return "unknown"
×
649
        }
650
}
651

652
// NewFundingManager creates and initializes a new instance of the
653
// fundingManager.
654
func NewFundingManager(cfg Config) (*Manager, error) {
111✔
655
        return &Manager{
111✔
656
                cfg:       &cfg,
111✔
657
                chanIDKey: cfg.TempChanIDSeed,
111✔
658
                activeReservations: make(
111✔
659
                        map[serializedPubKey]pendingChannels,
111✔
660
                ),
111✔
661
                signedReservations: make(
111✔
662
                        map[lnwire.ChannelID][32]byte,
111✔
663
                ),
111✔
664
                fundingMsgs: make(
111✔
665
                        chan *fundingMsg, msgBufferSize,
111✔
666
                ),
111✔
667
                fundingRequests: make(
111✔
668
                        chan *InitFundingMsg, msgBufferSize,
111✔
669
                ),
111✔
670
                localDiscoverySignals: &lnutils.SyncMap[
111✔
671
                        lnwire.ChannelID, chan struct{},
111✔
672
                ]{},
111✔
673
                handleChannelReadyBarriers: &lnutils.SyncMap[
111✔
674
                        lnwire.ChannelID, struct{},
111✔
675
                ]{},
111✔
676
                pendingMusigNonces: make(
111✔
677
                        map[lnwire.ChannelID]*musig2.Nonces,
111✔
678
                ),
111✔
679
                quit: make(chan struct{}),
111✔
680
        }, nil
111✔
681
}
111✔
682

683
// Start launches all helper goroutines required for handling requests sent
684
// to the funding manager.
685
func (f *Manager) Start() error {
111✔
686
        var err error
111✔
687
        f.started.Do(func() {
222✔
688
                log.Info("Funding manager starting")
111✔
689
                err = f.start()
111✔
690
        })
111✔
691
        return err
111✔
692
}
693

694
func (f *Manager) start() error {
111✔
695
        // Upon restart, the Funding Manager will check the database to load any
111✔
696
        // channels that were  waiting for their funding transactions to be
111✔
697
        // confirmed on the blockchain at the time when the daemon last went
111✔
698
        // down.
111✔
699
        // TODO(roasbeef): store height that funding finished?
111✔
700
        //  * would then replace call below
111✔
701
        allChannels, err := f.cfg.ChannelDB.FetchAllChannels()
111✔
702
        if err != nil {
111✔
703
                return err
×
704
        }
×
705

706
        for _, channel := range allChannels {
124✔
707
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
13✔
708

13✔
709
                // For any channels that were in a pending state when the
13✔
710
                // daemon was last connected, the Funding Manager will
13✔
711
                // re-initialize the channel barriers, and republish the
13✔
712
                // funding transaction if we're the initiator.
13✔
713
                if channel.IsPending {
18✔
714
                        log.Tracef("Loading pending ChannelPoint(%v), "+
5✔
715
                                "creating chan barrier",
5✔
716
                                channel.FundingOutpoint)
5✔
717

5✔
718
                        f.localDiscoverySignals.Store(
5✔
719
                                chanID, make(chan struct{}),
5✔
720
                        )
5✔
721

5✔
722
                        // Rebroadcast the funding transaction for any pending
5✔
723
                        // channel that we initiated. No error will be returned
5✔
724
                        // if the transaction already has been broadcast.
5✔
725
                        chanType := channel.ChanType
5✔
726
                        if chanType.IsSingleFunder() &&
5✔
727
                                chanType.HasFundingTx() &&
5✔
728
                                channel.IsInitiator {
10✔
729

5✔
730
                                f.rebroadcastFundingTx(channel)
5✔
731
                        }
5✔
732
                } else if channel.ChanType.IsSingleFunder() &&
12✔
733
                        channel.ChanType.HasFundingTx() &&
12✔
734
                        channel.IsZeroConf() && channel.IsInitiator &&
12✔
735
                        !channel.ZeroConfConfirmed() {
14✔
736

2✔
737
                        // Rebroadcast the funding transaction for unconfirmed
2✔
738
                        // zero-conf channels if we have the funding tx and are
2✔
739
                        // also the initiator.
2✔
740
                        f.rebroadcastFundingTx(channel)
2✔
741
                }
2✔
742

743
                // We will restart the funding state machine for all channels,
744
                // which will wait for the channel's funding transaction to be
745
                // confirmed on the blockchain, and transmit the messages
746
                // necessary for the channel to be operational.
747
                f.wg.Add(1)
13✔
748
                go f.advanceFundingState(channel, chanID, nil)
13✔
749
        }
750

751
        f.wg.Add(1) // TODO(roasbeef): tune
111✔
752
        go f.reservationCoordinator()
111✔
753

111✔
754
        return nil
111✔
755
}
756

757
// Stop signals all helper goroutines to execute a graceful shutdown. This
758
// method will block until all goroutines have exited.
759
func (f *Manager) Stop() error {
108✔
760
        f.stopped.Do(func() {
215✔
761
                log.Info("Funding manager shutting down...")
107✔
762
                defer log.Debug("Funding manager shutdown complete")
107✔
763

107✔
764
                close(f.quit)
107✔
765
                f.wg.Wait()
107✔
766
        })
107✔
767

768
        return nil
108✔
769
}
770

771
// rebroadcastFundingTx publishes the funding tx on startup for each
772
// unconfirmed channel.
773
func (f *Manager) rebroadcastFundingTx(c *channeldb.OpenChannel) {
7✔
774
        var fundingTxBuf bytes.Buffer
7✔
775
        err := c.FundingTxn.Serialize(&fundingTxBuf)
7✔
776
        if err != nil {
7✔
777
                log.Errorf("Unable to serialize funding transaction %v: %v",
×
778
                        c.FundingTxn.TxHash(), err)
×
779

×
780
                // Clear the buffer of any bytes that were written before the
×
781
                // serialization error to prevent logging an incomplete
×
782
                // transaction.
×
783
                fundingTxBuf.Reset()
×
784
        } else {
7✔
785
                log.Debugf("Rebroadcasting funding tx for ChannelPoint(%v): "+
7✔
786
                        "%x", c.FundingOutpoint, fundingTxBuf.Bytes())
7✔
787
        }
7✔
788

789
        // Set a nil short channel ID at this stage because we do not know it
790
        // until our funding tx confirms.
791
        label := labels.MakeLabel(labels.LabelTypeChannelOpen, nil)
7✔
792

7✔
793
        err = f.cfg.PublishTransaction(c.FundingTxn, label)
7✔
794
        if err != nil {
7✔
795
                log.Errorf("Unable to rebroadcast funding tx %x for "+
×
796
                        "ChannelPoint(%v): %v", fundingTxBuf.Bytes(),
×
797
                        c.FundingOutpoint, err)
×
798
        }
×
799
}
800

801
// nextPendingChanID returns the next free pending channel ID to be used to
802
// identify a particular future channel funding workflow.
803
func (f *Manager) nextPendingChanID() [32]byte {
60✔
804
        // Obtain a fresh nonce. We do this by encoding the current nonce
60✔
805
        // counter, then incrementing it by one.
60✔
806
        f.nonceMtx.Lock()
60✔
807
        var nonce [8]byte
60✔
808
        binary.LittleEndian.PutUint64(nonce[:], f.chanIDNonce)
60✔
809
        f.chanIDNonce++
60✔
810
        f.nonceMtx.Unlock()
60✔
811

60✔
812
        // We'll generate the next pending channelID by "encrypting" 32-bytes
60✔
813
        // of zeroes which'll extract 32 random bytes from our stream cipher.
60✔
814
        var (
60✔
815
                nextChanID [32]byte
60✔
816
                zeroes     [32]byte
60✔
817
        )
60✔
818
        salsa20.XORKeyStream(nextChanID[:], zeroes[:], nonce[:], &f.chanIDKey)
60✔
819

60✔
820
        return nextChanID
60✔
821
}
60✔
822

823
// CancelPeerReservations cancels all active reservations associated with the
824
// passed node. This will ensure any outputs which have been pre committed,
825
// (and thus locked from coin selection), are properly freed.
826
func (f *Manager) CancelPeerReservations(nodePub [33]byte) {
4✔
827
        log.Debugf("Cancelling all reservations for peer %x", nodePub[:])
4✔
828

4✔
829
        f.resMtx.Lock()
4✔
830
        defer f.resMtx.Unlock()
4✔
831

4✔
832
        // We'll attempt to look up this node in the set of active
4✔
833
        // reservations.  If they don't have any, then there's no further work
4✔
834
        // to be done.
4✔
835
        nodeReservations, ok := f.activeReservations[nodePub]
4✔
836
        if !ok {
8✔
837
                log.Debugf("No active reservations for node: %x", nodePub[:])
4✔
838
                return
4✔
839
        }
4✔
840

841
        // If they do have any active reservations, then we'll cancel all of
842
        // them (which releases any locked UTXO's), and also delete it from the
843
        // reservation map.
844
        for pendingID, resCtx := range nodeReservations {
×
845
                if err := resCtx.reservation.Cancel(); err != nil {
×
846
                        log.Errorf("unable to cancel reservation for "+
×
847
                                "node=%x: %v", nodePub[:], err)
×
848
                }
×
849

850
                resCtx.err <- fmt.Errorf("peer disconnected")
×
851
                delete(nodeReservations, pendingID)
×
852
        }
853

854
        // Finally, we'll delete the node itself from the set of reservations.
855
        delete(f.activeReservations, nodePub)
×
856
}
857

858
// chanIdentifier wraps pending channel ID and channel ID into one struct so
859
// it's easier to identify a specific channel.
860
//
861
// TODO(yy): move to a different package to hide the private fields so direct
862
// access is disabled.
863
type chanIdentifier struct {
864
        // tempChanID is the pending channel ID created by the funder when
865
        // initializing the funding flow. For fundee, it's received from the
866
        // `open_channel` message.
867
        tempChanID lnwire.ChannelID
868

869
        // chanID is the channel ID created by the funder once the
870
        // `accept_channel` message is received. For fundee, it's received from
871
        // the `funding_created` message.
872
        chanID lnwire.ChannelID
873

874
        // chanIDSet is a boolean indicates whether the active channel ID is
875
        // set for this identifier. For zero conf channels, the `chanID` can be
876
        // all-zero, which is the same as the empty value of `ChannelID`. To
877
        // avoid the confusion, we use this boolean to explicitly signal
878
        // whether the `chanID` is set or not.
879
        chanIDSet bool
880
}
881

882
// newChanIdentifier creates a new chanIdentifier.
883
func newChanIdentifier(tempChanID lnwire.ChannelID) *chanIdentifier {
148✔
884
        return &chanIdentifier{
148✔
885
                tempChanID: tempChanID,
148✔
886
        }
148✔
887
}
148✔
888

889
// setChanID updates the `chanIdentifier` with the active channel ID.
890
func (c *chanIdentifier) setChanID(chanID lnwire.ChannelID) {
92✔
891
        c.chanID = chanID
92✔
892
        c.chanIDSet = true
92✔
893
}
92✔
894

895
// hasChanID returns true if the active channel ID has been set.
896
func (c *chanIdentifier) hasChanID() bool {
25✔
897
        return c.chanIDSet
25✔
898
}
25✔
899

900
// failFundingFlow will fail the active funding flow with the target peer,
901
// identified by its unique temporary channel ID. This method will send an
902
// error to the remote peer, and also remove the reservation from our set of
903
// pending reservations.
904
//
905
// TODO(roasbeef): if peer disconnects, and haven't yet broadcast funding
906
// transaction, then all reservations should be cleared.
907
func (f *Manager) failFundingFlow(peer lnpeer.Peer, cid *chanIdentifier,
908
        fundingErr error) {
25✔
909

25✔
910
        log.Debugf("Failing funding flow for pending_id=%v: %v",
25✔
911
                cid.tempChanID, fundingErr)
25✔
912

25✔
913
        // First, notify Brontide to remove the pending channel.
25✔
914
        //
25✔
915
        // NOTE: depending on where we fail the flow, we may not have the
25✔
916
        // active channel ID yet.
25✔
917
        if cid.hasChanID() {
34✔
918
                err := peer.RemovePendingChannel(cid.chanID)
9✔
919
                if err != nil {
9✔
920
                        log.Errorf("Unable to remove channel %v with peer %x: "+
×
921
                                "%v", cid,
×
922
                                peer.IdentityKey().SerializeCompressed(), err)
×
923
                }
×
924
        }
925

926
        ctx, err := f.cancelReservationCtx(
25✔
927
                peer.IdentityKey(), cid.tempChanID, false,
25✔
928
        )
25✔
929
        if err != nil {
38✔
930
                log.Errorf("unable to cancel reservation: %v", err)
13✔
931
        }
13✔
932

933
        // In case the case where the reservation existed, send the funding
934
        // error on the error channel.
935
        if ctx != nil {
41✔
936
                ctx.err <- fundingErr
16✔
937
        }
16✔
938

939
        // We only send the exact error if it is part of out whitelisted set of
940
        // errors (lnwire.FundingError or lnwallet.ReservationError).
941
        var msg lnwire.ErrorData
25✔
942
        switch e := fundingErr.(type) {
25✔
943
        // Let the actual error message be sent to the remote for the
944
        // whitelisted types.
945
        case lnwallet.ReservationError:
9✔
946
                msg = lnwire.ErrorData(e.Error())
9✔
947
        case lnwire.FundingError:
8✔
948
                msg = lnwire.ErrorData(e.Error())
8✔
949
        case chanacceptor.ChanAcceptError:
4✔
950
                msg = lnwire.ErrorData(e.Error())
4✔
951

952
        // For all other error types we just send a generic error.
953
        default:
16✔
954
                msg = lnwire.ErrorData("funding failed due to internal error")
16✔
955
        }
956

957
        errMsg := &lnwire.Error{
25✔
958
                ChanID: cid.tempChanID,
25✔
959
                Data:   msg,
25✔
960
        }
25✔
961

25✔
962
        log.Debugf("Sending funding error to peer (%x): %v",
25✔
963
                peer.IdentityKey().SerializeCompressed(), spew.Sdump(errMsg))
25✔
964
        if err := peer.SendMessage(false, errMsg); err != nil {
25✔
UNCOV
965
                log.Errorf("unable to send error message to peer %v", err)
×
UNCOV
966
        }
×
967
}
968

969
// sendWarning sends a new warning message to the target peer, targeting the
970
// specified cid with the passed funding error.
971
func (f *Manager) sendWarning(peer lnpeer.Peer, cid *chanIdentifier,
972
        fundingErr error) {
×
973

×
974
        msg := fundingErr.Error()
×
975

×
976
        errMsg := &lnwire.Warning{
×
977
                ChanID: cid.tempChanID,
×
978
                Data:   lnwire.WarningData(msg),
×
979
        }
×
980

×
981
        log.Debugf("Sending funding warning to peer (%x): %v",
×
982
                peer.IdentityKey().SerializeCompressed(),
×
983
                spew.Sdump(errMsg),
×
984
        )
×
985

×
986
        if err := peer.SendMessage(false, errMsg); err != nil {
×
987
                log.Errorf("unable to send error message to peer %v", err)
×
988
        }
×
989
}
990

991
// reservationCoordinator is the primary goroutine tasked with progressing the
992
// funding workflow between the wallet, and any outside peers or local callers.
993
//
994
// NOTE: This MUST be run as a goroutine.
995
func (f *Manager) reservationCoordinator() {
111✔
996
        defer f.wg.Done()
111✔
997

111✔
998
        zombieSweepTicker := time.NewTicker(f.cfg.ZombieSweeperInterval)
111✔
999
        defer zombieSweepTicker.Stop()
111✔
1000

111✔
1001
        for {
487✔
1002
                select {
376✔
1003
                case fmsg := <-f.fundingMsgs:
213✔
1004
                        switch msg := fmsg.msg.(type) {
213✔
1005
                        case *lnwire.OpenChannel:
57✔
1006
                                f.fundeeProcessOpenChannel(fmsg.peer, msg)
57✔
1007

1008
                        case *lnwire.AcceptChannel:
36✔
1009
                                f.funderProcessAcceptChannel(fmsg.peer, msg)
36✔
1010

1011
                        case *lnwire.FundingCreated:
31✔
1012
                                f.fundeeProcessFundingCreated(fmsg.peer, msg)
31✔
1013

1014
                        case *lnwire.FundingSigned:
31✔
1015
                                f.funderProcessFundingSigned(fmsg.peer, msg)
31✔
1016

1017
                        case *lnwire.ChannelReady:
32✔
1018
                                f.wg.Add(1)
32✔
1019
                                go f.handleChannelReady(fmsg.peer, msg)
32✔
1020

1021
                        case *lnwire.Warning:
42✔
1022
                                f.handleWarningMsg(fmsg.peer, msg)
42✔
1023

1024
                        case *lnwire.Error:
4✔
1025
                                f.handleErrorMsg(fmsg.peer, msg)
4✔
1026
                        }
1027
                case req := <-f.fundingRequests:
60✔
1028
                        f.handleInitFundingMsg(req)
60✔
1029

1030
                case <-zombieSweepTicker.C:
4✔
1031
                        f.pruneZombieReservations()
4✔
1032

1033
                case <-f.quit:
107✔
1034
                        return
107✔
1035
                }
1036
        }
1037
}
1038

1039
// advanceFundingState will advance the channel through the steps after the
1040
// funding transaction is broadcasted, up until the point where the channel is
1041
// ready for operation. This includes waiting for the funding transaction to
1042
// confirm, sending channel_ready to the peer, adding the channel to the graph,
1043
// and announcing the channel. The updateChan can be set non-nil to get
1044
// OpenStatusUpdates.
1045
//
1046
// NOTE: This MUST be run as a goroutine.
1047
func (f *Manager) advanceFundingState(channel *channeldb.OpenChannel,
1048
        pendingChanID [32]byte, updateChan chan<- *lnrpc.OpenStatusUpdate) {
67✔
1049

67✔
1050
        defer f.wg.Done()
67✔
1051

67✔
1052
        // If the channel is still pending we must wait for the funding
67✔
1053
        // transaction to confirm.
67✔
1054
        if channel.IsPending {
126✔
1055
                err := f.advancePendingChannelState(channel, pendingChanID)
59✔
1056
                if err != nil {
84✔
1057
                        log.Errorf("Unable to advance pending state of "+
25✔
1058
                                "ChannelPoint(%v): %v",
25✔
1059
                                channel.FundingOutpoint, err)
25✔
1060
                        return
25✔
1061
                }
25✔
1062
        }
1063

1064
        // We create the state-machine object which wraps the database state.
1065
        lnChannel, err := lnwallet.NewLightningChannel(
46✔
1066
                nil, channel, nil,
46✔
1067
        )
46✔
1068
        if err != nil {
46✔
1069
                log.Errorf("Unable to create LightningChannel(%v): %v",
×
1070
                        channel.FundingOutpoint, err)
×
1071
                return
×
1072
        }
×
1073

1074
        for {
198✔
1075
                channelState, shortChanID, err := f.getChannelOpeningState(
152✔
1076
                        &channel.FundingOutpoint,
152✔
1077
                )
152✔
1078
                if err == channeldb.ErrChannelNotFound {
181✔
1079
                        // Channel not in fundingManager's opening database,
29✔
1080
                        // meaning it was successfully announced to the
29✔
1081
                        // network.
29✔
1082
                        // TODO(halseth): could do graph consistency check
29✔
1083
                        // here, and re-add the edge if missing.
29✔
1084
                        log.Debugf("ChannelPoint(%v) with chan_id=%x not "+
29✔
1085
                                "found in opening database, assuming already "+
29✔
1086
                                "announced to the network",
29✔
1087
                                channel.FundingOutpoint, pendingChanID)
29✔
1088
                        return
29✔
1089
                } else if err != nil {
156✔
1090
                        log.Errorf("Unable to query database for "+
×
1091
                                "channel opening state(%v): %v",
×
1092
                                channel.FundingOutpoint, err)
×
1093
                        return
×
1094
                }
×
1095

1096
                // If we did find the channel in the opening state database, we
1097
                // have seen the funding transaction being confirmed, but there
1098
                // are still steps left of the setup procedure. We continue the
1099
                // procedure where we left off.
1100
                err = f.stateStep(
127✔
1101
                        channel, lnChannel, shortChanID, pendingChanID,
127✔
1102
                        channelState, updateChan,
127✔
1103
                )
127✔
1104
                if err != nil {
148✔
1105
                        log.Errorf("Unable to advance state(%v): %v",
21✔
1106
                                channel.FundingOutpoint, err)
21✔
1107
                        return
21✔
1108
                }
21✔
1109
        }
1110
}
1111

1112
// stateStep advances the confirmed channel one step in the funding state
1113
// machine. This method is synchronous and the new channel opening state will
1114
// have been written to the database when it successfully returns. The
1115
// updateChan can be set non-nil to get OpenStatusUpdates.
1116
func (f *Manager) stateStep(channel *channeldb.OpenChannel,
1117
        lnChannel *lnwallet.LightningChannel,
1118
        shortChanID *lnwire.ShortChannelID, pendingChanID [32]byte,
1119
        channelState channelOpeningState,
1120
        updateChan chan<- *lnrpc.OpenStatusUpdate) error {
127✔
1121

127✔
1122
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
127✔
1123
        log.Debugf("Channel(%v) with ShortChanID %v has opening state %v",
127✔
1124
                chanID, shortChanID, channelState)
127✔
1125

127✔
1126
        switch channelState {
127✔
1127
        // The funding transaction was confirmed, but we did not successfully
1128
        // send the channelReady message to the peer, so let's do that now.
1129
        case markedOpen:
39✔
1130
                err := f.sendChannelReady(channel, lnChannel)
39✔
1131
                if err != nil {
40✔
1132
                        return fmt.Errorf("failed sending channelReady: %w",
1✔
1133
                                err)
1✔
1134
                }
1✔
1135

1136
                // As the channelReady message is now sent to the peer, the
1137
                // channel is moved to the next state of the state machine. It
1138
                // will be moved to the last state (actually deleted from the
1139
                // database) after the channel is finally announced.
1140
                err = f.saveChannelOpeningState(
38✔
1141
                        &channel.FundingOutpoint, channelReadySent,
38✔
1142
                        shortChanID,
38✔
1143
                )
38✔
1144
                if err != nil {
38✔
1145
                        return fmt.Errorf("error setting channel state to"+
×
1146
                                " channelReadySent: %w", err)
×
1147
                }
×
1148

1149
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
38✔
1150
                        "sent ChannelReady", chanID, shortChanID)
38✔
1151

38✔
1152
                return nil
38✔
1153

1154
        // channelReady was sent to peer, but the channel was not added to the
1155
        // graph and the channel announcement was not sent.
1156
        case channelReadySent:
64✔
1157
                // We must wait until we've received the peer's channel_ready
64✔
1158
                // before sending a channel_update according to BOLT#07.
64✔
1159
                received, err := f.receivedChannelReady(
64✔
1160
                        channel.IdentityPub, chanID,
64✔
1161
                )
64✔
1162
                if err != nil {
64✔
1163
                        return fmt.Errorf("failed to check if channel_ready "+
×
1164
                                "was received: %v", err)
×
1165
                }
×
1166

1167
                if !received {
104✔
1168
                        // We haven't received ChannelReady, so we'll continue
40✔
1169
                        // to the next iteration of the loop after sleeping for
40✔
1170
                        // checkPeerChannelReadyInterval.
40✔
1171
                        select {
40✔
1172
                        case <-time.After(checkPeerChannelReadyInterval):
28✔
1173
                        case <-f.quit:
12✔
1174
                                return ErrFundingManagerShuttingDown
12✔
1175
                        }
1176

1177
                        return nil
28✔
1178
                }
1179

1180
                return f.handleChannelReadyReceived(
28✔
1181
                        channel, shortChanID, pendingChanID, updateChan,
28✔
1182
                )
28✔
1183

1184
        // The channel was added to the Router's topology, but the channel
1185
        // announcement was not sent.
1186
        case addedToGraph:
32✔
1187
                if channel.IsZeroConf() {
42✔
1188
                        // If this is a zero-conf channel, then we will wait
10✔
1189
                        // for it to be confirmed before announcing it to the
10✔
1190
                        // greater network.
10✔
1191
                        err := f.waitForZeroConfChannel(channel)
10✔
1192
                        if err != nil {
16✔
1193
                                return fmt.Errorf("failed waiting for zero "+
6✔
1194
                                        "channel: %v", err)
6✔
1195
                        }
6✔
1196

1197
                        // Update the local shortChanID variable such that
1198
                        // annAfterSixConfs uses the confirmed SCID.
1199
                        confirmedScid := channel.ZeroConfRealScid()
8✔
1200
                        shortChanID = &confirmedScid
8✔
1201
                }
1202

1203
                err := f.annAfterSixConfs(channel, shortChanID)
30✔
1204
                if err != nil {
36✔
1205
                        return fmt.Errorf("error sending channel "+
6✔
1206
                                "announcement: %v", err)
6✔
1207
                }
6✔
1208

1209
                // We delete the channel opening state from our internal
1210
                // database as the opening process has succeeded. We can do
1211
                // this because we assume the AuthenticatedGossiper queues the
1212
                // announcement messages, and persists them in case of a daemon
1213
                // shutdown.
1214
                err = f.deleteChannelOpeningState(&channel.FundingOutpoint)
28✔
1215
                if err != nil {
28✔
1216
                        return fmt.Errorf("error deleting channel state: %w",
×
1217
                                err)
×
1218
                }
×
1219

1220
                // After the fee parameters have been stored in the
1221
                // announcement we can delete them from the database. For
1222
                // private channels we do not announce the channel policy to
1223
                // the network but still need to delete them from the database.
1224
                err = f.deleteInitialForwardingPolicy(chanID)
28✔
1225
                if err != nil {
28✔
1226
                        log.Infof("Could not delete initial policy for chanId "+
×
1227
                                "%x", chanID)
×
1228
                }
×
1229

1230
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
28✔
1231
                        "announced", chanID, shortChanID)
28✔
1232

28✔
1233
                return nil
28✔
1234
        }
1235

1236
        return fmt.Errorf("undefined channelState: %v", channelState)
×
1237
}
1238

1239
// advancePendingChannelState waits for a pending channel's funding tx to
1240
// confirm, and marks it open in the database when that happens.
1241
func (f *Manager) advancePendingChannelState(
1242
        channel *channeldb.OpenChannel, pendingChanID [32]byte) error {
59✔
1243

59✔
1244
        if channel.IsZeroConf() {
67✔
1245
                // Persist the alias to the alias database.
8✔
1246
                baseScid := channel.ShortChannelID
8✔
1247
                err := f.cfg.AliasManager.AddLocalAlias(
8✔
1248
                        baseScid, baseScid, true,
8✔
1249
                )
8✔
1250
                if err != nil {
8✔
1251
                        return fmt.Errorf("error adding local alias to "+
×
1252
                                "store: %v", err)
×
1253
                }
×
1254

1255
                // We don't wait for zero-conf channels to be confirmed and
1256
                // instead immediately proceed with the rest of the funding
1257
                // flow. The channel opening state is stored under the alias
1258
                // SCID.
1259
                err = f.saveChannelOpeningState(
8✔
1260
                        &channel.FundingOutpoint, markedOpen,
8✔
1261
                        &channel.ShortChannelID,
8✔
1262
                )
8✔
1263
                if err != nil {
8✔
1264
                        return fmt.Errorf("error setting zero-conf channel "+
×
1265
                                "state to markedOpen: %v", err)
×
1266
                }
×
1267

1268
                // The ShortChannelID is already set since it's an alias, but
1269
                // we still need to mark the channel as no longer pending.
1270
                err = channel.MarkAsOpen(channel.ShortChannelID)
8✔
1271
                if err != nil {
8✔
1272
                        return fmt.Errorf("error setting zero-conf channel's "+
×
1273
                                "pending flag to false: %v", err)
×
1274
                }
×
1275

1276
                // Inform the ChannelNotifier that the channel has transitioned
1277
                // from pending open to open.
1278
                f.cfg.NotifyOpenChannelEvent(channel.FundingOutpoint)
8✔
1279

8✔
1280
                // Find and close the discoverySignal for this channel such
8✔
1281
                // that ChannelReady messages will be processed.
8✔
1282
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
8✔
1283
                discoverySignal, ok := f.localDiscoverySignals.Load(chanID)
8✔
1284
                if ok {
16✔
1285
                        close(discoverySignal)
8✔
1286
                }
8✔
1287

1288
                return nil
8✔
1289
        }
1290

1291
        confChannel, err := f.waitForFundingWithTimeout(channel)
55✔
1292
        if err == ErrConfirmationTimeout {
57✔
1293
                return f.fundingTimeout(channel, pendingChanID)
2✔
1294
        } else if err != nil {
78✔
1295
                return fmt.Errorf("error waiting for funding "+
23✔
1296
                        "confirmation for ChannelPoint(%v): %v",
23✔
1297
                        channel.FundingOutpoint, err)
23✔
1298
        }
23✔
1299

1300
        if blockchain.IsCoinBaseTx(confChannel.fundingTx) {
36✔
1301
                // If it's a coinbase transaction, we need to wait for it to
2✔
1302
                // mature. We wait out an additional MinAcceptDepth on top of
2✔
1303
                // the coinbase maturity as an extra margin of safety.
2✔
1304
                maturity := f.cfg.Wallet.Cfg.NetParams.CoinbaseMaturity
2✔
1305
                numCoinbaseConfs := uint32(maturity)
2✔
1306

2✔
1307
                if channel.NumConfsRequired > maturity {
2✔
1308
                        numCoinbaseConfs = uint32(channel.NumConfsRequired)
×
1309
                }
×
1310

1311
                txid := &channel.FundingOutpoint.Hash
2✔
1312
                fundingScript, err := makeFundingScript(channel)
2✔
1313
                if err != nil {
2✔
1314
                        log.Errorf("unable to create funding script for "+
×
1315
                                "ChannelPoint(%v): %v",
×
1316
                                channel.FundingOutpoint, err)
×
1317

×
1318
                        return err
×
1319
                }
×
1320

1321
                confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
2✔
1322
                        txid, fundingScript, numCoinbaseConfs,
2✔
1323
                        channel.BroadcastHeight(),
2✔
1324
                )
2✔
1325
                if err != nil {
2✔
1326
                        log.Errorf("Unable to register for confirmation of "+
×
1327
                                "ChannelPoint(%v): %v",
×
1328
                                channel.FundingOutpoint, err)
×
1329

×
1330
                        return err
×
1331
                }
×
1332

1333
                select {
2✔
1334
                case _, ok := <-confNtfn.Confirmed:
2✔
1335
                        if !ok {
2✔
1336
                                return fmt.Errorf("ChainNotifier shutting "+
×
1337
                                        "down, can't complete funding flow "+
×
1338
                                        "for ChannelPoint(%v)",
×
1339
                                        channel.FundingOutpoint)
×
1340
                        }
×
1341

1342
                case <-f.quit:
×
1343
                        return ErrFundingManagerShuttingDown
×
1344
                }
1345
        }
1346

1347
        // Success, funding transaction was confirmed.
1348
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
34✔
1349
        log.Debugf("ChannelID(%v) is now fully confirmed! "+
34✔
1350
                "(shortChanID=%v)", chanID, confChannel.shortChanID)
34✔
1351

34✔
1352
        err = f.handleFundingConfirmation(channel, confChannel)
34✔
1353
        if err != nil {
34✔
1354
                return fmt.Errorf("unable to handle funding "+
×
1355
                        "confirmation for ChannelPoint(%v): %v",
×
1356
                        channel.FundingOutpoint, err)
×
1357
        }
×
1358

1359
        return nil
34✔
1360
}
1361

1362
// ProcessFundingMsg sends a message to the internal fundingManager goroutine,
1363
// allowing it to handle the lnwire.Message.
1364
func (f *Manager) ProcessFundingMsg(msg lnwire.Message, peer lnpeer.Peer) {
214✔
1365
        select {
214✔
1366
        case f.fundingMsgs <- &fundingMsg{msg, peer}:
214✔
1367
        case <-f.quit:
×
1368
                return
×
1369
        }
1370
}
1371

1372
// fundeeProcessOpenChannel creates an initial 'ChannelReservation' within the
1373
// wallet, then responds to the source peer with an accept channel message
1374
// progressing the funding workflow.
1375
//
1376
// TODO(roasbeef): add error chan to all, let channelManager handle
1377
// error+propagate.
1378
//
1379
//nolint:funlen
1380
func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
1381
        msg *lnwire.OpenChannel) {
57✔
1382

57✔
1383
        // Check number of pending channels to be smaller than maximum allowed
57✔
1384
        // number and send ErrorGeneric to remote peer if condition is
57✔
1385
        // violated.
57✔
1386
        peerPubKey := peer.IdentityKey()
57✔
1387
        peerIDKey := newSerializedKey(peerPubKey)
57✔
1388

57✔
1389
        amt := msg.FundingAmount
57✔
1390

57✔
1391
        // We get all pending channels for this peer. This is the list of the
57✔
1392
        // active reservations and the channels pending open in the database.
57✔
1393
        f.resMtx.RLock()
57✔
1394
        reservations := f.activeReservations[peerIDKey]
57✔
1395

57✔
1396
        // We don't count reservations that were created from a canned funding
57✔
1397
        // shim. The user has registered the shim and therefore expects this
57✔
1398
        // channel to arrive.
57✔
1399
        numPending := 0
57✔
1400
        for _, res := range reservations {
69✔
1401
                if !res.reservation.IsCannedShim() {
24✔
1402
                        numPending++
12✔
1403
                }
12✔
1404
        }
1405
        f.resMtx.RUnlock()
57✔
1406

57✔
1407
        // Create the channel identifier.
57✔
1408
        cid := newChanIdentifier(msg.PendingChannelID)
57✔
1409

57✔
1410
        // Also count the channels that are already pending. There we don't know
57✔
1411
        // the underlying intent anymore, unfortunately.
57✔
1412
        channels, err := f.cfg.ChannelDB.FetchOpenChannels(peerPubKey)
57✔
1413
        if err != nil {
57✔
1414
                f.failFundingFlow(peer, cid, err)
×
1415
                return
×
1416
        }
×
1417

1418
        for _, c := range channels {
73✔
1419
                // Pending channels that have a non-zero thaw height were also
16✔
1420
                // created through a canned funding shim. Those also don't
16✔
1421
                // count towards the DoS protection limit.
16✔
1422
                //
16✔
1423
                // TODO(guggero): Properly store the funding type (wallet, shim,
16✔
1424
                // PSBT) on the channel so we don't need to use the thaw height.
16✔
1425
                if c.IsPending && c.ThawHeight == 0 {
28✔
1426
                        numPending++
12✔
1427
                }
12✔
1428
        }
1429

1430
        // TODO(roasbeef): modify to only accept a _single_ pending channel per
1431
        // block unless white listed
1432
        if numPending >= f.cfg.MaxPendingChannels {
65✔
1433
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
8✔
1434

8✔
1435
                return
8✔
1436
        }
8✔
1437

1438
        // Ensure that the pendingChansLimit is respected.
1439
        pendingChans, err := f.cfg.ChannelDB.FetchPendingChannels()
53✔
1440
        if err != nil {
53✔
1441
                f.failFundingFlow(peer, cid, err)
×
1442
                return
×
1443
        }
×
1444

1445
        if len(pendingChans) > pendingChansLimit {
53✔
1446
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
×
1447
                return
×
1448
        }
×
1449

1450
        // We'll also reject any requests to create channels until we're fully
1451
        // synced to the network as we won't be able to properly validate the
1452
        // confirmation of the funding transaction.
1453
        isSynced, _, err := f.cfg.Wallet.IsSynced()
53✔
1454
        if err != nil || !isSynced {
53✔
1455
                if err != nil {
×
1456
                        log.Errorf("unable to query wallet: %v", err)
×
1457
                }
×
1458
                err := errors.New("Synchronizing blockchain")
×
1459
                f.failFundingFlow(peer, cid, err)
×
1460
                return
×
1461
        }
1462

1463
        // Ensure that the remote party respects our maximum channel size.
1464
        if amt > f.cfg.MaxChanSize {
59✔
1465
                f.failFundingFlow(
6✔
1466
                        peer, cid,
6✔
1467
                        lnwallet.ErrChanTooLarge(amt, f.cfg.MaxChanSize),
6✔
1468
                )
6✔
1469
                return
6✔
1470
        }
6✔
1471

1472
        // We'll, also ensure that the remote party isn't attempting to propose
1473
        // a channel that's below our current min channel size.
1474
        if amt < f.cfg.MinChanSize {
55✔
1475
                f.failFundingFlow(
4✔
1476
                        peer, cid,
4✔
1477
                        lnwallet.ErrChanTooSmall(amt, f.cfg.MinChanSize),
4✔
1478
                )
4✔
1479
                return
4✔
1480
        }
4✔
1481

1482
        // If request specifies non-zero push amount and 'rejectpush' is set,
1483
        // signal an error.
1484
        if f.cfg.RejectPush && msg.PushAmount > 0 {
52✔
1485
                f.failFundingFlow(peer, cid, lnwallet.ErrNonZeroPushAmount())
1✔
1486
                return
1✔
1487
        }
1✔
1488

1489
        // Send the OpenChannel request to the ChannelAcceptor to determine
1490
        // whether this node will accept the channel.
1491
        chanReq := &chanacceptor.ChannelAcceptRequest{
50✔
1492
                Node:        peer.IdentityKey(),
50✔
1493
                OpenChanMsg: msg,
50✔
1494
        }
50✔
1495

50✔
1496
        // Query our channel acceptor to determine whether we should reject
50✔
1497
        // the channel.
50✔
1498
        acceptorResp := f.cfg.OpenChannelPredicate.Accept(chanReq)
50✔
1499
        if acceptorResp.RejectChannel() {
54✔
1500
                f.failFundingFlow(peer, cid, acceptorResp.ChanAcceptError)
4✔
1501
                return
4✔
1502
        }
4✔
1503

1504
        log.Infof("Recv'd fundingRequest(amt=%v, push=%v, delay=%v, "+
50✔
1505
                "pendingId=%x) from peer(%x)", amt, msg.PushAmount,
50✔
1506
                msg.CsvDelay, msg.PendingChannelID,
50✔
1507
                peer.IdentityKey().SerializeCompressed())
50✔
1508

50✔
1509
        // Attempt to initialize a reservation within the wallet. If the wallet
50✔
1510
        // has insufficient resources to create the channel, then the
50✔
1511
        // reservation attempt may be rejected. Note that since we're on the
50✔
1512
        // responding side of a single funder workflow, we don't commit any
50✔
1513
        // funds to the channel ourselves.
50✔
1514
        //
50✔
1515
        // Before we init the channel, we'll also check to see what commitment
50✔
1516
        // format we can use with this peer. This is dependent on *both* us and
50✔
1517
        // the remote peer are signaling the proper feature bit if we're using
50✔
1518
        // implicit negotiation, and simply the channel type sent over if we're
50✔
1519
        // using explicit negotiation.
50✔
1520
        chanType, commitType, err := negotiateCommitmentType(
50✔
1521
                msg.ChannelType, peer.LocalFeatures(), peer.RemoteFeatures(),
50✔
1522
        )
50✔
1523
        if err != nil {
50✔
1524
                // TODO(roasbeef): should be using soft errors
×
1525
                log.Errorf("channel type negotiation failed: %v", err)
×
1526
                f.failFundingFlow(peer, cid, err)
×
1527
                return
×
1528
        }
×
1529

1530
        var scidFeatureVal bool
50✔
1531
        if hasFeatures(
50✔
1532
                peer.LocalFeatures(), peer.RemoteFeatures(),
50✔
1533
                lnwire.ScidAliasOptional,
50✔
1534
        ) {
57✔
1535

7✔
1536
                scidFeatureVal = true
7✔
1537
        }
7✔
1538

1539
        var (
50✔
1540
                zeroConf bool
50✔
1541
                scid     bool
50✔
1542
        )
50✔
1543

50✔
1544
        // Only echo back a channel type in AcceptChannel if we actually used
50✔
1545
        // explicit negotiation above.
50✔
1546
        if chanType != nil {
58✔
1547
                // Check if the channel type includes the zero-conf or
8✔
1548
                // scid-alias bits.
8✔
1549
                featureVec := lnwire.RawFeatureVector(*chanType)
8✔
1550
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
8✔
1551
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
8✔
1552

8✔
1553
                // If the zero-conf channel type was negotiated, ensure that
8✔
1554
                // the acceptor allows it.
8✔
1555
                if zeroConf && !acceptorResp.ZeroConf {
8✔
1556
                        // Fail the funding flow.
×
1557
                        flowErr := fmt.Errorf("channel acceptor blocked " +
×
1558
                                "zero-conf channel negotiation")
×
1559
                        log.Errorf("Cancelling funding flow for %v based on "+
×
1560
                                "channel acceptor response: %v", cid, flowErr)
×
1561
                        f.failFundingFlow(peer, cid, flowErr)
×
1562
                        return
×
1563
                }
×
1564

1565
                // If the zero-conf channel type wasn't negotiated and the
1566
                // fundee still wants a zero-conf channel, perform more checks.
1567
                // Require that both sides have the scid-alias feature bit set.
1568
                // We don't require anchors here - this is for compatibility
1569
                // with LDK.
1570
                if !zeroConf && acceptorResp.ZeroConf {
8✔
1571
                        if !scidFeatureVal {
×
1572
                                // Fail the funding flow.
×
1573
                                flowErr := fmt.Errorf("scid-alias feature " +
×
1574
                                        "must be negotiated for zero-conf")
×
1575
                                log.Errorf("Cancelling funding flow for "+
×
1576
                                        "zero-conf channel %v: %v", cid,
×
1577
                                        flowErr)
×
1578
                                f.failFundingFlow(peer, cid, flowErr)
×
1579
                                return
×
1580
                        }
×
1581

1582
                        // Set zeroConf to true to enable the zero-conf flow.
1583
                        zeroConf = true
×
1584
                }
1585
        }
1586

1587
        public := msg.ChannelFlags&lnwire.FFAnnounceChannel != 0
50✔
1588
        switch {
50✔
1589
        // Sending the option-scid-alias channel type for a public channel is
1590
        // disallowed.
1591
        case public && scid:
×
1592
                err = fmt.Errorf("option-scid-alias chantype for public " +
×
1593
                        "channel")
×
1594
                log.Errorf("Cancelling funding flow for public channel %v "+
×
1595
                        "with scid-alias: %v", cid, err)
×
1596
                f.failFundingFlow(peer, cid, err)
×
1597

×
1598
                return
×
1599

1600
        // The current variant of taproot channels can only be used with
1601
        // unadvertised channels for now.
1602
        case commitType.IsTaproot() && public:
×
1603
                err = fmt.Errorf("taproot channel type for public channel")
×
1604
                log.Errorf("Cancelling funding flow for public taproot "+
×
1605
                        "channel %v: %v", cid, err)
×
1606
                f.failFundingFlow(peer, cid, err)
×
1607

×
1608
                return
×
1609
        }
1610

1611
        req := &lnwallet.InitFundingReserveMsg{
50✔
1612
                ChainHash:        &msg.ChainHash,
50✔
1613
                PendingChanID:    msg.PendingChannelID,
50✔
1614
                NodeID:           peer.IdentityKey(),
50✔
1615
                NodeAddr:         peer.Address(),
50✔
1616
                LocalFundingAmt:  0,
50✔
1617
                RemoteFundingAmt: amt,
50✔
1618
                CommitFeePerKw:   chainfee.SatPerKWeight(msg.FeePerKiloWeight),
50✔
1619
                FundingFeePerKw:  0,
50✔
1620
                PushMSat:         msg.PushAmount,
50✔
1621
                Flags:            msg.ChannelFlags,
50✔
1622
                MinConfs:         1,
50✔
1623
                CommitType:       commitType,
50✔
1624
                ZeroConf:         zeroConf,
50✔
1625
                OptionScidAlias:  scid,
50✔
1626
                ScidAliasFeature: scidFeatureVal,
50✔
1627
        }
50✔
1628

50✔
1629
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
50✔
1630
        if err != nil {
50✔
1631
                log.Errorf("Unable to initialize reservation: %v", err)
×
1632
                f.failFundingFlow(peer, cid, err)
×
1633
                return
×
1634
        }
×
1635

1636
        log.Debugf("Initialized channel reservation: zeroConf=%v, psbt=%v, "+
50✔
1637
                "cannedShim=%v", reservation.IsZeroConf(),
50✔
1638
                reservation.IsPsbt(), reservation.IsCannedShim())
50✔
1639

50✔
1640
        if zeroConf {
56✔
1641
                // Store an alias for zero-conf channels. Other option-scid
6✔
1642
                // channels will do this at a later point.
6✔
1643
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
6✔
1644
                if err != nil {
6✔
1645
                        log.Errorf("Unable to request alias: %v", err)
×
1646
                        f.failFundingFlow(peer, cid, err)
×
1647
                        return
×
1648
                }
×
1649

1650
                reservation.AddAlias(aliasScid)
6✔
1651
        }
1652

1653
        // As we're the responder, we get to specify the number of confirmations
1654
        // that we require before both of us consider the channel open. We'll
1655
        // use our mapping to derive the proper number of confirmations based on
1656
        // the amount of the channel, and also if any funds are being pushed to
1657
        // us. If a depth value was set by our channel acceptor, we will use
1658
        // that value instead.
1659
        numConfsReq := f.cfg.NumRequiredConfs(msg.FundingAmount, msg.PushAmount)
50✔
1660
        if acceptorResp.MinAcceptDepth != 0 {
50✔
1661
                numConfsReq = acceptorResp.MinAcceptDepth
×
1662
        }
×
1663

1664
        // We'll ignore the min_depth calculated above if this is a zero-conf
1665
        // channel.
1666
        if zeroConf {
56✔
1667
                numConfsReq = 0
6✔
1668
        }
6✔
1669

1670
        reservation.SetNumConfsRequired(numConfsReq)
50✔
1671

50✔
1672
        // We'll also validate and apply all the constraints the initiating
50✔
1673
        // party is attempting to dictate for our commitment transaction.
50✔
1674
        channelConstraints := &channeldb.ChannelConstraints{
50✔
1675
                DustLimit:        msg.DustLimit,
50✔
1676
                ChanReserve:      msg.ChannelReserve,
50✔
1677
                MaxPendingAmount: msg.MaxValueInFlight,
50✔
1678
                MinHTLC:          msg.HtlcMinimum,
50✔
1679
                MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs,
50✔
1680
                CsvDelay:         msg.CsvDelay,
50✔
1681
        }
50✔
1682
        err = reservation.CommitConstraints(
50✔
1683
                channelConstraints, f.cfg.MaxLocalCSVDelay, true,
50✔
1684
        )
50✔
1685
        if err != nil {
50✔
UNCOV
1686
                log.Errorf("Unacceptable channel constraints: %v", err)
×
UNCOV
1687
                f.failFundingFlow(peer, cid, err)
×
UNCOV
1688
                return
×
UNCOV
1689
        }
×
1690

1691
        // Check whether the peer supports upfront shutdown, and get a new
1692
        // wallet address if our node is configured to set shutdown addresses by
1693
        // default. We use the upfront shutdown script provided by our channel
1694
        // acceptor (if any) in lieu of user input.
1695
        shutdown, err := getUpfrontShutdownScript(
50✔
1696
                f.cfg.EnableUpfrontShutdown, peer, acceptorResp.UpfrontShutdown,
50✔
1697
                f.selectShutdownScript,
50✔
1698
        )
50✔
1699
        if err != nil {
50✔
1700
                f.failFundingFlow(
×
1701
                        peer, cid,
×
1702
                        fmt.Errorf("getUpfrontShutdownScript error: %w", err),
×
1703
                )
×
1704
                return
×
1705
        }
×
1706
        reservation.SetOurUpfrontShutdown(shutdown)
50✔
1707

50✔
1708
        // If a script enforced channel lease is being proposed, we'll need to
50✔
1709
        // validate its custom TLV records.
50✔
1710
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
54✔
1711
                if msg.LeaseExpiry == nil {
4✔
1712
                        err := errors.New("missing lease expiry")
×
1713
                        f.failFundingFlow(peer, cid, err)
×
1714
                        return
×
1715
                }
×
1716

1717
                // If we had a shim registered for this channel prior to
1718
                // receiving its corresponding OpenChannel message, then we'll
1719
                // validate the proposed LeaseExpiry against what was registered
1720
                // in our shim.
1721
                if reservation.LeaseExpiry() != 0 {
8✔
1722
                        if uint32(*msg.LeaseExpiry) !=
4✔
1723
                                reservation.LeaseExpiry() {
4✔
1724

×
1725
                                err := errors.New("lease expiry mismatch")
×
1726
                                f.failFundingFlow(peer, cid, err)
×
1727
                                return
×
1728
                        }
×
1729
                }
1730
        }
1731

1732
        log.Infof("Requiring %v confirmations for pendingChan(%x): "+
50✔
1733
                "amt=%v, push_amt=%v, committype=%v, upfrontShutdown=%x",
50✔
1734
                numConfsReq, msg.PendingChannelID, amt, msg.PushAmount,
50✔
1735
                commitType, msg.UpfrontShutdownScript)
50✔
1736

50✔
1737
        // Generate our required constraints for the remote party, using the
50✔
1738
        // values provided by the channel acceptor if they are non-zero.
50✔
1739
        remoteCsvDelay := f.cfg.RequiredRemoteDelay(amt)
50✔
1740
        if acceptorResp.CSVDelay != 0 {
50✔
1741
                remoteCsvDelay = acceptorResp.CSVDelay
×
1742
        }
×
1743

1744
        // If our default dust limit was above their ChannelReserve, we change
1745
        // it to the ChannelReserve. We must make sure the ChannelReserve we
1746
        // send in the AcceptChannel message is above both dust limits.
1747
        // Therefore, take the maximum of msg.DustLimit and our dust limit.
1748
        //
1749
        // NOTE: Even with this bounding, the ChannelAcceptor may return an
1750
        // BOLT#02-invalid ChannelReserve.
1751
        maxDustLimit := reservation.OurContribution().DustLimit
50✔
1752
        if msg.DustLimit > maxDustLimit {
50✔
1753
                maxDustLimit = msg.DustLimit
×
1754
        }
×
1755

1756
        chanReserve := f.cfg.RequiredRemoteChanReserve(amt, maxDustLimit)
50✔
1757
        if acceptorResp.Reserve != 0 {
50✔
1758
                chanReserve = acceptorResp.Reserve
×
1759
        }
×
1760

1761
        remoteMaxValue := f.cfg.RequiredRemoteMaxValue(amt)
50✔
1762
        if acceptorResp.InFlightTotal != 0 {
50✔
1763
                remoteMaxValue = acceptorResp.InFlightTotal
×
1764
        }
×
1765

1766
        maxHtlcs := f.cfg.RequiredRemoteMaxHTLCs(amt)
50✔
1767
        if acceptorResp.HtlcLimit != 0 {
50✔
1768
                maxHtlcs = acceptorResp.HtlcLimit
×
1769
        }
×
1770

1771
        // Default to our default minimum hltc value, replacing it with the
1772
        // channel acceptor's value if it is set.
1773
        minHtlc := f.cfg.DefaultMinHtlcIn
50✔
1774
        if acceptorResp.MinHtlcIn != 0 {
50✔
1775
                minHtlc = acceptorResp.MinHtlcIn
×
1776
        }
×
1777

1778
        // If we are handling a FundingOpen request then we need to specify the
1779
        // default channel fees since they are not provided by the responder
1780
        // interactively.
1781
        ourContribution := reservation.OurContribution()
50✔
1782
        forwardingPolicy := f.defaultForwardingPolicy(
50✔
1783
                ourContribution.ChannelConstraints,
50✔
1784
        )
50✔
1785

50✔
1786
        // Once the reservation has been created successfully, we add it to
50✔
1787
        // this peer's map of pending reservations to track this particular
50✔
1788
        // reservation until either abort or completion.
50✔
1789
        f.resMtx.Lock()
50✔
1790
        if _, ok := f.activeReservations[peerIDKey]; !ok {
96✔
1791
                f.activeReservations[peerIDKey] = make(pendingChannels)
46✔
1792
        }
46✔
1793
        resCtx := &reservationWithCtx{
50✔
1794
                reservation:       reservation,
50✔
1795
                chanAmt:           amt,
50✔
1796
                forwardingPolicy:  *forwardingPolicy,
50✔
1797
                remoteCsvDelay:    remoteCsvDelay,
50✔
1798
                remoteMinHtlc:     minHtlc,
50✔
1799
                remoteMaxValue:    remoteMaxValue,
50✔
1800
                remoteMaxHtlcs:    maxHtlcs,
50✔
1801
                remoteChanReserve: chanReserve,
50✔
1802
                maxLocalCsv:       f.cfg.MaxLocalCSVDelay,
50✔
1803
                channelType:       chanType,
50✔
1804
                err:               make(chan error, 1),
50✔
1805
                peer:              peer,
50✔
1806
        }
50✔
1807
        f.activeReservations[peerIDKey][msg.PendingChannelID] = resCtx
50✔
1808
        f.resMtx.Unlock()
50✔
1809

50✔
1810
        // Update the timestamp once the fundingOpenMsg has been handled.
50✔
1811
        defer resCtx.updateTimestamp()
50✔
1812

50✔
1813
        // With our parameters set, we'll now process their contribution so we
50✔
1814
        // can move the funding workflow ahead.
50✔
1815
        remoteContribution := &lnwallet.ChannelContribution{
50✔
1816
                FundingAmount:        amt,
50✔
1817
                FirstCommitmentPoint: msg.FirstCommitmentPoint,
50✔
1818
                ChannelConfig: &channeldb.ChannelConfig{
50✔
1819
                        ChannelConstraints: channeldb.ChannelConstraints{
50✔
1820
                                DustLimit:        msg.DustLimit,
50✔
1821
                                MaxPendingAmount: remoteMaxValue,
50✔
1822
                                ChanReserve:      chanReserve,
50✔
1823
                                MinHTLC:          minHtlc,
50✔
1824
                                MaxAcceptedHtlcs: maxHtlcs,
50✔
1825
                                CsvDelay:         remoteCsvDelay,
50✔
1826
                        },
50✔
1827
                        MultiSigKey: keychain.KeyDescriptor{
50✔
1828
                                PubKey: copyPubKey(msg.FundingKey),
50✔
1829
                        },
50✔
1830
                        RevocationBasePoint: keychain.KeyDescriptor{
50✔
1831
                                PubKey: copyPubKey(msg.RevocationPoint),
50✔
1832
                        },
50✔
1833
                        PaymentBasePoint: keychain.KeyDescriptor{
50✔
1834
                                PubKey: copyPubKey(msg.PaymentPoint),
50✔
1835
                        },
50✔
1836
                        DelayBasePoint: keychain.KeyDescriptor{
50✔
1837
                                PubKey: copyPubKey(msg.DelayedPaymentPoint),
50✔
1838
                        },
50✔
1839
                        HtlcBasePoint: keychain.KeyDescriptor{
50✔
1840
                                PubKey: copyPubKey(msg.HtlcPoint),
50✔
1841
                        },
50✔
1842
                },
50✔
1843
                UpfrontShutdown: msg.UpfrontShutdownScript,
50✔
1844
        }
50✔
1845

50✔
1846
        if resCtx.reservation.IsTaproot() {
56✔
1847
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
6✔
1848
                if err != nil {
6✔
1849
                        log.Error(errNoLocalNonce)
×
1850

×
1851
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
1852

×
1853
                        return
×
1854
                }
×
1855

1856
                remoteContribution.LocalNonce = &musig2.Nonces{
6✔
1857
                        PubNonce: localNonce,
6✔
1858
                }
6✔
1859
        }
1860

1861
        err = reservation.ProcessSingleContribution(remoteContribution)
50✔
1862
        if err != nil {
56✔
1863
                log.Errorf("unable to add contribution reservation: %v", err)
6✔
1864
                f.failFundingFlow(peer, cid, err)
6✔
1865
                return
6✔
1866
        }
6✔
1867

1868
        log.Infof("Sending fundingResp for pending_id(%x)",
44✔
1869
                msg.PendingChannelID)
44✔
1870
        log.Debugf("Remote party accepted commitment constraints: %v",
44✔
1871
                spew.Sdump(remoteContribution.ChannelConfig.ChannelConstraints))
44✔
1872

44✔
1873
        // With the initiator's contribution recorded, respond with our
44✔
1874
        // contribution in the next message of the workflow.
44✔
1875
        fundingAccept := lnwire.AcceptChannel{
44✔
1876
                PendingChannelID:      msg.PendingChannelID,
44✔
1877
                DustLimit:             ourContribution.DustLimit,
44✔
1878
                MaxValueInFlight:      remoteMaxValue,
44✔
1879
                ChannelReserve:        chanReserve,
44✔
1880
                MinAcceptDepth:        uint32(numConfsReq),
44✔
1881
                HtlcMinimum:           minHtlc,
44✔
1882
                CsvDelay:              remoteCsvDelay,
44✔
1883
                MaxAcceptedHTLCs:      maxHtlcs,
44✔
1884
                FundingKey:            ourContribution.MultiSigKey.PubKey,
44✔
1885
                RevocationPoint:       ourContribution.RevocationBasePoint.PubKey,
44✔
1886
                PaymentPoint:          ourContribution.PaymentBasePoint.PubKey,
44✔
1887
                DelayedPaymentPoint:   ourContribution.DelayBasePoint.PubKey,
44✔
1888
                HtlcPoint:             ourContribution.HtlcBasePoint.PubKey,
44✔
1889
                FirstCommitmentPoint:  ourContribution.FirstCommitmentPoint,
44✔
1890
                UpfrontShutdownScript: ourContribution.UpfrontShutdown,
44✔
1891
                ChannelType:           chanType,
44✔
1892
                LeaseExpiry:           msg.LeaseExpiry,
44✔
1893
        }
44✔
1894

44✔
1895
        if commitType.IsTaproot() {
50✔
1896
                fundingAccept.LocalNonce = lnwire.SomeMusig2Nonce(
6✔
1897
                        ourContribution.LocalNonce.PubNonce,
6✔
1898
                )
6✔
1899
        }
6✔
1900

1901
        if err := peer.SendMessage(true, &fundingAccept); err != nil {
44✔
1902
                log.Errorf("unable to send funding response to peer: %v", err)
×
1903
                f.failFundingFlow(peer, cid, err)
×
1904
                return
×
1905
        }
×
1906
}
1907

1908
// funderProcessAcceptChannel processes a response to the workflow initiation
1909
// sent by the remote peer. This message then queues a message with the funding
1910
// outpoint, and a commitment signature to the remote peer.
1911
//
1912
//nolint:funlen
1913
func (f *Manager) funderProcessAcceptChannel(peer lnpeer.Peer,
1914
        msg *lnwire.AcceptChannel) {
36✔
1915

36✔
1916
        pendingChanID := msg.PendingChannelID
36✔
1917
        peerKey := peer.IdentityKey()
36✔
1918
        var peerKeyBytes []byte
36✔
1919
        if peerKey != nil {
72✔
1920
                peerKeyBytes = peerKey.SerializeCompressed()
36✔
1921
        }
36✔
1922

1923
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
36✔
1924
        if err != nil {
36✔
1925
                log.Warnf("Can't find reservation (peerKey:%x, chan_id:%v)",
×
1926
                        peerKeyBytes, pendingChanID)
×
1927
                return
×
1928
        }
×
1929

1930
        // Update the timestamp once the fundingAcceptMsg has been handled.
1931
        defer resCtx.updateTimestamp()
36✔
1932

36✔
1933
        log.Infof("Recv'd fundingResponse for pending_id(%x)",
36✔
1934
                pendingChanID[:])
36✔
1935

36✔
1936
        // Create the channel identifier.
36✔
1937
        cid := newChanIdentifier(msg.PendingChannelID)
36✔
1938

36✔
1939
        // Perform some basic validation of any custom TLV records included.
36✔
1940
        //
36✔
1941
        // TODO: Return errors as funding.Error to give context to remote peer?
36✔
1942
        if resCtx.channelType != nil {
44✔
1943
                // We'll want to quickly check that the ChannelType echoed by
8✔
1944
                // the channel request recipient matches what we proposed.
8✔
1945
                if msg.ChannelType == nil {
9✔
1946
                        err := errors.New("explicit channel type not echoed " +
1✔
1947
                                "back")
1✔
1948
                        f.failFundingFlow(peer, cid, err)
1✔
1949
                        return
1✔
1950
                }
1✔
1951
                proposedFeatures := lnwire.RawFeatureVector(*resCtx.channelType)
7✔
1952
                ackedFeatures := lnwire.RawFeatureVector(*msg.ChannelType)
7✔
1953
                if !proposedFeatures.Equals(&ackedFeatures) {
7✔
1954
                        err := errors.New("channel type mismatch")
×
1955
                        f.failFundingFlow(peer, cid, err)
×
1956
                        return
×
1957
                }
×
1958

1959
                // We'll want to do the same with the LeaseExpiry if one should
1960
                // be set.
1961
                if resCtx.reservation.LeaseExpiry() != 0 {
11✔
1962
                        if msg.LeaseExpiry == nil {
4✔
1963
                                err := errors.New("lease expiry not echoed " +
×
1964
                                        "back")
×
1965
                                f.failFundingFlow(peer, cid, err)
×
1966
                                return
×
1967
                        }
×
1968
                        if uint32(*msg.LeaseExpiry) !=
4✔
1969
                                resCtx.reservation.LeaseExpiry() {
4✔
1970

×
1971
                                err := errors.New("lease expiry mismatch")
×
1972
                                f.failFundingFlow(peer, cid, err)
×
1973
                                return
×
1974
                        }
×
1975
                }
1976
        } else if msg.ChannelType != nil {
28✔
1977
                // The spec isn't too clear about whether it's okay to set the
×
1978
                // channel type in the accept_channel response if we didn't
×
1979
                // explicitly set it in the open_channel message. For now, we
×
1980
                // check that it's the same type we'd have arrived through
×
1981
                // implicit negotiation. If it's another type, we fail the flow.
×
1982
                _, implicitCommitType := implicitNegotiateCommitmentType(
×
1983
                        peer.LocalFeatures(), peer.RemoteFeatures(),
×
1984
                )
×
1985

×
1986
                _, negotiatedCommitType, err := negotiateCommitmentType(
×
1987
                        msg.ChannelType, peer.LocalFeatures(),
×
1988
                        peer.RemoteFeatures(),
×
1989
                )
×
1990
                if err != nil {
×
1991
                        err := errors.New("received unexpected channel type")
×
1992
                        f.failFundingFlow(peer, cid, err)
×
1993
                        return
×
1994
                }
×
1995

1996
                if implicitCommitType != negotiatedCommitType {
×
1997
                        err := errors.New("negotiated unexpected channel type")
×
1998
                        f.failFundingFlow(peer, cid, err)
×
1999
                        return
×
2000
                }
×
2001
        }
2002

2003
        // The required number of confirmations should not be greater than the
2004
        // maximum number of confirmations required by the ChainNotifier to
2005
        // properly dispatch confirmations.
2006
        if msg.MinAcceptDepth > chainntnfs.MaxNumConfs {
36✔
2007
                err := lnwallet.ErrNumConfsTooLarge(
1✔
2008
                        msg.MinAcceptDepth, chainntnfs.MaxNumConfs,
1✔
2009
                )
1✔
2010
                log.Warnf("Unacceptable channel constraints: %v", err)
1✔
2011
                f.failFundingFlow(peer, cid, err)
1✔
2012
                return
1✔
2013
        }
1✔
2014

2015
        // Check that zero-conf channels have minimum depth set to 0.
2016
        if resCtx.reservation.IsZeroConf() && msg.MinAcceptDepth != 0 {
34✔
2017
                err = fmt.Errorf("zero-conf channel has min_depth non-zero")
×
2018
                log.Warn(err)
×
2019
                f.failFundingFlow(peer, cid, err)
×
2020
                return
×
2021
        }
×
2022

2023
        // If this is not a zero-conf channel but the peer responded with a
2024
        // min-depth of zero, we will use our minimum of 1 instead.
2025
        minDepth := msg.MinAcceptDepth
34✔
2026
        if !resCtx.reservation.IsZeroConf() && minDepth == 0 {
34✔
2027
                log.Infof("Responder to pending_id=%v sent a minimum "+
×
2028
                        "confirmation depth of 0 for non-zero-conf channel. "+
×
2029
                        "We will use a minimum depth of 1 instead.",
×
2030
                        cid.tempChanID)
×
2031

×
2032
                minDepth = 1
×
2033
        }
×
2034

2035
        // We'll also specify the responder's preference for the number of
2036
        // required confirmations, and also the set of channel constraints
2037
        // they've specified for commitment states we can create.
2038
        resCtx.reservation.SetNumConfsRequired(uint16(minDepth))
34✔
2039
        channelConstraints := &channeldb.ChannelConstraints{
34✔
2040
                DustLimit:        msg.DustLimit,
34✔
2041
                ChanReserve:      msg.ChannelReserve,
34✔
2042
                MaxPendingAmount: msg.MaxValueInFlight,
34✔
2043
                MinHTLC:          msg.HtlcMinimum,
34✔
2044
                MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs,
34✔
2045
                CsvDelay:         msg.CsvDelay,
34✔
2046
        }
34✔
2047
        err = resCtx.reservation.CommitConstraints(
34✔
2048
                channelConstraints, resCtx.maxLocalCsv, false,
34✔
2049
        )
34✔
2050
        if err != nil {
35✔
2051
                log.Warnf("Unacceptable channel constraints: %v", err)
1✔
2052
                f.failFundingFlow(peer, cid, err)
1✔
2053
                return
1✔
2054
        }
1✔
2055

2056
        // The remote node has responded with their portion of the channel
2057
        // contribution. At this point, we can process their contribution which
2058
        // allows us to construct and sign both the commitment transaction, and
2059
        // the funding transaction.
2060
        remoteContribution := &lnwallet.ChannelContribution{
33✔
2061
                FirstCommitmentPoint: msg.FirstCommitmentPoint,
33✔
2062
                ChannelConfig: &channeldb.ChannelConfig{
33✔
2063
                        ChannelConstraints: channeldb.ChannelConstraints{
33✔
2064
                                DustLimit:        msg.DustLimit,
33✔
2065
                                MaxPendingAmount: resCtx.remoteMaxValue,
33✔
2066
                                ChanReserve:      resCtx.remoteChanReserve,
33✔
2067
                                MinHTLC:          resCtx.remoteMinHtlc,
33✔
2068
                                MaxAcceptedHtlcs: resCtx.remoteMaxHtlcs,
33✔
2069
                                CsvDelay:         resCtx.remoteCsvDelay,
33✔
2070
                        },
33✔
2071
                        MultiSigKey: keychain.KeyDescriptor{
33✔
2072
                                PubKey: copyPubKey(msg.FundingKey),
33✔
2073
                        },
33✔
2074
                        RevocationBasePoint: keychain.KeyDescriptor{
33✔
2075
                                PubKey: copyPubKey(msg.RevocationPoint),
33✔
2076
                        },
33✔
2077
                        PaymentBasePoint: keychain.KeyDescriptor{
33✔
2078
                                PubKey: copyPubKey(msg.PaymentPoint),
33✔
2079
                        },
33✔
2080
                        DelayBasePoint: keychain.KeyDescriptor{
33✔
2081
                                PubKey: copyPubKey(msg.DelayedPaymentPoint),
33✔
2082
                        },
33✔
2083
                        HtlcBasePoint: keychain.KeyDescriptor{
33✔
2084
                                PubKey: copyPubKey(msg.HtlcPoint),
33✔
2085
                        },
33✔
2086
                },
33✔
2087
                UpfrontShutdown: msg.UpfrontShutdownScript,
33✔
2088
        }
33✔
2089

33✔
2090
        if resCtx.reservation.IsTaproot() {
39✔
2091
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
6✔
2092
                if err != nil {
6✔
2093
                        log.Error(errNoLocalNonce)
×
2094

×
2095
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
2096

×
2097
                        return
×
2098
                }
×
2099

2100
                remoteContribution.LocalNonce = &musig2.Nonces{
6✔
2101
                        PubNonce: localNonce,
6✔
2102
                }
6✔
2103
        }
2104

2105
        err = resCtx.reservation.ProcessContribution(remoteContribution)
33✔
2106

33✔
2107
        // The wallet has detected that a PSBT funding process was requested by
33✔
2108
        // the user and has halted the funding process after negotiating the
33✔
2109
        // multisig keys. We now have everything that is needed for the user to
33✔
2110
        // start constructing a PSBT that sends to the multisig funding address.
33✔
2111
        var psbtIntent *chanfunding.PsbtIntent
33✔
2112
        if psbtErr, ok := err.(*lnwallet.PsbtFundingRequired); ok {
37✔
2113
                // Return the information that is needed by the user to
4✔
2114
                // construct the PSBT back to the caller.
4✔
2115
                addr, amt, packet, err := psbtErr.Intent.FundingParams()
4✔
2116
                if err != nil {
4✔
2117
                        log.Errorf("Unable to process PSBT funding params "+
×
2118
                                "for contribution from %x: %v", peerKeyBytes,
×
2119
                                err)
×
2120
                        f.failFundingFlow(peer, cid, err)
×
2121
                        return
×
2122
                }
×
2123
                var buf bytes.Buffer
4✔
2124
                err = packet.Serialize(&buf)
4✔
2125
                if err != nil {
4✔
2126
                        log.Errorf("Unable to serialize PSBT for "+
×
2127
                                "contribution from %x: %v", peerKeyBytes, err)
×
2128
                        f.failFundingFlow(peer, cid, err)
×
2129
                        return
×
2130
                }
×
2131
                resCtx.updates <- &lnrpc.OpenStatusUpdate{
4✔
2132
                        PendingChanId: pendingChanID[:],
4✔
2133
                        Update: &lnrpc.OpenStatusUpdate_PsbtFund{
4✔
2134
                                PsbtFund: &lnrpc.ReadyForPsbtFunding{
4✔
2135
                                        FundingAddress: addr.EncodeAddress(),
4✔
2136
                                        FundingAmount:  amt,
4✔
2137
                                        Psbt:           buf.Bytes(),
4✔
2138
                                },
4✔
2139
                        },
4✔
2140
                }
4✔
2141
                psbtIntent = psbtErr.Intent
4✔
2142
        } else if err != nil {
33✔
2143
                log.Errorf("Unable to process contribution from %x: %v",
×
2144
                        peerKeyBytes, err)
×
2145
                f.failFundingFlow(peer, cid, err)
×
2146
                return
×
2147
        }
×
2148

2149
        log.Infof("pendingChan(%x): remote party proposes num_confs=%v, "+
33✔
2150
                "csv_delay=%v", pendingChanID[:], msg.MinAcceptDepth,
33✔
2151
                msg.CsvDelay)
33✔
2152
        log.Debugf("Remote party accepted commitment constraints: %v",
33✔
2153
                spew.Sdump(remoteContribution.ChannelConfig.ChannelConstraints))
33✔
2154

33✔
2155
        // If the user requested funding through a PSBT, we cannot directly
33✔
2156
        // continue now and need to wait for the fully funded and signed PSBT
33✔
2157
        // to arrive. To not block any other channels from opening, we wait in
33✔
2158
        // a separate goroutine.
33✔
2159
        if psbtIntent != nil {
37✔
2160
                f.wg.Add(1)
4✔
2161
                go func() {
8✔
2162
                        defer f.wg.Done()
4✔
2163

4✔
2164
                        f.waitForPsbt(psbtIntent, resCtx, cid)
4✔
2165
                }()
4✔
2166

2167
                // With the new goroutine spawned, we can now exit to unblock
2168
                // the main event loop.
2169
                return
4✔
2170
        }
2171

2172
        // In a normal, non-PSBT funding flow, we can jump directly to the next
2173
        // step where we expect our contribution to be finalized.
2174
        f.continueFundingAccept(resCtx, cid)
33✔
2175
}
2176

2177
// waitForPsbt blocks until either a signed PSBT arrives, an error occurs or
2178
// the funding manager shuts down. In the case of a valid PSBT, the funding flow
2179
// is continued.
2180
//
2181
// NOTE: This method must be called as a goroutine.
2182
func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
2183
        resCtx *reservationWithCtx, cid *chanIdentifier) {
4✔
2184

4✔
2185
        // failFlow is a helper that logs an error message with the current
4✔
2186
        // context and then fails the funding flow.
4✔
2187
        peerKey := resCtx.peer.IdentityKey()
4✔
2188
        failFlow := func(errMsg string, cause error) {
8✔
2189
                log.Errorf("Unable to handle funding accept message "+
4✔
2190
                        "for peer_key=%x, pending_chan_id=%x: %s: %v",
4✔
2191
                        peerKey.SerializeCompressed(), cid.tempChanID, errMsg,
4✔
2192
                        cause)
4✔
2193
                f.failFundingFlow(resCtx.peer, cid, cause)
4✔
2194
        }
4✔
2195

2196
        // We'll now wait until the intent has received the final and complete
2197
        // funding transaction. If the channel is closed without any error being
2198
        // sent, we know everything's going as expected.
2199
        select {
4✔
2200
        case err := <-intent.PsbtReady:
4✔
2201
                switch err {
4✔
2202
                // If the user canceled the funding reservation, we need to
2203
                // inform the other peer about us canceling the reservation.
2204
                case chanfunding.ErrUserCanceled:
4✔
2205
                        failFlow("aborting PSBT flow", err)
4✔
2206
                        return
4✔
2207

2208
                // If the remote canceled the funding reservation, we don't need
2209
                // to send another fail message. But we want to inform the user
2210
                // about what happened.
2211
                case chanfunding.ErrRemoteCanceled:
4✔
2212
                        log.Infof("Remote canceled, aborting PSBT flow "+
4✔
2213
                                "for peer_key=%x, pending_chan_id=%x",
4✔
2214
                                peerKey.SerializeCompressed(), cid.tempChanID)
4✔
2215
                        return
4✔
2216

2217
                // Nil error means the flow continues normally now.
2218
                case nil:
4✔
2219

2220
                // For any other error, we'll fail the funding flow.
2221
                default:
×
2222
                        failFlow("error waiting for PSBT flow", err)
×
2223
                        return
×
2224
                }
2225

2226
                // A non-nil error means we can continue the funding flow.
2227
                // Notify the wallet so it can prepare everything we need to
2228
                // continue.
2229
                err = resCtx.reservation.ProcessPsbt()
4✔
2230
                if err != nil {
4✔
2231
                        failFlow("error continuing PSBT flow", err)
×
2232
                        return
×
2233
                }
×
2234

2235
                // We are now ready to continue the funding flow.
2236
                f.continueFundingAccept(resCtx, cid)
4✔
2237

2238
        // Handle a server shutdown as well because the reservation won't
2239
        // survive a restart as it's in memory only.
2240
        case <-f.quit:
×
2241
                log.Errorf("Unable to handle funding accept message "+
×
2242
                        "for peer_key=%x, pending_chan_id=%x: funding manager "+
×
2243
                        "shutting down", peerKey.SerializeCompressed(),
×
2244
                        cid.tempChanID)
×
2245
                return
×
2246
        }
2247
}
2248

2249
// continueFundingAccept continues the channel funding flow once our
2250
// contribution is finalized, the channel output is known and the funding
2251
// transaction is signed.
2252
func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
2253
        cid *chanIdentifier) {
33✔
2254

33✔
2255
        // Now that we have their contribution, we can extract, then send over
33✔
2256
        // both the funding out point and our signature for their version of
33✔
2257
        // the commitment transaction to the remote peer.
33✔
2258
        outPoint := resCtx.reservation.FundingOutpoint()
33✔
2259
        _, sig := resCtx.reservation.OurSignatures()
33✔
2260

33✔
2261
        // A new channel has almost finished the funding process. In order to
33✔
2262
        // properly synchronize with the writeHandler goroutine, we add a new
33✔
2263
        // channel to the barriers map which will be closed once the channel is
33✔
2264
        // fully open.
33✔
2265
        channelID := lnwire.NewChanIDFromOutPoint(*outPoint)
33✔
2266
        log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
33✔
2267

33✔
2268
        // The next message that advances the funding flow will reference the
33✔
2269
        // channel via its permanent channel ID, so we'll set up this mapping
33✔
2270
        // so we can retrieve the reservation context once we get the
33✔
2271
        // FundingSigned message.
33✔
2272
        f.resMtx.Lock()
33✔
2273
        f.signedReservations[channelID] = cid.tempChanID
33✔
2274
        f.resMtx.Unlock()
33✔
2275

33✔
2276
        log.Infof("Generated ChannelPoint(%v) for pending_id(%x)", outPoint,
33✔
2277
                cid.tempChanID[:])
33✔
2278

33✔
2279
        // Before sending FundingCreated sent, we notify Brontide to keep track
33✔
2280
        // of this pending open channel.
33✔
2281
        err := resCtx.peer.AddPendingChannel(channelID, f.quit)
33✔
2282
        if err != nil {
33✔
2283
                pubKey := resCtx.peer.IdentityKey().SerializeCompressed()
×
2284
                log.Errorf("Unable to add pending channel %v with peer %x: %v",
×
2285
                        channelID, pubKey, err)
×
2286
        }
×
2287

2288
        // Once Brontide is aware of this channel, we need to set it in
2289
        // chanIdentifier so this channel will be removed from Brontide if the
2290
        // funding flow fails.
2291
        cid.setChanID(channelID)
33✔
2292

33✔
2293
        // Send the FundingCreated msg.
33✔
2294
        fundingCreated := &lnwire.FundingCreated{
33✔
2295
                PendingChannelID: cid.tempChanID,
33✔
2296
                FundingPoint:     *outPoint,
33✔
2297
        }
33✔
2298

33✔
2299
        // If this is a taproot channel, then we'll need to populate the musig2
33✔
2300
        // partial sig field instead of the regular commit sig field.
33✔
2301
        if resCtx.reservation.IsTaproot() {
39✔
2302
                partialSig, ok := sig.(*lnwallet.MusigPartialSig)
6✔
2303
                if !ok {
6✔
2304
                        err := fmt.Errorf("expected musig partial sig, got %T",
×
2305
                                sig)
×
2306
                        log.Error(err)
×
2307
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2308

×
2309
                        return
×
2310
                }
×
2311

2312
                fundingCreated.PartialSig = lnwire.MaybePartialSigWithNonce(
6✔
2313
                        partialSig.ToWireSig(),
6✔
2314
                )
6✔
2315
        } else {
31✔
2316
                fundingCreated.CommitSig, err = lnwire.NewSigFromSignature(sig)
31✔
2317
                if err != nil {
31✔
2318
                        log.Errorf("Unable to parse signature: %v", err)
×
2319
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2320
                        return
×
2321
                }
×
2322
        }
2323

2324
        if err := resCtx.peer.SendMessage(true, fundingCreated); err != nil {
33✔
2325
                log.Errorf("Unable to send funding complete message: %v", err)
×
2326
                f.failFundingFlow(resCtx.peer, cid, err)
×
2327
                return
×
2328
        }
×
2329
}
2330

2331
// fundeeProcessFundingCreated progresses the funding workflow when the daemon
2332
// is on the responding side of a single funder workflow. Once this message has
2333
// been processed, a signature is sent to the remote peer allowing it to
2334
// broadcast the funding transaction, progressing the workflow into the final
2335
// stage.
2336
//
2337
//nolint:funlen
2338
func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
2339
        msg *lnwire.FundingCreated) {
31✔
2340

31✔
2341
        peerKey := peer.IdentityKey()
31✔
2342
        pendingChanID := msg.PendingChannelID
31✔
2343

31✔
2344
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
31✔
2345
        if err != nil {
31✔
2346
                log.Warnf("can't find reservation (peer_id:%v, chan_id:%x)",
×
2347
                        peerKey, pendingChanID[:])
×
2348
                return
×
2349
        }
×
2350

2351
        // The channel initiator has responded with the funding outpoint of the
2352
        // final funding transaction, as well as a signature for our version of
2353
        // the commitment transaction. So at this point, we can validate the
2354
        // initiator's commitment transaction, then send our own if it's valid.
2355
        // TODO(roasbeef): make case (p vs P) consistent throughout
2356
        fundingOut := msg.FundingPoint
31✔
2357
        log.Infof("completing pending_id(%x) with ChannelPoint(%v)",
31✔
2358
                pendingChanID[:], fundingOut)
31✔
2359

31✔
2360
        // Create the channel identifier without setting the active channel ID.
31✔
2361
        cid := newChanIdentifier(pendingChanID)
31✔
2362

31✔
2363
        // For taproot channels, the commit signature is actually the partial
31✔
2364
        // signature. Otherwise, we can convert the ECDSA commit signature into
31✔
2365
        // our internal input.Signature type.
31✔
2366
        var commitSig input.Signature
31✔
2367
        if resCtx.reservation.IsTaproot() {
37✔
2368
                partialSig, err := msg.PartialSig.UnwrapOrErrV(errNoPartialSig)
6✔
2369
                if err != nil {
6✔
2370
                        f.failFundingFlow(peer, cid, err)
×
2371

×
2372
                        return
×
2373
                }
×
2374

2375
                commitSig = new(lnwallet.MusigPartialSig).FromWireSig(
6✔
2376
                        &partialSig,
6✔
2377
                )
6✔
2378
        } else {
29✔
2379
                commitSig, err = msg.CommitSig.ToSignature()
29✔
2380
                if err != nil {
29✔
2381
                        log.Errorf("unable to parse signature: %v", err)
×
2382
                        f.failFundingFlow(peer, cid, err)
×
2383
                        return
×
2384
                }
×
2385
        }
2386

2387
        // With all the necessary data available, attempt to advance the
2388
        // funding workflow to the next stage. If this succeeds then the
2389
        // funding transaction will broadcast after our next message.
2390
        // CompleteReservationSingle will also mark the channel as 'IsPending'
2391
        // in the database.
2392
        completeChan, err := resCtx.reservation.CompleteReservationSingle(
31✔
2393
                &fundingOut, commitSig,
31✔
2394
        )
31✔
2395
        if err != nil {
31✔
2396
                // TODO(roasbeef): better error logging: peerID, channelID, etc.
×
2397
                log.Errorf("unable to complete single reservation: %v", err)
×
2398
                f.failFundingFlow(peer, cid, err)
×
2399
                return
×
2400
        }
×
2401

2402
        // Get forwarding policy before deleting the reservation context.
2403
        forwardingPolicy := resCtx.forwardingPolicy
31✔
2404

31✔
2405
        // The channel is marked IsPending in the database, and can be removed
31✔
2406
        // from the set of active reservations.
31✔
2407
        f.deleteReservationCtx(peerKey, cid.tempChanID)
31✔
2408

31✔
2409
        // If something goes wrong before the funding transaction is confirmed,
31✔
2410
        // we use this convenience method to delete the pending OpenChannel
31✔
2411
        // from the database.
31✔
2412
        deleteFromDatabase := func() {
31✔
2413
                localBalance := completeChan.LocalCommitment.LocalBalance.ToSatoshis()
×
2414
                closeInfo := &channeldb.ChannelCloseSummary{
×
2415
                        ChanPoint:               completeChan.FundingOutpoint,
×
2416
                        ChainHash:               completeChan.ChainHash,
×
2417
                        RemotePub:               completeChan.IdentityPub,
×
2418
                        CloseType:               channeldb.FundingCanceled,
×
2419
                        Capacity:                completeChan.Capacity,
×
2420
                        SettledBalance:          localBalance,
×
2421
                        RemoteCurrentRevocation: completeChan.RemoteCurrentRevocation,
×
2422
                        RemoteNextRevocation:    completeChan.RemoteNextRevocation,
×
2423
                        LocalChanConfig:         completeChan.LocalChanCfg,
×
2424
                }
×
2425

×
2426
                // Close the channel with us as the initiator because we are
×
2427
                // deciding to exit the funding flow due to an internal error.
×
2428
                if err := completeChan.CloseChannel(
×
2429
                        closeInfo, channeldb.ChanStatusLocalCloseInitiator,
×
2430
                ); err != nil {
×
2431
                        log.Errorf("Failed closing channel %v: %v",
×
2432
                                completeChan.FundingOutpoint, err)
×
2433
                }
×
2434
        }
2435

2436
        // A new channel has almost finished the funding process. In order to
2437
        // properly synchronize with the writeHandler goroutine, we add a new
2438
        // channel to the barriers map which will be closed once the channel is
2439
        // fully open.
2440
        channelID := lnwire.NewChanIDFromOutPoint(fundingOut)
31✔
2441
        log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
31✔
2442

31✔
2443
        fundingSigned := &lnwire.FundingSigned{}
31✔
2444

31✔
2445
        // For taproot channels, we'll need to send over a partial signature
31✔
2446
        // that includes the nonce along side the signature.
31✔
2447
        _, sig := resCtx.reservation.OurSignatures()
31✔
2448
        if resCtx.reservation.IsTaproot() {
37✔
2449
                partialSig, ok := sig.(*lnwallet.MusigPartialSig)
6✔
2450
                if !ok {
6✔
2451
                        err := fmt.Errorf("expected musig partial sig, got %T",
×
2452
                                sig)
×
2453
                        log.Error(err)
×
2454
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2455
                        deleteFromDatabase()
×
2456

×
2457
                        return
×
2458
                }
×
2459

2460
                fundingSigned.PartialSig = lnwire.MaybePartialSigWithNonce(
6✔
2461
                        partialSig.ToWireSig(),
6✔
2462
                )
6✔
2463
        } else {
29✔
2464
                fundingSigned.CommitSig, err = lnwire.NewSigFromSignature(sig)
29✔
2465
                if err != nil {
29✔
2466
                        log.Errorf("unable to parse signature: %v", err)
×
2467
                        f.failFundingFlow(peer, cid, err)
×
2468
                        deleteFromDatabase()
×
2469

×
2470
                        return
×
2471
                }
×
2472
        }
2473

2474
        // Before sending FundingSigned, we notify Brontide first to keep track
2475
        // of this pending open channel.
2476
        if err := peer.AddPendingChannel(channelID, f.quit); err != nil {
31✔
2477
                pubKey := peer.IdentityKey().SerializeCompressed()
×
2478
                log.Errorf("Unable to add pending channel %v with peer %x: %v",
×
2479
                        cid.chanID, pubKey, err)
×
2480
        }
×
2481

2482
        // Once Brontide is aware of this channel, we need to set it in
2483
        // chanIdentifier so this channel will be removed from Brontide if the
2484
        // funding flow fails.
2485
        cid.setChanID(channelID)
31✔
2486

31✔
2487
        fundingSigned.ChanID = cid.chanID
31✔
2488

31✔
2489
        log.Infof("sending FundingSigned for pending_id(%x) over "+
31✔
2490
                "ChannelPoint(%v)", pendingChanID[:], fundingOut)
31✔
2491

31✔
2492
        // With their signature for our version of the commitment transaction
31✔
2493
        // verified, we can now send over our signature to the remote peer.
31✔
2494
        if err := peer.SendMessage(true, fundingSigned); err != nil {
31✔
2495
                log.Errorf("unable to send FundingSigned message: %v", err)
×
2496
                f.failFundingFlow(peer, cid, err)
×
2497
                deleteFromDatabase()
×
2498
                return
×
2499
        }
×
2500

2501
        // With a permanent channel id established we can save the respective
2502
        // forwarding policy in the database. In the channel announcement phase
2503
        // this forwarding policy is retrieved and applied.
2504
        err = f.saveInitialForwardingPolicy(cid.chanID, &forwardingPolicy)
31✔
2505
        if err != nil {
31✔
2506
                log.Errorf("Unable to store the forwarding policy: %v", err)
×
2507
        }
×
2508

2509
        // Now that we've sent over our final signature for this channel, we'll
2510
        // send it to the ChainArbitrator so it can watch for any on-chain
2511
        // actions during this final confirmation stage.
2512
        if err := f.cfg.WatchNewChannel(completeChan, peerKey); err != nil {
31✔
2513
                log.Errorf("Unable to send new ChannelPoint(%v) for "+
×
2514
                        "arbitration: %v", fundingOut, err)
×
2515
        }
×
2516

2517
        // Create an entry in the local discovery map so we can ensure that we
2518
        // process the channel confirmation fully before we receive a
2519
        // channel_ready message.
2520
        f.localDiscoverySignals.Store(cid.chanID, make(chan struct{}))
31✔
2521

31✔
2522
        // Inform the ChannelNotifier that the channel has entered
31✔
2523
        // pending open state.
31✔
2524
        f.cfg.NotifyPendingOpenChannelEvent(fundingOut, completeChan)
31✔
2525

31✔
2526
        // At this point we have sent our last funding message to the
31✔
2527
        // initiating peer before the funding transaction will be broadcast.
31✔
2528
        // With this last message, our job as the responder is now complete.
31✔
2529
        // We'll wait for the funding transaction to reach the specified number
31✔
2530
        // of confirmations, then start normal operations.
31✔
2531
        //
31✔
2532
        // When we get to this point we have sent the signComplete message to
31✔
2533
        // the channel funder, and BOLT#2 specifies that we MUST remember the
31✔
2534
        // channel for reconnection. The channel is already marked
31✔
2535
        // as pending in the database, so in case of a disconnect or restart,
31✔
2536
        // we will continue waiting for the confirmation the next time we start
31✔
2537
        // the funding manager. In case the funding transaction never appears
31✔
2538
        // on the blockchain, we must forget this channel. We therefore
31✔
2539
        // completely forget about this channel if we haven't seen the funding
31✔
2540
        // transaction in 288 blocks (~ 48 hrs), by canceling the reservation
31✔
2541
        // and canceling the wait for the funding confirmation.
31✔
2542
        f.wg.Add(1)
31✔
2543
        go f.advanceFundingState(completeChan, pendingChanID, nil)
31✔
2544
}
2545

2546
// funderProcessFundingSigned processes the final message received in a single
2547
// funder workflow. Once this message is processed, the funding transaction is
2548
// broadcast. Once the funding transaction reaches a sufficient number of
2549
// confirmations, a message is sent to the responding peer along with a compact
2550
// encoding of the location of the channel within the blockchain.
2551
func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
2552
        msg *lnwire.FundingSigned) {
31✔
2553

31✔
2554
        // As the funding signed message will reference the reservation by its
31✔
2555
        // permanent channel ID, we'll need to perform an intermediate look up
31✔
2556
        // before we can obtain the reservation.
31✔
2557
        f.resMtx.Lock()
31✔
2558
        pendingChanID, ok := f.signedReservations[msg.ChanID]
31✔
2559
        delete(f.signedReservations, msg.ChanID)
31✔
2560
        f.resMtx.Unlock()
31✔
2561

31✔
2562
        // Create the channel identifier and set the channel ID.
31✔
2563
        //
31✔
2564
        // NOTE: we may get an empty pending channel ID here if the key cannot
31✔
2565
        // be found, which means when we cancel the reservation context in
31✔
2566
        // `failFundingFlow`, we will get an error. In this case, we will send
31✔
2567
        // an error msg to our peer using the active channel ID.
31✔
2568
        //
31✔
2569
        // TODO(yy): refactor the funding flow to fix this case.
31✔
2570
        cid := newChanIdentifier(pendingChanID)
31✔
2571
        cid.setChanID(msg.ChanID)
31✔
2572

31✔
2573
        // If the pending channel ID is not found, fail the funding flow.
31✔
2574
        if !ok {
31✔
2575
                // NOTE: we directly overwrite the pending channel ID here for
×
2576
                // this rare case since we don't have a valid pending channel
×
2577
                // ID.
×
2578
                cid.tempChanID = msg.ChanID
×
2579

×
2580
                err := fmt.Errorf("unable to find signed reservation for "+
×
2581
                        "chan_id=%x", msg.ChanID)
×
2582
                log.Warnf(err.Error())
×
2583
                f.failFundingFlow(peer, cid, err)
×
2584
                return
×
2585
        }
×
2586

2587
        peerKey := peer.IdentityKey()
31✔
2588
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
31✔
2589
        if err != nil {
31✔
2590
                log.Warnf("Unable to find reservation (peer_id:%v, "+
×
2591
                        "chan_id:%x)", peerKey, pendingChanID[:])
×
2592
                // TODO: add ErrChanNotFound?
×
2593
                f.failFundingFlow(peer, cid, err)
×
2594
                return
×
2595
        }
×
2596

2597
        // Create an entry in the local discovery map so we can ensure that we
2598
        // process the channel confirmation fully before we receive a
2599
        // channel_ready message.
2600
        fundingPoint := resCtx.reservation.FundingOutpoint()
31✔
2601
        permChanID := lnwire.NewChanIDFromOutPoint(*fundingPoint)
31✔
2602
        f.localDiscoverySignals.Store(permChanID, make(chan struct{}))
31✔
2603

31✔
2604
        // We have to store the forwardingPolicy before the reservation context
31✔
2605
        // is deleted. The policy will then be read and applied in
31✔
2606
        // newChanAnnouncement.
31✔
2607
        err = f.saveInitialForwardingPolicy(
31✔
2608
                permChanID, &resCtx.forwardingPolicy,
31✔
2609
        )
31✔
2610
        if err != nil {
31✔
2611
                log.Errorf("Unable to store the forwarding policy: %v", err)
×
2612
        }
×
2613

2614
        // For taproot channels, the commit signature is actually the partial
2615
        // signature. Otherwise, we can convert the ECDSA commit signature into
2616
        // our internal input.Signature type.
2617
        var commitSig input.Signature
31✔
2618
        if resCtx.reservation.IsTaproot() {
37✔
2619
                partialSig, err := msg.PartialSig.UnwrapOrErrV(errNoPartialSig)
6✔
2620
                if err != nil {
6✔
2621
                        f.failFundingFlow(peer, cid, err)
×
2622

×
2623
                        return
×
2624
                }
×
2625

2626
                commitSig = new(lnwallet.MusigPartialSig).FromWireSig(
6✔
2627
                        &partialSig,
6✔
2628
                )
6✔
2629
        } else {
29✔
2630
                commitSig, err = msg.CommitSig.ToSignature()
29✔
2631
                if err != nil {
29✔
2632
                        log.Errorf("unable to parse signature: %v", err)
×
2633
                        f.failFundingFlow(peer, cid, err)
×
2634
                        return
×
2635
                }
×
2636
        }
2637

2638
        completeChan, err := resCtx.reservation.CompleteReservation(
31✔
2639
                nil, commitSig,
31✔
2640
        )
31✔
2641
        if err != nil {
31✔
2642
                log.Errorf("Unable to complete reservation sign "+
×
2643
                        "complete: %v", err)
×
2644
                f.failFundingFlow(peer, cid, err)
×
2645
                return
×
2646
        }
×
2647

2648
        // The channel is now marked IsPending in the database, and we can
2649
        // delete it from our set of active reservations.
2650
        f.deleteReservationCtx(peerKey, pendingChanID)
31✔
2651

31✔
2652
        // Broadcast the finalized funding transaction to the network, but only
31✔
2653
        // if we actually have the funding transaction.
31✔
2654
        if completeChan.ChanType.HasFundingTx() {
61✔
2655
                fundingTx := completeChan.FundingTxn
30✔
2656
                var fundingTxBuf bytes.Buffer
30✔
2657
                if err := fundingTx.Serialize(&fundingTxBuf); err != nil {
30✔
2658
                        log.Errorf("Unable to serialize funding "+
×
2659
                                "transaction %v: %v", fundingTx.TxHash(), err)
×
2660

×
2661
                        // Clear the buffer of any bytes that were written
×
2662
                        // before the serialization error to prevent logging an
×
2663
                        // incomplete transaction.
×
2664
                        fundingTxBuf.Reset()
×
2665
                }
×
2666

2667
                log.Infof("Broadcasting funding tx for ChannelPoint(%v): %x",
30✔
2668
                        completeChan.FundingOutpoint, fundingTxBuf.Bytes())
30✔
2669

30✔
2670
                // Set a nil short channel ID at this stage because we do not
30✔
2671
                // know it until our funding tx confirms.
30✔
2672
                label := labels.MakeLabel(
30✔
2673
                        labels.LabelTypeChannelOpen, nil,
30✔
2674
                )
30✔
2675

30✔
2676
                err = f.cfg.PublishTransaction(fundingTx, label)
30✔
2677
                if err != nil {
30✔
2678
                        log.Errorf("Unable to broadcast funding tx %x for "+
×
2679
                                "ChannelPoint(%v): %v", fundingTxBuf.Bytes(),
×
2680
                                completeChan.FundingOutpoint, err)
×
2681

×
2682
                        // We failed to broadcast the funding transaction, but
×
2683
                        // watch the channel regardless, in case the
×
2684
                        // transaction made it to the network. We will retry
×
2685
                        // broadcast at startup.
×
2686
                        //
×
2687
                        // TODO(halseth): retry more often? Handle with CPFP?
×
2688
                        // Just delete from the DB?
×
2689
                }
×
2690
        }
2691

2692
        // Now that we have a finalized reservation for this funding flow,
2693
        // we'll send the to be active channel to the ChainArbitrator so it can
2694
        // watch for any on-chain actions before the channel has fully
2695
        // confirmed.
2696
        if err := f.cfg.WatchNewChannel(completeChan, peerKey); err != nil {
31✔
2697
                log.Errorf("Unable to send new ChannelPoint(%v) for "+
×
2698
                        "arbitration: %v", fundingPoint, err)
×
2699
        }
×
2700

2701
        log.Infof("Finalizing pending_id(%x) over ChannelPoint(%v), "+
31✔
2702
                "waiting for channel open on-chain", pendingChanID[:],
31✔
2703
                fundingPoint)
31✔
2704

31✔
2705
        // Send an update to the upstream client that the negotiation process
31✔
2706
        // is over.
31✔
2707
        //
31✔
2708
        // TODO(roasbeef): add abstraction over updates to accommodate
31✔
2709
        // long-polling, or SSE, etc.
31✔
2710
        upd := &lnrpc.OpenStatusUpdate{
31✔
2711
                Update: &lnrpc.OpenStatusUpdate_ChanPending{
31✔
2712
                        ChanPending: &lnrpc.PendingUpdate{
31✔
2713
                                Txid:        fundingPoint.Hash[:],
31✔
2714
                                OutputIndex: fundingPoint.Index,
31✔
2715
                        },
31✔
2716
                },
31✔
2717
                PendingChanId: pendingChanID[:],
31✔
2718
        }
31✔
2719

31✔
2720
        select {
31✔
2721
        case resCtx.updates <- upd:
31✔
2722
                // Inform the ChannelNotifier that the channel has entered
31✔
2723
                // pending open state.
31✔
2724
                f.cfg.NotifyPendingOpenChannelEvent(*fundingPoint, completeChan)
31✔
2725
        case <-f.quit:
×
2726
                return
×
2727
        }
2728

2729
        // At this point we have broadcast the funding transaction and done all
2730
        // necessary processing.
2731
        f.wg.Add(1)
31✔
2732
        go f.advanceFundingState(completeChan, pendingChanID, resCtx.updates)
31✔
2733
}
2734

2735
// confirmedChannel wraps a confirmed funding transaction, as well as the short
2736
// channel ID which identifies that channel into a single struct. We'll use
2737
// this to pass around the final state of a channel after it has been
2738
// confirmed.
2739
type confirmedChannel struct {
2740
        // shortChanID expresses where in the block the funding transaction was
2741
        // located.
2742
        shortChanID lnwire.ShortChannelID
2743

2744
        // fundingTx is the funding transaction that created the channel.
2745
        fundingTx *wire.MsgTx
2746
}
2747

2748
// fundingTimeout is called when callers of waitForFundingWithTimeout receive
2749
// an ErrConfirmationTimeout. It is used to clean-up channel state and mark the
2750
// channel as closed. The error is only returned for the responder of the
2751
// channel flow.
2752
func (f *Manager) fundingTimeout(c *channeldb.OpenChannel,
2753
        pendingID [32]byte) error {
2✔
2754

2✔
2755
        // We'll get a timeout if the number of blocks mined since the channel
2✔
2756
        // was initiated reaches MaxWaitNumBlocksFundingConf and we are not the
2✔
2757
        // channel initiator.
2✔
2758
        localBalance := c.LocalCommitment.LocalBalance.ToSatoshis()
2✔
2759
        closeInfo := &channeldb.ChannelCloseSummary{
2✔
2760
                ChainHash:               c.ChainHash,
2✔
2761
                ChanPoint:               c.FundingOutpoint,
2✔
2762
                RemotePub:               c.IdentityPub,
2✔
2763
                Capacity:                c.Capacity,
2✔
2764
                SettledBalance:          localBalance,
2✔
2765
                CloseType:               channeldb.FundingCanceled,
2✔
2766
                RemoteCurrentRevocation: c.RemoteCurrentRevocation,
2✔
2767
                RemoteNextRevocation:    c.RemoteNextRevocation,
2✔
2768
                LocalChanConfig:         c.LocalChanCfg,
2✔
2769
        }
2✔
2770

2✔
2771
        // Close the channel with us as the initiator because we are timing the
2✔
2772
        // channel out.
2✔
2773
        if err := c.CloseChannel(
2✔
2774
                closeInfo, channeldb.ChanStatusLocalCloseInitiator,
2✔
2775
        ); err != nil {
2✔
2776
                return fmt.Errorf("failed closing channel %v: %w",
×
2777
                        c.FundingOutpoint, err)
×
2778
        }
×
2779

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

2✔
2783
        // When the peer comes online, we'll notify it that we are now
2✔
2784
        // considering the channel flow canceled.
2✔
2785
        f.wg.Add(1)
2✔
2786
        go func() {
4✔
2787
                defer f.wg.Done()
2✔
2788

2✔
2789
                peer, err := f.waitForPeerOnline(c.IdentityPub)
2✔
2790
                switch err {
2✔
2791
                // We're already shutting down, so we can just return.
2792
                case ErrFundingManagerShuttingDown:
×
2793
                        return
×
2794

2795
                // nil error means we continue on.
2796
                case nil:
2✔
2797

2798
                // For unexpected errors, we print the error and still try to
2799
                // fail the funding flow.
2800
                default:
×
2801
                        log.Errorf("Unexpected error while waiting for peer "+
×
2802
                                "to come online: %v", err)
×
2803
                }
2804

2805
                // Create channel identifier and set the channel ID.
2806
                cid := newChanIdentifier(pendingID)
2✔
2807
                cid.setChanID(lnwire.NewChanIDFromOutPoint(c.FundingOutpoint))
2✔
2808

2✔
2809
                // TODO(halseth): should this send be made
2✔
2810
                // reliable?
2✔
2811

2✔
2812
                // The reservation won't exist at this point, but we'll send an
2✔
2813
                // Error message over anyways with ChanID set to pendingID.
2✔
2814
                f.failFundingFlow(peer, cid, timeoutErr)
2✔
2815
        }()
2816

2817
        return timeoutErr
2✔
2818
}
2819

2820
// waitForFundingWithTimeout is a wrapper around waitForFundingConfirmation and
2821
// waitForTimeout that will return ErrConfirmationTimeout if we are not the
2822
// channel initiator and the MaxWaitNumBlocksFundingConf has passed from the
2823
// funding broadcast height. In case of confirmation, the short channel ID of
2824
// the channel and the funding transaction will be returned.
2825
func (f *Manager) waitForFundingWithTimeout(
2826
        ch *channeldb.OpenChannel) (*confirmedChannel, error) {
61✔
2827

61✔
2828
        confChan := make(chan *confirmedChannel)
61✔
2829
        timeoutChan := make(chan error, 1)
61✔
2830
        cancelChan := make(chan struct{})
61✔
2831

61✔
2832
        f.wg.Add(1)
61✔
2833
        go f.waitForFundingConfirmation(ch, cancelChan, confChan)
61✔
2834

61✔
2835
        // If we are not the initiator, we have no money at stake and will
61✔
2836
        // timeout waiting for the funding transaction to confirm after a
61✔
2837
        // while.
61✔
2838
        if !ch.IsInitiator && !ch.IsZeroConf() {
90✔
2839
                f.wg.Add(1)
29✔
2840
                go f.waitForTimeout(ch, cancelChan, timeoutChan)
29✔
2841
        }
29✔
2842
        defer close(cancelChan)
61✔
2843

61✔
2844
        select {
61✔
2845
        case err := <-timeoutChan:
2✔
2846
                if err != nil {
2✔
2847
                        return nil, err
×
2848
                }
×
2849
                return nil, ErrConfirmationTimeout
2✔
2850

2851
        case <-f.quit:
25✔
2852
                // The fundingManager is shutting down, and will resume wait on
25✔
2853
                // startup.
25✔
2854
                return nil, ErrFundingManagerShuttingDown
25✔
2855

2856
        case confirmedChannel, ok := <-confChan:
38✔
2857
                if !ok {
38✔
2858
                        return nil, fmt.Errorf("waiting for funding" +
×
2859
                                "confirmation failed")
×
2860
                }
×
2861
                return confirmedChannel, nil
38✔
2862
        }
2863
}
2864

2865
// makeFundingScript re-creates the funding script for the funding transaction
2866
// of the target channel.
2867
func makeFundingScript(channel *channeldb.OpenChannel) ([]byte, error) {
81✔
2868
        localKey := channel.LocalChanCfg.MultiSigKey.PubKey
81✔
2869
        remoteKey := channel.RemoteChanCfg.MultiSigKey.PubKey
81✔
2870

81✔
2871
        if channel.ChanType.IsTaproot() {
90✔
2872
                pkScript, _, err := input.GenTaprootFundingScript(
9✔
2873
                        localKey, remoteKey, int64(channel.Capacity),
9✔
2874
                )
9✔
2875
                if err != nil {
9✔
2876
                        return nil, err
×
2877
                }
×
2878

2879
                return pkScript, nil
9✔
2880
        }
2881

2882
        multiSigScript, err := input.GenMultiSigScript(
76✔
2883
                localKey.SerializeCompressed(),
76✔
2884
                remoteKey.SerializeCompressed(),
76✔
2885
        )
76✔
2886
        if err != nil {
76✔
2887
                return nil, err
×
2888
        }
×
2889

2890
        return input.WitnessScriptHash(multiSigScript)
76✔
2891
}
2892

2893
// waitForFundingConfirmation handles the final stages of the channel funding
2894
// process once the funding transaction has been broadcast. The primary
2895
// function of waitForFundingConfirmation is to wait for blockchain
2896
// confirmation, and then to notify the other systems that must be notified
2897
// when a channel has become active for lightning transactions.
2898
// The wait can be canceled by closing the cancelChan. In case of success,
2899
// a *lnwire.ShortChannelID will be passed to confChan.
2900
//
2901
// NOTE: This MUST be run as a goroutine.
2902
func (f *Manager) waitForFundingConfirmation(
2903
        completeChan *channeldb.OpenChannel, cancelChan <-chan struct{},
2904
        confChan chan<- *confirmedChannel) {
61✔
2905

61✔
2906
        defer f.wg.Done()
61✔
2907
        defer close(confChan)
61✔
2908

61✔
2909
        // Register with the ChainNotifier for a notification once the funding
61✔
2910
        // transaction reaches `numConfs` confirmations.
61✔
2911
        txid := completeChan.FundingOutpoint.Hash
61✔
2912
        fundingScript, err := makeFundingScript(completeChan)
61✔
2913
        if err != nil {
61✔
2914
                log.Errorf("unable to create funding script for "+
×
2915
                        "ChannelPoint(%v): %v", completeChan.FundingOutpoint,
×
2916
                        err)
×
2917
                return
×
2918
        }
×
2919
        numConfs := uint32(completeChan.NumConfsRequired)
61✔
2920

61✔
2921
        // If the underlying channel is a zero-conf channel, we'll set numConfs
61✔
2922
        // to 6, since it will be zero here.
61✔
2923
        if completeChan.IsZeroConf() {
71✔
2924
                numConfs = 6
10✔
2925
        }
10✔
2926

2927
        confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
61✔
2928
                &txid, fundingScript, numConfs,
61✔
2929
                completeChan.BroadcastHeight(),
61✔
2930
        )
61✔
2931
        if err != nil {
61✔
2932
                log.Errorf("Unable to register for confirmation of "+
×
2933
                        "ChannelPoint(%v): %v", completeChan.FundingOutpoint,
×
2934
                        err)
×
2935
                return
×
2936
        }
×
2937

2938
        log.Infof("Waiting for funding tx (%v) to reach %v confirmations",
61✔
2939
                txid, numConfs)
61✔
2940

61✔
2941
        var confDetails *chainntnfs.TxConfirmation
61✔
2942
        var ok bool
61✔
2943

61✔
2944
        // Wait until the specified number of confirmations has been reached,
61✔
2945
        // we get a cancel signal, or the wallet signals a shutdown.
61✔
2946
        select {
61✔
2947
        case confDetails, ok = <-confNtfn.Confirmed:
38✔
2948
                // fallthrough
2949

2950
        case <-cancelChan:
3✔
2951
                log.Warnf("canceled waiting for funding confirmation, "+
3✔
2952
                        "stopping funding flow for ChannelPoint(%v)",
3✔
2953
                        completeChan.FundingOutpoint)
3✔
2954
                return
3✔
2955

2956
        case <-f.quit:
24✔
2957
                log.Warnf("fundingManager shutting down, stopping funding "+
24✔
2958
                        "flow for ChannelPoint(%v)",
24✔
2959
                        completeChan.FundingOutpoint)
24✔
2960
                return
24✔
2961
        }
2962

2963
        if !ok {
38✔
2964
                log.Warnf("ChainNotifier shutting down, cannot complete "+
×
2965
                        "funding flow for ChannelPoint(%v)",
×
2966
                        completeChan.FundingOutpoint)
×
2967
                return
×
2968
        }
×
2969

2970
        fundingPoint := completeChan.FundingOutpoint
38✔
2971
        log.Infof("ChannelPoint(%v) is now active: ChannelID(%v)",
38✔
2972
                fundingPoint, lnwire.NewChanIDFromOutPoint(fundingPoint))
38✔
2973

38✔
2974
        // With the block height and the transaction index known, we can
38✔
2975
        // construct the compact chanID which is used on the network to unique
38✔
2976
        // identify channels.
38✔
2977
        shortChanID := lnwire.ShortChannelID{
38✔
2978
                BlockHeight: confDetails.BlockHeight,
38✔
2979
                TxIndex:     confDetails.TxIndex,
38✔
2980
                TxPosition:  uint16(fundingPoint.Index),
38✔
2981
        }
38✔
2982

38✔
2983
        select {
38✔
2984
        case confChan <- &confirmedChannel{
2985
                shortChanID: shortChanID,
2986
                fundingTx:   confDetails.Tx,
2987
        }:
38✔
2988
        case <-f.quit:
×
2989
                return
×
2990
        }
2991
}
2992

2993
// waitForTimeout will close the timeout channel if MaxWaitNumBlocksFundingConf
2994
// has passed from the broadcast height of the given channel. In case of error,
2995
// the error is sent on timeoutChan. The wait can be canceled by closing the
2996
// cancelChan.
2997
//
2998
// NOTE: timeoutChan MUST be buffered.
2999
// NOTE: This MUST be run as a goroutine.
3000
func (f *Manager) waitForTimeout(completeChan *channeldb.OpenChannel,
3001
        cancelChan <-chan struct{}, timeoutChan chan<- error) {
29✔
3002

29✔
3003
        defer f.wg.Done()
29✔
3004

29✔
3005
        epochClient, err := f.cfg.Notifier.RegisterBlockEpochNtfn(nil)
29✔
3006
        if err != nil {
29✔
3007
                timeoutChan <- fmt.Errorf("unable to register for epoch "+
×
3008
                        "notification: %v", err)
×
3009
                return
×
3010
        }
×
3011

3012
        defer epochClient.Cancel()
29✔
3013

29✔
3014
        // On block maxHeight we will cancel the funding confirmation wait.
29✔
3015
        broadcastHeight := completeChan.BroadcastHeight()
29✔
3016
        maxHeight := broadcastHeight + MaxWaitNumBlocksFundingConf
29✔
3017
        for {
60✔
3018
                select {
31✔
3019
                case epoch, ok := <-epochClient.Epochs:
8✔
3020
                        if !ok {
8✔
3021
                                timeoutChan <- fmt.Errorf("epoch client " +
×
3022
                                        "shutting down")
×
3023
                                return
×
3024
                        }
×
3025

3026
                        // Close the timeout channel and exit if the block is
3027
                        // above the max height.
3028
                        if uint32(epoch.Height) >= maxHeight {
10✔
3029
                                log.Warnf("Waited for %v blocks without "+
2✔
3030
                                        "seeing funding transaction confirmed,"+
2✔
3031
                                        " cancelling.",
2✔
3032
                                        MaxWaitNumBlocksFundingConf)
2✔
3033

2✔
3034
                                // Notify the caller of the timeout.
2✔
3035
                                close(timeoutChan)
2✔
3036
                                return
2✔
3037
                        }
2✔
3038

3039
                        // TODO: If we are the channel initiator implement
3040
                        // a method for recovering the funds from the funding
3041
                        // transaction
3042

3043
                case <-cancelChan:
19✔
3044
                        return
19✔
3045

3046
                case <-f.quit:
12✔
3047
                        // The fundingManager is shutting down, will resume
12✔
3048
                        // waiting for the funding transaction on startup.
12✔
3049
                        return
12✔
3050
                }
3051
        }
3052
}
3053

3054
// makeLabelForTx updates the label for the confirmed funding transaction. If
3055
// we opened the channel, and lnd's wallet published our funding tx (which is
3056
// not the case for some channels) then we update our transaction label with
3057
// our short channel ID, which is known now that our funding transaction has
3058
// confirmed. We do not label transactions we did not publish, because our
3059
// wallet has no knowledge of them.
3060
func (f *Manager) makeLabelForTx(c *channeldb.OpenChannel) {
38✔
3061
        if c.IsInitiator && c.ChanType.HasFundingTx() {
58✔
3062
                shortChanID := c.ShortChanID()
20✔
3063

20✔
3064
                // For zero-conf channels, we'll use the actually-confirmed
20✔
3065
                // short channel id.
20✔
3066
                if c.IsZeroConf() {
26✔
3067
                        shortChanID = c.ZeroConfRealScid()
6✔
3068
                }
6✔
3069

3070
                label := labels.MakeLabel(
20✔
3071
                        labels.LabelTypeChannelOpen, &shortChanID,
20✔
3072
                )
20✔
3073

20✔
3074
                err := f.cfg.UpdateLabel(c.FundingOutpoint.Hash, label)
20✔
3075
                if err != nil {
20✔
3076
                        log.Errorf("unable to update label: %v", err)
×
3077
                }
×
3078
        }
3079
}
3080

3081
// handleFundingConfirmation marks a channel as open in the database, and set
3082
// the channelOpeningState markedOpen. In addition it will report the now
3083
// decided short channel ID to the switch, and close the local discovery signal
3084
// for this channel.
3085
func (f *Manager) handleFundingConfirmation(
3086
        completeChan *channeldb.OpenChannel,
3087
        confChannel *confirmedChannel) error {
34✔
3088

34✔
3089
        fundingPoint := completeChan.FundingOutpoint
34✔
3090
        chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
34✔
3091

34✔
3092
        // TODO(roasbeef): ideally persistent state update for chan above
34✔
3093
        // should be abstracted
34✔
3094

34✔
3095
        // Now that that the channel has been fully confirmed, we'll request
34✔
3096
        // that the wallet fully verify this channel to ensure that it can be
34✔
3097
        // used.
34✔
3098
        err := f.cfg.Wallet.ValidateChannel(completeChan, confChannel.fundingTx)
34✔
3099
        if err != nil {
34✔
3100
                // TODO(roasbeef): delete chan state?
×
3101
                return fmt.Errorf("unable to validate channel: %w", err)
×
3102
        }
×
3103

3104
        // Now that the channel has been validated, we'll persist an alias for
3105
        // this channel if the option-scid-alias feature-bit was negotiated.
3106
        if completeChan.NegotiatedAliasFeature() {
40✔
3107
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
6✔
3108
                if err != nil {
6✔
3109
                        return fmt.Errorf("unable to request alias: %w", err)
×
3110
                }
×
3111

3112
                err = f.cfg.AliasManager.AddLocalAlias(
6✔
3113
                        aliasScid, confChannel.shortChanID, true,
6✔
3114
                )
6✔
3115
                if err != nil {
6✔
3116
                        return fmt.Errorf("unable to request alias: %w", err)
×
3117
                }
×
3118
        }
3119

3120
        // The funding transaction now being confirmed, we add this channel to
3121
        // the fundingManager's internal persistent state machine that we use
3122
        // to track the remaining process of the channel opening. This is
3123
        // useful to resume the opening process in case of restarts. We set the
3124
        // opening state before we mark the channel opened in the database,
3125
        // such that we can receover from one of the db writes failing.
3126
        err = f.saveChannelOpeningState(
34✔
3127
                &fundingPoint, markedOpen, &confChannel.shortChanID,
34✔
3128
        )
34✔
3129
        if err != nil {
34✔
3130
                return fmt.Errorf("error setting channel state to "+
×
3131
                        "markedOpen: %v", err)
×
3132
        }
×
3133

3134
        // Now that the channel has been fully confirmed and we successfully
3135
        // saved the opening state, we'll mark it as open within the database.
3136
        err = completeChan.MarkAsOpen(confChannel.shortChanID)
34✔
3137
        if err != nil {
34✔
3138
                return fmt.Errorf("error setting channel pending flag to "+
×
3139
                        "false:        %v", err)
×
3140
        }
×
3141

3142
        // Update the confirmed funding transaction label.
3143
        f.makeLabelForTx(completeChan)
34✔
3144

34✔
3145
        // Inform the ChannelNotifier that the channel has transitioned from
34✔
3146
        // pending open to open.
34✔
3147
        f.cfg.NotifyOpenChannelEvent(completeChan.FundingOutpoint)
34✔
3148

34✔
3149
        // Close the discoverySignal channel, indicating to a separate
34✔
3150
        // goroutine that the channel now is marked as open in the database
34✔
3151
        // and that it is acceptable to process channel_ready messages
34✔
3152
        // from the peer.
34✔
3153
        if discoverySignal, ok := f.localDiscoverySignals.Load(chanID); ok {
68✔
3154
                close(discoverySignal)
34✔
3155
        }
34✔
3156

3157
        return nil
34✔
3158
}
3159

3160
// sendChannelReady creates and sends the channelReady message.
3161
// This should be called after the funding transaction has been confirmed,
3162
// and the channelState is 'markedOpen'.
3163
func (f *Manager) sendChannelReady(completeChan *channeldb.OpenChannel,
3164
        channel *lnwallet.LightningChannel) error {
39✔
3165

39✔
3166
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
39✔
3167

39✔
3168
        var peerKey [33]byte
39✔
3169
        copy(peerKey[:], completeChan.IdentityPub.SerializeCompressed())
39✔
3170

39✔
3171
        // Next, we'll send over the channel_ready message which marks that we
39✔
3172
        // consider the channel open by presenting the remote party with our
39✔
3173
        // next revocation key. Without the revocation key, the remote party
39✔
3174
        // will be unable to propose state transitions.
39✔
3175
        nextRevocation, err := channel.NextRevocationKey()
39✔
3176
        if err != nil {
39✔
3177
                return fmt.Errorf("unable to create next revocation: %w", err)
×
3178
        }
×
3179
        channelReadyMsg := lnwire.NewChannelReady(chanID, nextRevocation)
39✔
3180

39✔
3181
        // If this is a taproot channel, then we also need to send along our
39✔
3182
        // set of musig2 nonces as well.
39✔
3183
        if completeChan.ChanType.IsTaproot() {
47✔
3184
                log.Infof("ChanID(%v): generating musig2 nonces...",
8✔
3185
                        chanID)
8✔
3186

8✔
3187
                f.nonceMtx.Lock()
8✔
3188
                localNonce, ok := f.pendingMusigNonces[chanID]
8✔
3189
                if !ok {
16✔
3190
                        // If we don't have any nonces generated yet for this
8✔
3191
                        // first state, then we'll generate them now and stow
8✔
3192
                        // them away.  When we receive the funding locked
8✔
3193
                        // message, we'll then pass along this same set of
8✔
3194
                        // nonces.
8✔
3195
                        newNonce, err := channel.GenMusigNonces()
8✔
3196
                        if err != nil {
8✔
3197
                                f.nonceMtx.Unlock()
×
3198
                                return err
×
3199
                        }
×
3200

3201
                        // Now that we've generated the nonce for this channel,
3202
                        // we'll store it in the set of pending nonces.
3203
                        localNonce = newNonce
8✔
3204
                        f.pendingMusigNonces[chanID] = localNonce
8✔
3205
                }
3206
                f.nonceMtx.Unlock()
8✔
3207

8✔
3208
                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce(
8✔
3209
                        localNonce.PubNonce,
8✔
3210
                )
8✔
3211
        }
3212

3213
        // If the channel negotiated the option-scid-alias feature bit, we'll
3214
        // send a TLV segment that includes an alias the peer can use in their
3215
        // invoice hop hints. We'll send the first alias we find for the
3216
        // channel since it does not matter which alias we send. We'll error
3217
        // out in the odd case that no aliases are found.
3218
        if completeChan.NegotiatedAliasFeature() {
49✔
3219
                aliases := f.cfg.AliasManager.GetAliases(
10✔
3220
                        completeChan.ShortChanID(),
10✔
3221
                )
10✔
3222
                if len(aliases) == 0 {
10✔
3223
                        return fmt.Errorf("no aliases found")
×
3224
                }
×
3225

3226
                // We can use a pointer to aliases since GetAliases returns a
3227
                // copy of the alias slice.
3228
                channelReadyMsg.AliasScid = &aliases[0]
10✔
3229
        }
3230

3231
        // If the peer has disconnected before we reach this point, we will need
3232
        // to wait for him to come back online before sending the channelReady
3233
        // message. This is special for channelReady, since failing to send any
3234
        // of the previous messages in the funding flow just cancels the flow.
3235
        // But now the funding transaction is confirmed, the channel is open
3236
        // and we have to make sure the peer gets the channelReady message when
3237
        // it comes back online. This is also crucial during restart of lnd,
3238
        // where we might try to resend the channelReady message before the
3239
        // server has had the time to connect to the peer. We keep trying to
3240
        // send channelReady until we succeed, or the fundingManager is shut
3241
        // down.
3242
        for {
78✔
3243
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
39✔
3244
                if err != nil {
40✔
3245
                        return err
1✔
3246
                }
1✔
3247

3248
                localAlias := peer.LocalFeatures().HasFeature(
38✔
3249
                        lnwire.ScidAliasOptional,
38✔
3250
                )
38✔
3251
                remoteAlias := peer.RemoteFeatures().HasFeature(
38✔
3252
                        lnwire.ScidAliasOptional,
38✔
3253
                )
38✔
3254

38✔
3255
                // We could also refresh the channel state instead of checking
38✔
3256
                // whether the feature was negotiated, but this saves us a
38✔
3257
                // database read.
38✔
3258
                if channelReadyMsg.AliasScid == nil && localAlias &&
38✔
3259
                        remoteAlias {
38✔
3260

×
3261
                        // If an alias was not assigned above and the scid
×
3262
                        // alias feature was negotiated, check if we already
×
3263
                        // have an alias stored in case handleChannelReady was
×
3264
                        // called before this. If an alias exists, use that in
×
3265
                        // channel_ready. Otherwise, request and store an
×
3266
                        // alias and use that.
×
3267
                        aliases := f.cfg.AliasManager.GetAliases(
×
3268
                                completeChan.ShortChannelID,
×
3269
                        )
×
3270
                        if len(aliases) == 0 {
×
3271
                                // No aliases were found.
×
3272
                                alias, err := f.cfg.AliasManager.RequestAlias()
×
3273
                                if err != nil {
×
3274
                                        return err
×
3275
                                }
×
3276

3277
                                err = f.cfg.AliasManager.AddLocalAlias(
×
3278
                                        alias, completeChan.ShortChannelID,
×
3279
                                        false,
×
3280
                                )
×
3281
                                if err != nil {
×
3282
                                        return err
×
3283
                                }
×
3284

3285
                                channelReadyMsg.AliasScid = &alias
×
3286
                        } else {
×
3287
                                channelReadyMsg.AliasScid = &aliases[0]
×
3288
                        }
×
3289
                }
3290

3291
                log.Infof("Peer(%x) is online, sending ChannelReady "+
38✔
3292
                        "for ChannelID(%v)", peerKey, chanID)
38✔
3293

38✔
3294
                if err := peer.SendMessage(true, channelReadyMsg); err == nil {
76✔
3295
                        // Sending succeeded, we can break out and continue the
38✔
3296
                        // funding flow.
38✔
3297
                        break
38✔
3298
                }
3299

3300
                log.Warnf("Unable to send channelReady to peer %x: %v. "+
×
3301
                        "Will retry when online", peerKey, err)
×
3302
        }
3303

3304
        return nil
38✔
3305
}
3306

3307
// receivedChannelReady checks whether or not we've received a ChannelReady
3308
// from the remote peer. If we have, RemoteNextRevocation will be set.
3309
func (f *Manager) receivedChannelReady(node *btcec.PublicKey,
3310
        chanID lnwire.ChannelID) (bool, error) {
64✔
3311

64✔
3312
        // If the funding manager has exited, return an error to stop looping.
64✔
3313
        // Note that the peer may appear as online while the funding manager
64✔
3314
        // has stopped due to the shutdown order in the server.
64✔
3315
        select {
64✔
3316
        case <-f.quit:
×
3317
                return false, ErrFundingManagerShuttingDown
×
3318
        default:
64✔
3319
        }
3320

3321
        // Avoid a tight loop if peer is offline.
3322
        if _, err := f.waitForPeerOnline(node); err != nil {
64✔
3323
                log.Errorf("Wait for peer online failed: %v", err)
×
3324
                return false, err
×
3325
        }
×
3326

3327
        // If we cannot find the channel, then we haven't processed the
3328
        // remote's channelReady message.
3329
        channel, err := f.cfg.FindChannel(node, chanID)
64✔
3330
        if err != nil {
64✔
3331
                log.Errorf("Unable to locate ChannelID(%v) to determine if "+
×
3332
                        "ChannelReady was received", chanID)
×
3333
                return false, err
×
3334
        }
×
3335

3336
        // If we haven't insert the next revocation point, we haven't finished
3337
        // processing the channel ready message.
3338
        if channel.RemoteNextRevocation == nil {
104✔
3339
                return false, nil
40✔
3340
        }
40✔
3341

3342
        // Finally, the barrier signal is removed once we finish
3343
        // `handleChannelReady`. If we can still find the signal, we haven't
3344
        // finished processing it yet.
3345
        _, loaded := f.handleChannelReadyBarriers.Load(chanID)
28✔
3346

28✔
3347
        return !loaded, nil
28✔
3348
}
3349

3350
// extractAnnounceParams extracts the various channel announcement and update
3351
// parameters that will be needed to construct a ChannelAnnouncement and a
3352
// ChannelUpdate.
3353
func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) (
3354
        lnwire.MilliSatoshi, lnwire.MilliSatoshi) {
30✔
3355

30✔
3356
        // We'll obtain the min HTLC value we can forward in our direction, as
30✔
3357
        // we'll use this value within our ChannelUpdate. This constraint is
30✔
3358
        // originally set by the remote node, as it will be the one that will
30✔
3359
        // need to determine the smallest HTLC it deems economically relevant.
30✔
3360
        fwdMinHTLC := c.LocalChanCfg.MinHTLC
30✔
3361

30✔
3362
        // We don't necessarily want to go as low as the remote party allows.
30✔
3363
        // Check it against our default forwarding policy.
30✔
3364
        if fwdMinHTLC < f.cfg.DefaultRoutingPolicy.MinHTLCOut {
34✔
3365
                fwdMinHTLC = f.cfg.DefaultRoutingPolicy.MinHTLCOut
4✔
3366
        }
4✔
3367

3368
        // We'll obtain the max HTLC value we can forward in our direction, as
3369
        // we'll use this value within our ChannelUpdate. This value must be <=
3370
        // channel capacity and <= the maximum in-flight msats set by the peer.
3371
        fwdMaxHTLC := c.LocalChanCfg.MaxPendingAmount
30✔
3372
        capacityMSat := lnwire.NewMSatFromSatoshis(c.Capacity)
30✔
3373
        if fwdMaxHTLC > capacityMSat {
30✔
3374
                fwdMaxHTLC = capacityMSat
×
3375
        }
×
3376

3377
        return fwdMinHTLC, fwdMaxHTLC
30✔
3378
}
3379

3380
// addToGraph sends a ChannelAnnouncement and a ChannelUpdate to the
3381
// gossiper so that the channel is added to the graph builder's internal graph.
3382
// These announcement messages are NOT broadcasted to the greater network,
3383
// only to the channel counter party. The proofs required to announce the
3384
// channel to the greater network will be created and sent in annAfterSixConfs.
3385
// The peerAlias is used for zero-conf channels to give the counter-party a
3386
// ChannelUpdate they understand. ourPolicy may be set for various
3387
// option-scid-alias channels to re-use the same policy.
3388
func (f *Manager) addToGraph(completeChan *channeldb.OpenChannel,
3389
        shortChanID *lnwire.ShortChannelID,
3390
        peerAlias *lnwire.ShortChannelID,
3391
        ourPolicy *models.ChannelEdgePolicy) error {
30✔
3392

30✔
3393
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
30✔
3394

30✔
3395
        fwdMinHTLC, fwdMaxHTLC := f.extractAnnounceParams(completeChan)
30✔
3396

30✔
3397
        ann, err := f.newChanAnnouncement(
30✔
3398
                f.cfg.IDKey, completeChan.IdentityPub,
30✔
3399
                &completeChan.LocalChanCfg.MultiSigKey,
30✔
3400
                completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
30✔
3401
                chanID, fwdMinHTLC, fwdMaxHTLC, ourPolicy,
30✔
3402
                completeChan.ChanType,
30✔
3403
        )
30✔
3404
        if err != nil {
30✔
3405
                return fmt.Errorf("error generating channel "+
×
3406
                        "announcement: %v", err)
×
3407
        }
×
3408

3409
        // Send ChannelAnnouncement and ChannelUpdate to the gossiper to add
3410
        // to the Router's topology.
3411
        errChan := f.cfg.SendAnnouncement(
30✔
3412
                ann.chanAnn, discovery.ChannelCapacity(completeChan.Capacity),
30✔
3413
                discovery.ChannelPoint(completeChan.FundingOutpoint),
30✔
3414
        )
30✔
3415
        select {
30✔
3416
        case err := <-errChan:
30✔
3417
                if err != nil {
30✔
3418
                        if graph.IsError(err, graph.ErrOutdated,
×
3419
                                graph.ErrIgnored) {
×
3420

×
3421
                                log.Debugf("Graph rejected "+
×
3422
                                        "ChannelAnnouncement: %v", err)
×
3423
                        } else {
×
3424
                                return fmt.Errorf("error sending channel "+
×
3425
                                        "announcement: %v", err)
×
3426
                        }
×
3427
                }
3428
        case <-f.quit:
×
3429
                return ErrFundingManagerShuttingDown
×
3430
        }
3431

3432
        errChan = f.cfg.SendAnnouncement(
30✔
3433
                ann.chanUpdateAnn, discovery.RemoteAlias(peerAlias),
30✔
3434
        )
30✔
3435
        select {
30✔
3436
        case err := <-errChan:
30✔
3437
                if err != nil {
30✔
3438
                        if graph.IsError(err, graph.ErrOutdated,
×
3439
                                graph.ErrIgnored) {
×
3440

×
3441
                                log.Debugf("Graph rejected "+
×
3442
                                        "ChannelUpdate: %v", err)
×
3443
                        } else {
×
3444
                                return fmt.Errorf("error sending channel "+
×
3445
                                        "update: %v", err)
×
3446
                        }
×
3447
                }
3448
        case <-f.quit:
×
3449
                return ErrFundingManagerShuttingDown
×
3450
        }
3451

3452
        return nil
30✔
3453
}
3454

3455
// annAfterSixConfs broadcasts the necessary channel announcement messages to
3456
// the network after 6 confs. Should be called after the channelReady message
3457
// is sent and the channel is added to the graph (channelState is
3458
// 'addedToGraph') and the channel is ready to be used. This is the last
3459
// step in the channel opening process, and the opening state will be deleted
3460
// from the database if successful.
3461
func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
3462
        shortChanID *lnwire.ShortChannelID) error {
30✔
3463

30✔
3464
        // If this channel is not meant to be announced to the greater network,
30✔
3465
        // we'll only send our NodeAnnouncement to our counterparty to ensure we
30✔
3466
        // don't leak any of our information.
30✔
3467
        announceChan := completeChan.ChannelFlags&lnwire.FFAnnounceChannel != 0
30✔
3468
        if !announceChan {
42✔
3469
                log.Debugf("Will not announce private channel %v.",
12✔
3470
                        shortChanID.ToUint64())
12✔
3471

12✔
3472
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
12✔
3473
                if err != nil {
12✔
3474
                        return err
×
3475
                }
×
3476

3477
                nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
12✔
3478
                if err != nil {
12✔
3479
                        return fmt.Errorf("unable to retrieve current node "+
×
3480
                                "announcement: %v", err)
×
3481
                }
×
3482

3483
                chanID := lnwire.NewChanIDFromOutPoint(
12✔
3484
                        completeChan.FundingOutpoint,
12✔
3485
                )
12✔
3486
                pubKey := peer.PubKey()
12✔
3487
                log.Debugf("Sending our NodeAnnouncement for "+
12✔
3488
                        "ChannelID(%v) to %x", chanID, pubKey)
12✔
3489

12✔
3490
                // TODO(halseth): make reliable. If the peer is not online this
12✔
3491
                // will fail, and the opening process will stop. Should instead
12✔
3492
                // block here, waiting for the peer to come online.
12✔
3493
                if err := peer.SendMessage(true, &nodeAnn); err != nil {
12✔
3494
                        return fmt.Errorf("unable to send node announcement "+
×
3495
                                "to peer %x: %v", pubKey, err)
×
3496
                }
×
3497
        } else {
22✔
3498
                // Otherwise, we'll wait until the funding transaction has
22✔
3499
                // reached 6 confirmations before announcing it.
22✔
3500
                numConfs := uint32(completeChan.NumConfsRequired)
22✔
3501
                if numConfs < 6 {
44✔
3502
                        numConfs = 6
22✔
3503
                }
22✔
3504
                txid := completeChan.FundingOutpoint.Hash
22✔
3505
                log.Debugf("Will announce channel %v after ChannelPoint"+
22✔
3506
                        "(%v) has gotten %d confirmations",
22✔
3507
                        shortChanID.ToUint64(), completeChan.FundingOutpoint,
22✔
3508
                        numConfs)
22✔
3509

22✔
3510
                fundingScript, err := makeFundingScript(completeChan)
22✔
3511
                if err != nil {
22✔
3512
                        return fmt.Errorf("unable to create funding script "+
×
3513
                                "for ChannelPoint(%v): %v",
×
3514
                                completeChan.FundingOutpoint, err)
×
3515
                }
×
3516

3517
                // Register with the ChainNotifier for a notification once the
3518
                // funding transaction reaches at least 6 confirmations.
3519
                confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
22✔
3520
                        &txid, fundingScript, numConfs,
22✔
3521
                        completeChan.BroadcastHeight(),
22✔
3522
                )
22✔
3523
                if err != nil {
22✔
3524
                        return fmt.Errorf("unable to register for "+
×
3525
                                "confirmation of ChannelPoint(%v): %v",
×
3526
                                completeChan.FundingOutpoint, err)
×
3527
                }
×
3528

3529
                // Wait until 6 confirmations has been reached or the wallet
3530
                // signals a shutdown.
3531
                select {
22✔
3532
                case _, ok := <-confNtfn.Confirmed:
20✔
3533
                        if !ok {
20✔
3534
                                return fmt.Errorf("ChainNotifier shutting "+
×
3535
                                        "down, cannot complete funding flow "+
×
3536
                                        "for ChannelPoint(%v)",
×
3537
                                        completeChan.FundingOutpoint)
×
3538
                        }
×
3539
                        // Fallthrough.
3540

3541
                case <-f.quit:
6✔
3542
                        return fmt.Errorf("%v, stopping funding flow for "+
6✔
3543
                                "ChannelPoint(%v)",
6✔
3544
                                ErrFundingManagerShuttingDown,
6✔
3545
                                completeChan.FundingOutpoint)
6✔
3546
                }
3547

3548
                fundingPoint := completeChan.FundingOutpoint
20✔
3549
                chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
20✔
3550

20✔
3551
                log.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
20✔
3552
                        &fundingPoint, shortChanID)
20✔
3553

20✔
3554
                // If this is a non-zero-conf option-scid-alias channel, we'll
20✔
3555
                // delete the mappings the gossiper uses so that ChannelUpdates
20✔
3556
                // with aliases won't be accepted. This is done elsewhere for
20✔
3557
                // zero-conf channels.
20✔
3558
                isScidFeature := completeChan.NegotiatedAliasFeature()
20✔
3559
                isZeroConf := completeChan.IsZeroConf()
20✔
3560
                if isScidFeature && !isZeroConf {
24✔
3561
                        baseScid := completeChan.ShortChanID()
4✔
3562
                        err := f.cfg.AliasManager.DeleteSixConfs(baseScid)
4✔
3563
                        if err != nil {
4✔
3564
                                return fmt.Errorf("failed deleting six confs "+
×
3565
                                        "maps: %v", err)
×
3566
                        }
×
3567

3568
                        // We'll delete the edge and add it again via
3569
                        // addToGraph. This is because the peer may have
3570
                        // sent us a ChannelUpdate with an alias and we don't
3571
                        // want to relay this.
3572
                        ourPolicy, err := f.cfg.DeleteAliasEdge(baseScid)
4✔
3573
                        if err != nil {
4✔
3574
                                return fmt.Errorf("failed deleting real edge "+
×
3575
                                        "for alias channel from graph: %v",
×
3576
                                        err)
×
3577
                        }
×
3578

3579
                        err = f.addToGraph(
4✔
3580
                                completeChan, &baseScid, nil, ourPolicy,
4✔
3581
                        )
4✔
3582
                        if err != nil {
4✔
3583
                                return fmt.Errorf("failed to re-add to "+
×
3584
                                        "graph: %v", err)
×
3585
                        }
×
3586
                }
3587

3588
                // Create and broadcast the proofs required to make this channel
3589
                // public and usable for other nodes for routing.
3590
                err = f.announceChannel(
20✔
3591
                        f.cfg.IDKey, completeChan.IdentityPub,
20✔
3592
                        &completeChan.LocalChanCfg.MultiSigKey,
20✔
3593
                        completeChan.RemoteChanCfg.MultiSigKey.PubKey,
20✔
3594
                        *shortChanID, chanID, completeChan.ChanType,
20✔
3595
                )
20✔
3596
                if err != nil {
24✔
3597
                        return fmt.Errorf("channel announcement failed: %w",
4✔
3598
                                err)
4✔
3599
                }
4✔
3600

3601
                log.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
20✔
3602
                        "sent to gossiper", &fundingPoint, shortChanID)
20✔
3603
        }
3604

3605
        return nil
28✔
3606
}
3607

3608
// waitForZeroConfChannel is called when the state is addedToGraph with
3609
// a zero-conf channel. This will wait for the real confirmation, add the
3610
// confirmed SCID to the graph, and then announce after six confs.
3611
func (f *Manager) waitForZeroConfChannel(c *channeldb.OpenChannel) error {
10✔
3612
        // First we'll check whether the channel is confirmed on-chain. If it
10✔
3613
        // is already confirmed, the chainntnfs subsystem will return with the
10✔
3614
        // confirmed tx. Otherwise, we'll wait here until confirmation occurs.
10✔
3615
        confChan, err := f.waitForFundingWithTimeout(c)
10✔
3616
        if err != nil {
16✔
3617
                return fmt.Errorf("error waiting for zero-conf funding "+
6✔
3618
                        "confirmation for ChannelPoint(%v): %v",
6✔
3619
                        c.FundingOutpoint, err)
6✔
3620
        }
6✔
3621

3622
        // We'll need to refresh the channel state so that things are properly
3623
        // populated when validating the channel state. Otherwise, a panic may
3624
        // occur due to inconsistency in the OpenChannel struct.
3625
        err = c.Refresh()
8✔
3626
        if err != nil {
12✔
3627
                return fmt.Errorf("unable to refresh channel state: %w", err)
4✔
3628
        }
4✔
3629

3630
        // Now that we have the confirmed transaction and the proper SCID,
3631
        // we'll call ValidateChannel to ensure the confirmed tx is properly
3632
        // formatted.
3633
        err = f.cfg.Wallet.ValidateChannel(c, confChan.fundingTx)
8✔
3634
        if err != nil {
8✔
3635
                return fmt.Errorf("unable to validate zero-conf channel: "+
×
3636
                        "%v", err)
×
3637
        }
×
3638

3639
        // Once we know the confirmed ShortChannelID, we'll need to save it to
3640
        // the database and refresh the OpenChannel struct with it.
3641
        err = c.MarkRealScid(confChan.shortChanID)
8✔
3642
        if err != nil {
8✔
3643
                return fmt.Errorf("unable to set confirmed SCID for zero "+
×
3644
                        "channel: %v", err)
×
3645
        }
×
3646

3647
        // Six confirmations have been reached. If this channel is public,
3648
        // we'll delete some of the alias mappings the gossiper uses.
3649
        isPublic := c.ChannelFlags&lnwire.FFAnnounceChannel != 0
8✔
3650
        if isPublic {
14✔
3651
                err = f.cfg.AliasManager.DeleteSixConfs(c.ShortChannelID)
6✔
3652
                if err != nil {
6✔
3653
                        return fmt.Errorf("unable to delete base alias after "+
×
3654
                                "six confirmations: %v", err)
×
3655
                }
×
3656

3657
                // TODO: Make this atomic!
3658
                ourPolicy, err := f.cfg.DeleteAliasEdge(c.ShortChanID())
6✔
3659
                if err != nil {
6✔
3660
                        return fmt.Errorf("unable to delete alias edge from "+
×
3661
                                "graph: %v", err)
×
3662
                }
×
3663

3664
                // We'll need to update the graph with the new ShortChannelID
3665
                // via an addToGraph call. We don't pass in the peer's
3666
                // alias since we'll be using the confirmed SCID from now on
3667
                // regardless if it's public or not.
3668
                err = f.addToGraph(
6✔
3669
                        c, &confChan.shortChanID, nil, ourPolicy,
6✔
3670
                )
6✔
3671
                if err != nil {
6✔
3672
                        return fmt.Errorf("failed adding confirmed zero-conf "+
×
3673
                                "SCID to graph: %v", err)
×
3674
                }
×
3675
        }
3676

3677
        // Since we have now marked down the confirmed SCID, we'll also need to
3678
        // tell the Switch to refresh the relevant ChannelLink so that forwards
3679
        // under the confirmed SCID are possible if this is a public channel.
3680
        err = f.cfg.ReportShortChanID(c.FundingOutpoint)
8✔
3681
        if err != nil {
8✔
3682
                // This should only fail if the link is not found in the
×
3683
                // Switch's linkIndex map. If this is the case, then the peer
×
3684
                // has gone offline and the next time the link is loaded, it
×
3685
                // will have a refreshed state. Just log an error here.
×
3686
                log.Errorf("unable to report scid for zero-conf channel "+
×
3687
                        "channel: %v", err)
×
3688
        }
×
3689

3690
        // Update the confirmed transaction's label.
3691
        f.makeLabelForTx(c)
8✔
3692

8✔
3693
        return nil
8✔
3694
}
3695

3696
// genFirstStateMusigNonce generates a nonces for the "first" local state. This
3697
// is the verification nonce for the state created for us after the initial
3698
// commitment transaction signed as part of the funding flow.
3699
func genFirstStateMusigNonce(channel *channeldb.OpenChannel,
3700
) (*musig2.Nonces, error) {
8✔
3701

8✔
3702
        musig2ShaChain, err := channeldb.DeriveMusig2Shachain(
8✔
3703
                channel.RevocationProducer,
8✔
3704
        )
8✔
3705
        if err != nil {
8✔
3706
                return nil, fmt.Errorf("unable to generate musig channel "+
×
3707
                        "nonces: %v", err)
×
3708
        }
×
3709

3710
        // We use the _next_ commitment height here as we need to generate the
3711
        // nonce for the next state the remote party will sign for us.
3712
        verNonce, err := channeldb.NewMusigVerificationNonce(
8✔
3713
                channel.LocalChanCfg.MultiSigKey.PubKey,
8✔
3714
                channel.LocalCommitment.CommitHeight+1,
8✔
3715
                musig2ShaChain,
8✔
3716
        )
8✔
3717
        if err != nil {
8✔
3718
                return nil, fmt.Errorf("unable to generate musig channel "+
×
3719
                        "nonces: %v", err)
×
3720
        }
×
3721

3722
        return verNonce, nil
8✔
3723
}
3724

3725
// handleChannelReady finalizes the channel funding process and enables the
3726
// channel to enter normal operating mode.
3727
func (f *Manager) handleChannelReady(peer lnpeer.Peer, //nolint:funlen
3728
        msg *lnwire.ChannelReady) {
32✔
3729

32✔
3730
        defer f.wg.Done()
32✔
3731

32✔
3732
        // If we are in development mode, we'll wait for specified duration
32✔
3733
        // before processing the channel ready message.
32✔
3734
        if f.cfg.Dev != nil {
36✔
3735
                duration := f.cfg.Dev.ProcessChannelReadyWait
4✔
3736
                log.Warnf("Channel(%v): sleeping %v before processing "+
4✔
3737
                        "channel_ready", msg.ChanID, duration)
4✔
3738

4✔
3739
                select {
4✔
3740
                case <-time.After(duration):
4✔
3741
                        log.Warnf("Channel(%v): slept %v before processing "+
4✔
3742
                                "channel_ready", msg.ChanID, duration)
4✔
3743
                case <-f.quit:
×
3744
                        log.Warnf("Channel(%v): quit sleeping", msg.ChanID)
×
3745
                        return
×
3746
                }
3747
        }
3748

3749
        log.Debugf("Received ChannelReady for ChannelID(%v) from "+
32✔
3750
                "peer %x", msg.ChanID,
32✔
3751
                peer.IdentityKey().SerializeCompressed())
32✔
3752

32✔
3753
        // We now load or create a new channel barrier for this channel.
32✔
3754
        _, loaded := f.handleChannelReadyBarriers.LoadOrStore(
32✔
3755
                msg.ChanID, struct{}{},
32✔
3756
        )
32✔
3757

32✔
3758
        // If we are currently in the process of handling a channel_ready
32✔
3759
        // message for this channel, ignore.
32✔
3760
        if loaded {
37✔
3761
                log.Infof("Already handling channelReady for "+
5✔
3762
                        "ChannelID(%v), ignoring.", msg.ChanID)
5✔
3763
                return
5✔
3764
        }
5✔
3765

3766
        // If not already handling channelReady for this channel, then the
3767
        // `LoadOrStore` has set up a barrier, and it will be removed once this
3768
        // function exits.
3769
        defer f.handleChannelReadyBarriers.Delete(msg.ChanID)
31✔
3770

31✔
3771
        localDiscoverySignal, ok := f.localDiscoverySignals.Load(msg.ChanID)
31✔
3772
        if ok {
60✔
3773
                // Before we proceed with processing the channel_ready
29✔
3774
                // message, we'll wait for the local waitForFundingConfirmation
29✔
3775
                // goroutine to signal that it has the necessary state in
29✔
3776
                // place. Otherwise, we may be missing critical information
29✔
3777
                // required to handle forwarded HTLC's.
29✔
3778
                select {
29✔
3779
                case <-localDiscoverySignal:
29✔
3780
                        // Fallthrough
3781
                case <-f.quit:
×
3782
                        return
×
3783
                }
3784

3785
                // With the signal received, we can now safely delete the entry
3786
                // from the map.
3787
                f.localDiscoverySignals.Delete(msg.ChanID)
29✔
3788
        }
3789

3790
        // First, we'll attempt to locate the channel whose funding workflow is
3791
        // being finalized by this message. We go to the database rather than
3792
        // our reservation map as we may have restarted, mid funding flow. Also
3793
        // provide the node's public key to make the search faster.
3794
        chanID := msg.ChanID
31✔
3795
        channel, err := f.cfg.FindChannel(peer.IdentityKey(), chanID)
31✔
3796
        if err != nil {
31✔
3797
                log.Errorf("Unable to locate ChannelID(%v), cannot complete "+
×
3798
                        "funding", chanID)
×
3799
                return
×
3800
        }
×
3801

3802
        // If this is a taproot channel, then we can generate the set of nonces
3803
        // the remote party needs to send the next remote commitment here.
3804
        var firstVerNonce *musig2.Nonces
31✔
3805
        if channel.ChanType.IsTaproot() {
39✔
3806
                firstVerNonce, err = genFirstStateMusigNonce(channel)
8✔
3807
                if err != nil {
8✔
3808
                        log.Error(err)
×
3809
                        return
×
3810
                }
×
3811
        }
3812

3813
        // We'll need to store the received TLV alias if the option_scid_alias
3814
        // feature was negotiated. This will be used to provide route hints
3815
        // during invoice creation. In the zero-conf case, it is also used to
3816
        // provide a ChannelUpdate to the remote peer. This is done before the
3817
        // call to InsertNextRevocation in case the call to PutPeerAlias fails.
3818
        // If it were to fail on the first call to handleChannelReady, we
3819
        // wouldn't want the channel to be usable yet.
3820
        if channel.NegotiatedAliasFeature() {
41✔
3821
                // If the AliasScid field is nil, we must fail out. We will
10✔
3822
                // most likely not be able to route through the peer.
10✔
3823
                if msg.AliasScid == nil {
10✔
3824
                        log.Debugf("Consider closing ChannelID(%v), peer "+
×
3825
                                "does not implement the option-scid-alias "+
×
3826
                                "feature properly", chanID)
×
3827
                        return
×
3828
                }
×
3829

3830
                // We'll store the AliasScid so that invoice creation can use
3831
                // it.
3832
                err = f.cfg.AliasManager.PutPeerAlias(chanID, *msg.AliasScid)
10✔
3833
                if err != nil {
10✔
3834
                        log.Errorf("unable to store peer's alias: %v", err)
×
3835
                        return
×
3836
                }
×
3837

3838
                // If we do not have an alias stored, we'll create one now.
3839
                // This is only used in the upgrade case where a user toggles
3840
                // the option-scid-alias feature-bit to on. We'll also send the
3841
                // channel_ready message here in case the link is created
3842
                // before sendChannelReady is called.
3843
                aliases := f.cfg.AliasManager.GetAliases(
10✔
3844
                        channel.ShortChannelID,
10✔
3845
                )
10✔
3846
                if len(aliases) == 0 {
10✔
3847
                        // No aliases were found so we'll request and store an
×
3848
                        // alias and use it in the channel_ready message.
×
3849
                        alias, err := f.cfg.AliasManager.RequestAlias()
×
3850
                        if err != nil {
×
3851
                                log.Errorf("unable to request alias: %v", err)
×
3852
                                return
×
3853
                        }
×
3854

3855
                        err = f.cfg.AliasManager.AddLocalAlias(
×
3856
                                alias, channel.ShortChannelID, false,
×
3857
                        )
×
3858
                        if err != nil {
×
3859
                                log.Errorf("unable to add local alias: %v",
×
3860
                                        err)
×
3861
                                return
×
3862
                        }
×
3863

3864
                        secondPoint, err := channel.SecondCommitmentPoint()
×
3865
                        if err != nil {
×
3866
                                log.Errorf("unable to fetch second "+
×
3867
                                        "commitment point: %v", err)
×
3868
                                return
×
3869
                        }
×
3870

3871
                        channelReadyMsg := lnwire.NewChannelReady(
×
3872
                                chanID, secondPoint,
×
3873
                        )
×
3874
                        channelReadyMsg.AliasScid = &alias
×
3875

×
3876
                        if firstVerNonce != nil {
×
3877
                                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce( //nolint:lll
×
3878
                                        firstVerNonce.PubNonce,
×
3879
                                )
×
3880
                        }
×
3881

3882
                        err = peer.SendMessage(true, channelReadyMsg)
×
3883
                        if err != nil {
×
3884
                                log.Errorf("unable to send channel_ready: %v",
×
3885
                                        err)
×
3886
                                return
×
3887
                        }
×
3888
                }
3889
        }
3890

3891
        // If the RemoteNextRevocation is non-nil, it means that we have
3892
        // already processed channelReady for this channel, so ignore. This
3893
        // check is after the alias logic so we store the peer's most recent
3894
        // alias. The spec requires us to validate that subsequent
3895
        // channel_ready messages use the same per commitment point (the
3896
        // second), but it is not actually necessary since we'll just end up
3897
        // ignoring it. We are, however, required to *send* the same per
3898
        // commitment point, since another pedantic implementation might
3899
        // verify it.
3900
        if channel.RemoteNextRevocation != nil {
36✔
3901
                log.Infof("Received duplicate channelReady for "+
5✔
3902
                        "ChannelID(%v), ignoring.", chanID)
5✔
3903
                return
5✔
3904
        }
5✔
3905

3906
        // If this is a taproot channel, then we'll need to map the received
3907
        // nonces to a nonce pair, and also fetch our pending nonces, which are
3908
        // required in order to make the channel whole.
3909
        var chanOpts []lnwallet.ChannelOpt
30✔
3910
        if channel.ChanType.IsTaproot() {
38✔
3911
                f.nonceMtx.Lock()
8✔
3912
                localNonce, ok := f.pendingMusigNonces[chanID]
8✔
3913
                if !ok {
12✔
3914
                        // If there's no pending nonce for this channel ID,
4✔
3915
                        // we'll use the one generated above.
4✔
3916
                        localNonce = firstVerNonce
4✔
3917
                        f.pendingMusigNonces[chanID] = firstVerNonce
4✔
3918
                }
4✔
3919
                f.nonceMtx.Unlock()
8✔
3920

8✔
3921
                log.Infof("ChanID(%v): applying local+remote musig2 nonces",
8✔
3922
                        chanID)
8✔
3923

8✔
3924
                remoteNonce, err := msg.NextLocalNonce.UnwrapOrErrV(
8✔
3925
                        errNoLocalNonce,
8✔
3926
                )
8✔
3927
                if err != nil {
8✔
3928
                        cid := newChanIdentifier(msg.ChanID)
×
3929
                        f.sendWarning(peer, cid, err)
×
3930

×
3931
                        return
×
3932
                }
×
3933

3934
                chanOpts = append(
8✔
3935
                        chanOpts,
8✔
3936
                        lnwallet.WithLocalMusigNonces(localNonce),
8✔
3937
                        lnwallet.WithRemoteMusigNonces(&musig2.Nonces{
8✔
3938
                                PubNonce: remoteNonce,
8✔
3939
                        }),
8✔
3940
                )
8✔
3941
        }
3942

3943
        // The channel_ready message contains the next commitment point we'll
3944
        // need to create the next commitment state for the remote party. So
3945
        // we'll insert that into the channel now before passing it along to
3946
        // other sub-systems.
3947
        err = channel.InsertNextRevocation(msg.NextPerCommitmentPoint)
30✔
3948
        if err != nil {
30✔
3949
                log.Errorf("unable to insert next commitment point: %v", err)
×
3950
                return
×
3951
        }
×
3952

3953
        // Before we can add the channel to the peer, we'll need to ensure that
3954
        // we have an initial forwarding policy set.
3955
        if err := f.ensureInitialForwardingPolicy(chanID, channel); err != nil {
30✔
3956
                log.Errorf("Unable to ensure initial forwarding policy: %v",
×
3957
                        err)
×
3958
        }
×
3959

3960
        err = peer.AddNewChannel(&lnpeer.NewChannel{
30✔
3961
                OpenChannel: channel,
30✔
3962
                ChanOpts:    chanOpts,
30✔
3963
        }, f.quit)
30✔
3964
        if err != nil {
30✔
3965
                log.Errorf("Unable to add new channel %v with peer %x: %v",
×
3966
                        channel.FundingOutpoint,
×
3967
                        peer.IdentityKey().SerializeCompressed(), err,
×
3968
                )
×
3969
        }
×
3970
}
3971

3972
// handleChannelReadyReceived is called once the remote's channelReady message
3973
// is received and processed. At this stage, we must have sent out our
3974
// channelReady message, once the remote's channelReady is processed, the
3975
// channel is now active, thus we change its state to `addedToGraph` to
3976
// let the channel start handling routing.
3977
func (f *Manager) handleChannelReadyReceived(channel *channeldb.OpenChannel,
3978
        scid *lnwire.ShortChannelID, pendingChanID [32]byte,
3979
        updateChan chan<- *lnrpc.OpenStatusUpdate) error {
28✔
3980

28✔
3981
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
28✔
3982

28✔
3983
        // Since we've sent+received funding locked at this point, we
28✔
3984
        // can clean up the pending musig2 nonce state.
28✔
3985
        f.nonceMtx.Lock()
28✔
3986
        delete(f.pendingMusigNonces, chanID)
28✔
3987
        f.nonceMtx.Unlock()
28✔
3988

28✔
3989
        var peerAlias *lnwire.ShortChannelID
28✔
3990
        if channel.IsZeroConf() {
36✔
3991
                // We'll need to wait until channel_ready has been received and
8✔
3992
                // the peer lets us know the alias they want to use for the
8✔
3993
                // channel. With this information, we can then construct a
8✔
3994
                // ChannelUpdate for them.  If an alias does not yet exist,
8✔
3995
                // we'll just return, letting the next iteration of the loop
8✔
3996
                // check again.
8✔
3997
                var defaultAlias lnwire.ShortChannelID
8✔
3998
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
8✔
3999
                foundAlias, _ := f.cfg.AliasManager.GetPeerAlias(chanID)
8✔
4000
                if foundAlias == defaultAlias {
8✔
4001
                        return nil
×
4002
                }
×
4003

4004
                peerAlias = &foundAlias
8✔
4005
        }
4006

4007
        err := f.addToGraph(channel, scid, peerAlias, nil)
28✔
4008
        if err != nil {
28✔
4009
                return fmt.Errorf("failed adding to graph: %w", err)
×
4010
        }
×
4011

4012
        // As the channel is now added to the ChannelRouter's topology, the
4013
        // channel is moved to the next state of the state machine. It will be
4014
        // moved to the last state (actually deleted from the database) after
4015
        // the channel is finally announced.
4016
        err = f.saveChannelOpeningState(
28✔
4017
                &channel.FundingOutpoint, addedToGraph, scid,
28✔
4018
        )
28✔
4019
        if err != nil {
28✔
4020
                return fmt.Errorf("error setting channel state to"+
×
4021
                        " addedToGraph: %w", err)
×
4022
        }
×
4023

4024
        log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
28✔
4025
                "added to graph", chanID, scid)
28✔
4026

28✔
4027
        // Give the caller a final update notifying them that the channel is
28✔
4028
        fundingPoint := channel.FundingOutpoint
28✔
4029
        cp := &lnrpc.ChannelPoint{
28✔
4030
                FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
28✔
4031
                        FundingTxidBytes: fundingPoint.Hash[:],
28✔
4032
                },
28✔
4033
                OutputIndex: fundingPoint.Index,
28✔
4034
        }
28✔
4035

28✔
4036
        if updateChan != nil {
42✔
4037
                upd := &lnrpc.OpenStatusUpdate{
14✔
4038
                        Update: &lnrpc.OpenStatusUpdate_ChanOpen{
14✔
4039
                                ChanOpen: &lnrpc.ChannelOpenUpdate{
14✔
4040
                                        ChannelPoint: cp,
14✔
4041
                                },
14✔
4042
                        },
14✔
4043
                        PendingChanId: pendingChanID[:],
14✔
4044
                }
14✔
4045

14✔
4046
                select {
14✔
4047
                case updateChan <- upd:
14✔
4048
                case <-f.quit:
×
4049
                        return ErrFundingManagerShuttingDown
×
4050
                }
4051
        }
4052

4053
        return nil
28✔
4054
}
4055

4056
// ensureInitialForwardingPolicy ensures that we have an initial forwarding
4057
// policy set for the given channel. If we don't, we'll fall back to the default
4058
// values.
4059
func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID,
4060
        channel *channeldb.OpenChannel) error {
30✔
4061

30✔
4062
        // Before we can add the channel to the peer, we'll need to ensure that
30✔
4063
        // we have an initial forwarding policy set. This should always be the
30✔
4064
        // case except for a channel that was created with lnd <= 0.15.5 and
30✔
4065
        // is still pending while updating to this version.
30✔
4066
        var needDBUpdate bool
30✔
4067
        forwardingPolicy, err := f.getInitialForwardingPolicy(chanID)
30✔
4068
        if err != nil {
30✔
4069
                log.Errorf("Unable to fetch initial forwarding policy, "+
×
4070
                        "falling back to default values: %v", err)
×
4071

×
4072
                forwardingPolicy = f.defaultForwardingPolicy(
×
4073
                        channel.LocalChanCfg.ChannelConstraints,
×
4074
                )
×
4075
                needDBUpdate = true
×
4076
        }
×
4077

4078
        // We only started storing the actual values for MinHTLCOut and MaxHTLC
4079
        // after 0.16.x, so if a channel was opened with such a version and is
4080
        // still pending while updating to this version, we'll need to set the
4081
        // values to the default values.
4082
        if forwardingPolicy.MinHTLCOut == 0 {
47✔
4083
                forwardingPolicy.MinHTLCOut = channel.LocalChanCfg.MinHTLC
17✔
4084
                needDBUpdate = true
17✔
4085
        }
17✔
4086
        if forwardingPolicy.MaxHTLC == 0 {
47✔
4087
                forwardingPolicy.MaxHTLC = channel.LocalChanCfg.MaxPendingAmount
17✔
4088
                needDBUpdate = true
17✔
4089
        }
17✔
4090

4091
        // And finally, if we found that the values currently stored aren't
4092
        // sufficient for the link, we'll update the database.
4093
        if needDBUpdate {
47✔
4094
                err := f.saveInitialForwardingPolicy(chanID, forwardingPolicy)
17✔
4095
                if err != nil {
17✔
4096
                        return fmt.Errorf("unable to update initial "+
×
4097
                                "forwarding policy: %v", err)
×
4098
                }
×
4099
        }
4100

4101
        return nil
30✔
4102
}
4103

4104
// chanAnnouncement encapsulates the two authenticated announcements that we
4105
// send out to the network after a new channel has been created locally.
4106
type chanAnnouncement struct {
4107
        chanAnn       *lnwire.ChannelAnnouncement
4108
        chanUpdateAnn *lnwire.ChannelUpdate
4109
        chanProof     *lnwire.AnnounceSignatures
4110
}
4111

4112
// newChanAnnouncement creates the authenticated channel announcement messages
4113
// required to broadcast a newly created channel to the network. The
4114
// announcement is two part: the first part authenticates the existence of the
4115
// channel and contains four signatures binding the funding pub keys and
4116
// identity pub keys of both parties to the channel, and the second segment is
4117
// authenticated only by us and contains our directional routing policy for the
4118
// channel. ourPolicy may be set in order to re-use an existing, non-default
4119
// policy.
4120
func (f *Manager) newChanAnnouncement(localPubKey,
4121
        remotePubKey *btcec.PublicKey, localFundingKey *keychain.KeyDescriptor,
4122
        remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
4123
        chanID lnwire.ChannelID, fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi,
4124
        ourPolicy *models.ChannelEdgePolicy,
4125
        chanType channeldb.ChannelType) (*chanAnnouncement, error) {
46✔
4126

46✔
4127
        chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
46✔
4128

46✔
4129
        // The unconditional section of the announcement is the ShortChannelID
46✔
4130
        // itself which compactly encodes the location of the funding output
46✔
4131
        // within the blockchain.
46✔
4132
        chanAnn := &lnwire.ChannelAnnouncement{
46✔
4133
                ShortChannelID: shortChanID,
46✔
4134
                Features:       lnwire.NewRawFeatureVector(),
46✔
4135
                ChainHash:      chainHash,
46✔
4136
        }
46✔
4137

46✔
4138
        // If this is a taproot channel, then we'll set a special bit in the
46✔
4139
        // feature vector to indicate to the routing layer that this needs a
46✔
4140
        // slightly different type of validation.
46✔
4141
        //
46✔
4142
        // TODO(roasbeef): temp, remove after gossip 1.5
46✔
4143
        if chanType.IsTaproot() {
54✔
4144
                log.Debugf("Applying taproot feature bit to "+
8✔
4145
                        "ChannelAnnouncement for %v", chanID)
8✔
4146

8✔
4147
                chanAnn.Features.Set(
8✔
4148
                        lnwire.SimpleTaprootChannelsRequiredStaging,
8✔
4149
                )
8✔
4150
        }
8✔
4151

4152
        // The chanFlags field indicates which directed edge of the channel is
4153
        // being updated within the ChannelUpdateAnnouncement announcement
4154
        // below. A value of zero means it's the edge of the "first" node and 1
4155
        // being the other node.
4156
        var chanFlags lnwire.ChanUpdateChanFlags
46✔
4157

46✔
4158
        // The lexicographical ordering of the two identity public keys of the
46✔
4159
        // nodes indicates which of the nodes is "first". If our serialized
46✔
4160
        // identity key is lower than theirs then we're the "first" node and
46✔
4161
        // second otherwise.
46✔
4162
        selfBytes := localPubKey.SerializeCompressed()
46✔
4163
        remoteBytes := remotePubKey.SerializeCompressed()
46✔
4164
        if bytes.Compare(selfBytes, remoteBytes) == -1 {
71✔
4165
                copy(chanAnn.NodeID1[:], localPubKey.SerializeCompressed())
25✔
4166
                copy(chanAnn.NodeID2[:], remotePubKey.SerializeCompressed())
25✔
4167
                copy(
25✔
4168
                        chanAnn.BitcoinKey1[:],
25✔
4169
                        localFundingKey.PubKey.SerializeCompressed(),
25✔
4170
                )
25✔
4171
                copy(
25✔
4172
                        chanAnn.BitcoinKey2[:],
25✔
4173
                        remoteFundingKey.SerializeCompressed(),
25✔
4174
                )
25✔
4175

25✔
4176
                // If we're the first node then update the chanFlags to
25✔
4177
                // indicate the "direction" of the update.
25✔
4178
                chanFlags = 0
25✔
4179
        } else {
50✔
4180
                copy(chanAnn.NodeID1[:], remotePubKey.SerializeCompressed())
25✔
4181
                copy(chanAnn.NodeID2[:], localPubKey.SerializeCompressed())
25✔
4182
                copy(
25✔
4183
                        chanAnn.BitcoinKey1[:],
25✔
4184
                        remoteFundingKey.SerializeCompressed(),
25✔
4185
                )
25✔
4186
                copy(
25✔
4187
                        chanAnn.BitcoinKey2[:],
25✔
4188
                        localFundingKey.PubKey.SerializeCompressed(),
25✔
4189
                )
25✔
4190

25✔
4191
                // If we're the second node then update the chanFlags to
25✔
4192
                // indicate the "direction" of the update.
25✔
4193
                chanFlags = 1
25✔
4194
        }
25✔
4195

4196
        // Our channel update message flags will signal that we support the
4197
        // max_htlc field.
4198
        msgFlags := lnwire.ChanUpdateRequiredMaxHtlc
46✔
4199

46✔
4200
        // We announce the channel with the default values. Some of
46✔
4201
        // these values can later be changed by crafting a new ChannelUpdate.
46✔
4202
        chanUpdateAnn := &lnwire.ChannelUpdate{
46✔
4203
                ShortChannelID: shortChanID,
46✔
4204
                ChainHash:      chainHash,
46✔
4205
                Timestamp:      uint32(time.Now().Unix()),
46✔
4206
                MessageFlags:   msgFlags,
46✔
4207
                ChannelFlags:   chanFlags,
46✔
4208
                TimeLockDelta: uint16(
46✔
4209
                        f.cfg.DefaultRoutingPolicy.TimeLockDelta,
46✔
4210
                ),
46✔
4211
                HtlcMinimumMsat: fwdMinHTLC,
46✔
4212
                HtlcMaximumMsat: fwdMaxHTLC,
46✔
4213
        }
46✔
4214

46✔
4215
        // The caller of newChanAnnouncement is expected to provide the initial
46✔
4216
        // forwarding policy to be announced. If no persisted initial policy
46✔
4217
        // values are found, then we will use the default policy values in the
46✔
4218
        // channel announcement.
46✔
4219
        storedFwdingPolicy, err := f.getInitialForwardingPolicy(chanID)
46✔
4220
        if err != nil && !errors.Is(err, channeldb.ErrChannelNotFound) {
46✔
4221
                return nil, errors.Errorf("unable to generate channel "+
×
4222
                        "update announcement: %v", err)
×
4223
        }
×
4224

4225
        switch {
46✔
4226
        case ourPolicy != nil:
4✔
4227
                // If ourPolicy is non-nil, modify the default parameters of the
4✔
4228
                // ChannelUpdate.
4✔
4229
                chanUpdateAnn.MessageFlags = ourPolicy.MessageFlags
4✔
4230
                chanUpdateAnn.ChannelFlags = ourPolicy.ChannelFlags
4✔
4231
                chanUpdateAnn.TimeLockDelta = ourPolicy.TimeLockDelta
4✔
4232
                chanUpdateAnn.HtlcMinimumMsat = ourPolicy.MinHTLC
4✔
4233
                chanUpdateAnn.HtlcMaximumMsat = ourPolicy.MaxHTLC
4✔
4234
                chanUpdateAnn.BaseFee = uint32(ourPolicy.FeeBaseMSat)
4✔
4235
                chanUpdateAnn.FeeRate = uint32(
4✔
4236
                        ourPolicy.FeeProportionalMillionths,
4✔
4237
                )
4✔
4238

4239
        case storedFwdingPolicy != nil:
46✔
4240
                chanUpdateAnn.BaseFee = uint32(storedFwdingPolicy.BaseFee)
46✔
4241
                chanUpdateAnn.FeeRate = uint32(storedFwdingPolicy.FeeRate)
46✔
4242

4243
        default:
×
4244
                log.Infof("No channel forwarding policy specified for channel "+
×
4245
                        "announcement of ChannelID(%v). "+
×
4246
                        "Assuming default fee parameters.", chanID)
×
4247
                chanUpdateAnn.BaseFee = uint32(
×
4248
                        f.cfg.DefaultRoutingPolicy.BaseFee,
×
4249
                )
×
4250
                chanUpdateAnn.FeeRate = uint32(
×
4251
                        f.cfg.DefaultRoutingPolicy.FeeRate,
×
4252
                )
×
4253
        }
4254

4255
        // With the channel update announcement constructed, we'll generate a
4256
        // signature that signs a double-sha digest of the announcement.
4257
        // This'll serve to authenticate this announcement and any other future
4258
        // updates we may send.
4259
        chanUpdateMsg, err := chanUpdateAnn.DataToSign()
46✔
4260
        if err != nil {
46✔
4261
                return nil, err
×
4262
        }
×
4263
        sig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanUpdateMsg, true)
46✔
4264
        if err != nil {
46✔
4265
                return nil, errors.Errorf("unable to generate channel "+
×
4266
                        "update announcement signature: %v", err)
×
4267
        }
×
4268
        chanUpdateAnn.Signature, err = lnwire.NewSigFromSignature(sig)
46✔
4269
        if err != nil {
46✔
4270
                return nil, errors.Errorf("unable to generate channel "+
×
4271
                        "update announcement signature: %v", err)
×
4272
        }
×
4273

4274
        // The channel existence proofs itself is currently announced in
4275
        // distinct message. In order to properly authenticate this message, we
4276
        // need two signatures: one under the identity public key used which
4277
        // signs the message itself and another signature of the identity
4278
        // public key under the funding key itself.
4279
        //
4280
        // TODO(roasbeef): use SignAnnouncement here instead?
4281
        chanAnnMsg, err := chanAnn.DataToSign()
46✔
4282
        if err != nil {
46✔
4283
                return nil, err
×
4284
        }
×
4285
        nodeSig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanAnnMsg, true)
46✔
4286
        if err != nil {
46✔
4287
                return nil, errors.Errorf("unable to generate node "+
×
4288
                        "signature for channel announcement: %v", err)
×
4289
        }
×
4290
        bitcoinSig, err := f.cfg.SignMessage(
46✔
4291
                localFundingKey.KeyLocator, chanAnnMsg, true,
46✔
4292
        )
46✔
4293
        if err != nil {
46✔
4294
                return nil, errors.Errorf("unable to generate bitcoin "+
×
4295
                        "signature for node public key: %v", err)
×
4296
        }
×
4297

4298
        // Finally, we'll generate the announcement proof which we'll use to
4299
        // provide the other side with the necessary signatures required to
4300
        // allow them to reconstruct the full channel announcement.
4301
        proof := &lnwire.AnnounceSignatures{
46✔
4302
                ChannelID:      chanID,
46✔
4303
                ShortChannelID: shortChanID,
46✔
4304
        }
46✔
4305
        proof.NodeSignature, err = lnwire.NewSigFromSignature(nodeSig)
46✔
4306
        if err != nil {
46✔
4307
                return nil, err
×
4308
        }
×
4309
        proof.BitcoinSignature, err = lnwire.NewSigFromSignature(bitcoinSig)
46✔
4310
        if err != nil {
46✔
4311
                return nil, err
×
4312
        }
×
4313

4314
        return &chanAnnouncement{
46✔
4315
                chanAnn:       chanAnn,
46✔
4316
                chanUpdateAnn: chanUpdateAnn,
46✔
4317
                chanProof:     proof,
46✔
4318
        }, nil
46✔
4319
}
4320

4321
// announceChannel announces a newly created channel to the rest of the network
4322
// by crafting the two authenticated announcements required for the peers on
4323
// the network to recognize the legitimacy of the channel. The crafted
4324
// announcements are then sent to the channel router to handle broadcasting to
4325
// the network during its next trickle.
4326
// This method is synchronous and will return when all the network requests
4327
// finish, either successfully or with an error.
4328
func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
4329
        localFundingKey *keychain.KeyDescriptor,
4330
        remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
4331
        chanID lnwire.ChannelID, chanType channeldb.ChannelType) error {
20✔
4332

20✔
4333
        // First, we'll create the batch of announcements to be sent upon
20✔
4334
        // initial channel creation. This includes the channel announcement
20✔
4335
        // itself, the channel update announcement, and our half of the channel
20✔
4336
        // proof needed to fully authenticate the channel.
20✔
4337
        //
20✔
4338
        // We can pass in zeroes for the min and max htlc policy, because we
20✔
4339
        // only use the channel announcement message from the returned struct.
20✔
4340
        ann, err := f.newChanAnnouncement(localIDKey, remoteIDKey,
20✔
4341
                localFundingKey, remoteFundingKey, shortChanID, chanID,
20✔
4342
                0, 0, nil, chanType,
20✔
4343
        )
20✔
4344
        if err != nil {
20✔
4345
                log.Errorf("can't generate channel announcement: %v", err)
×
4346
                return err
×
4347
        }
×
4348

4349
        // We only send the channel proof announcement and the node announcement
4350
        // because addToGraph previously sent the ChannelAnnouncement and
4351
        // the ChannelUpdate announcement messages. The channel proof and node
4352
        // announcements are broadcast to the greater network.
4353
        errChan := f.cfg.SendAnnouncement(ann.chanProof)
20✔
4354
        select {
20✔
4355
        case err := <-errChan:
20✔
4356
                if err != nil {
24✔
4357
                        if graph.IsError(err, graph.ErrOutdated,
4✔
4358
                                graph.ErrIgnored) {
4✔
4359

×
4360
                                log.Debugf("Graph rejected "+
×
4361
                                        "AnnounceSignatures: %v", err)
×
4362
                        } else {
4✔
4363
                                log.Errorf("Unable to send channel "+
4✔
4364
                                        "proof: %v", err)
4✔
4365
                                return err
4✔
4366
                        }
4✔
4367
                }
4368

4369
        case <-f.quit:
×
4370
                return ErrFundingManagerShuttingDown
×
4371
        }
4372

4373
        // Now that the channel is announced to the network, we will also
4374
        // obtain and send a node announcement. This is done since a node
4375
        // announcement is only accepted after a channel is known for that
4376
        // particular node, and this might be our first channel.
4377
        nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
20✔
4378
        if err != nil {
20✔
4379
                log.Errorf("can't generate node announcement: %v", err)
×
4380
                return err
×
4381
        }
×
4382

4383
        errChan = f.cfg.SendAnnouncement(&nodeAnn)
20✔
4384
        select {
20✔
4385
        case err := <-errChan:
20✔
4386
                if err != nil {
24✔
4387
                        if graph.IsError(err, graph.ErrOutdated,
4✔
4388
                                graph.ErrIgnored) {
8✔
4389

4✔
4390
                                log.Debugf("Graph rejected "+
4✔
4391
                                        "NodeAnnouncement: %v", err)
4✔
4392
                        } else {
4✔
4393
                                log.Errorf("Unable to send node "+
×
4394
                                        "announcement: %v", err)
×
4395
                                return err
×
4396
                        }
×
4397
                }
4398

4399
        case <-f.quit:
×
4400
                return ErrFundingManagerShuttingDown
×
4401
        }
4402

4403
        return nil
20✔
4404
}
4405

4406
// InitFundingWorkflow sends a message to the funding manager instructing it
4407
// to initiate a single funder workflow with the source peer.
4408
// TODO(roasbeef): re-visit blocking nature..
4409
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
60✔
4410
        f.fundingRequests <- msg
60✔
4411
}
60✔
4412

4413
// getUpfrontShutdownScript takes a user provided script and a getScript
4414
// function which can be used to generate an upfront shutdown script. If our
4415
// peer does not support the feature, this function will error if a non-zero
4416
// script was provided by the user, and return an empty script otherwise. If
4417
// our peer does support the feature, we will return the user provided script
4418
// if non-zero, or a freshly generated script if our node is configured to set
4419
// upfront shutdown scripts automatically.
4420
func getUpfrontShutdownScript(enableUpfrontShutdown bool, peer lnpeer.Peer,
4421
        script lnwire.DeliveryAddress,
4422
        getScript func(bool) (lnwire.DeliveryAddress, error)) (lnwire.DeliveryAddress,
4423
        error) {
112✔
4424

112✔
4425
        // Check whether the remote peer supports upfront shutdown scripts.
112✔
4426
        remoteUpfrontShutdown := peer.RemoteFeatures().HasFeature(
112✔
4427
                lnwire.UpfrontShutdownScriptOptional,
112✔
4428
        )
112✔
4429

112✔
4430
        // If the peer does not support upfront shutdown scripts, and one has been
112✔
4431
        // provided, return an error because the feature is not supported.
112✔
4432
        if !remoteUpfrontShutdown && len(script) != 0 {
113✔
4433
                return nil, errUpfrontShutdownScriptNotSupported
1✔
4434
        }
1✔
4435

4436
        // If the peer does not support upfront shutdown, return an empty address.
4437
        if !remoteUpfrontShutdown {
214✔
4438
                return nil, nil
103✔
4439
        }
103✔
4440

4441
        // If the user has provided an script and the peer supports the feature,
4442
        // return it. Note that user set scripts override the enable upfront
4443
        // shutdown flag.
4444
        if len(script) > 0 {
14✔
4445
                return script, nil
6✔
4446
        }
6✔
4447

4448
        // If we do not have setting of upfront shutdown script enabled, return
4449
        // an empty script.
4450
        if !enableUpfrontShutdown {
11✔
4451
                return nil, nil
5✔
4452
        }
5✔
4453

4454
        // We can safely send a taproot address iff, both sides have negotiated
4455
        // the shutdown-any-segwit feature.
4456
        taprootOK := peer.RemoteFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) &&
1✔
4457
                peer.LocalFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional)
1✔
4458

1✔
4459
        return getScript(taprootOK)
1✔
4460
}
4461

4462
// handleInitFundingMsg creates a channel reservation within the daemon's
4463
// wallet, then sends a funding request to the remote peer kicking off the
4464
// funding workflow.
4465
func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
60✔
4466
        var (
60✔
4467
                peerKey        = msg.Peer.IdentityKey()
60✔
4468
                localAmt       = msg.LocalFundingAmt
60✔
4469
                baseFee        = msg.BaseFee
60✔
4470
                feeRate        = msg.FeeRate
60✔
4471
                minHtlcIn      = msg.MinHtlcIn
60✔
4472
                remoteCsvDelay = msg.RemoteCsvDelay
60✔
4473
                maxValue       = msg.MaxValueInFlight
60✔
4474
                maxHtlcs       = msg.MaxHtlcs
60✔
4475
                maxCSV         = msg.MaxLocalCsv
60✔
4476
                chanReserve    = msg.RemoteChanReserve
60✔
4477
                outpoints      = msg.Outpoints
60✔
4478
        )
60✔
4479

60✔
4480
        // If no maximum CSV delay was set for this channel, we use our default
60✔
4481
        // value.
60✔
4482
        if maxCSV == 0 {
120✔
4483
                maxCSV = f.cfg.MaxLocalCSVDelay
60✔
4484
        }
60✔
4485

4486
        log.Infof("Initiating fundingRequest(local_amt=%v "+
60✔
4487
                "(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
60✔
4488
                "min_confs=%v)", localAmt, msg.SubtractFees, msg.PushAmt,
60✔
4489
                msg.ChainHash, peerKey.SerializeCompressed(), msg.MinConfs)
60✔
4490

60✔
4491
        // We set the channel flags to indicate whether we want this channel to
60✔
4492
        // be announced to the network.
60✔
4493
        var channelFlags lnwire.FundingFlag
60✔
4494
        if !msg.Private {
115✔
4495
                // This channel will be announced.
55✔
4496
                channelFlags = lnwire.FFAnnounceChannel
55✔
4497
        }
55✔
4498

4499
        // If the caller specified their own channel ID, then we'll use that.
4500
        // Otherwise we'll generate a fresh one as normal.  This will be used
4501
        // to track this reservation throughout its lifetime.
4502
        var chanID [32]byte
60✔
4503
        if msg.PendingChanID == zeroID {
120✔
4504
                chanID = f.nextPendingChanID()
60✔
4505
        } else {
64✔
4506
                // If the user specified their own pending channel ID, then
4✔
4507
                // we'll ensure it doesn't collide with any existing pending
4✔
4508
                // channel ID.
4✔
4509
                chanID = msg.PendingChanID
4✔
4510
                if _, err := f.getReservationCtx(peerKey, chanID); err == nil {
4✔
4511
                        msg.Err <- fmt.Errorf("pendingChannelID(%x) "+
×
4512
                                "already present", chanID[:])
×
4513
                        return
×
4514
                }
×
4515
        }
4516

4517
        // Check whether the peer supports upfront shutdown, and get an address
4518
        // which should be used (either a user specified address or a new
4519
        // address from the wallet if our node is configured to set shutdown
4520
        // address by default).
4521
        shutdown, err := getUpfrontShutdownScript(
60✔
4522
                f.cfg.EnableUpfrontShutdown, msg.Peer, msg.ShutdownScript,
60✔
4523
                f.selectShutdownScript,
60✔
4524
        )
60✔
4525
        if err != nil {
60✔
4526
                msg.Err <- err
×
4527
                return
×
4528
        }
×
4529

4530
        // Initialize a funding reservation with the local wallet. If the
4531
        // wallet doesn't have enough funds to commit to this channel, then the
4532
        // request will fail, and be aborted.
4533
        //
4534
        // Before we init the channel, we'll also check to see what commitment
4535
        // format we can use with this peer. This is dependent on *both* us and
4536
        // the remote peer are signaling the proper feature bit.
4537
        chanType, commitType, err := negotiateCommitmentType(
60✔
4538
                msg.ChannelType, msg.Peer.LocalFeatures(),
60✔
4539
                msg.Peer.RemoteFeatures(),
60✔
4540
        )
60✔
4541
        if err != nil {
64✔
4542
                log.Errorf("channel type negotiation failed: %v", err)
4✔
4543
                msg.Err <- err
4✔
4544
                return
4✔
4545
        }
4✔
4546

4547
        var (
60✔
4548
                zeroConf bool
60✔
4549
                scid     bool
60✔
4550
        )
60✔
4551

60✔
4552
        if chanType != nil {
68✔
4553
                // Check if the returned chanType includes either the zero-conf
8✔
4554
                // or scid-alias bits.
8✔
4555
                featureVec := lnwire.RawFeatureVector(*chanType)
8✔
4556
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
8✔
4557
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
8✔
4558

8✔
4559
                // The option-scid-alias channel type for a public channel is
8✔
4560
                // disallowed.
8✔
4561
                if scid && !msg.Private {
8✔
4562
                        err = fmt.Errorf("option-scid-alias chantype for " +
×
4563
                                "public channel")
×
4564
                        log.Error(err)
×
4565
                        msg.Err <- err
×
4566

×
4567
                        return
×
4568
                }
×
4569
        }
4570

4571
        // First, we'll query the fee estimator for a fee that should get the
4572
        // commitment transaction confirmed by the next few blocks (conf target
4573
        // of 3). We target the near blocks here to ensure that we'll be able
4574
        // to execute a timely unilateral channel closure if needed.
4575
        commitFeePerKw, err := f.cfg.FeeEstimator.EstimateFeePerKW(3)
60✔
4576
        if err != nil {
60✔
4577
                msg.Err <- err
×
4578
                return
×
4579
        }
×
4580

4581
        // For anchor channels cap the initial commit fee rate at our defined
4582
        // maximum.
4583
        if commitType.HasAnchors() &&
60✔
4584
                commitFeePerKw > f.cfg.MaxAnchorsCommitFeeRate {
68✔
4585

8✔
4586
                commitFeePerKw = f.cfg.MaxAnchorsCommitFeeRate
8✔
4587
        }
8✔
4588

4589
        var scidFeatureVal bool
60✔
4590
        if hasFeatures(
60✔
4591
                msg.Peer.LocalFeatures(), msg.Peer.RemoteFeatures(),
60✔
4592
                lnwire.ScidAliasOptional,
60✔
4593
        ) {
67✔
4594

7✔
4595
                scidFeatureVal = true
7✔
4596
        }
7✔
4597

4598
        req := &lnwallet.InitFundingReserveMsg{
60✔
4599
                ChainHash:         &msg.ChainHash,
60✔
4600
                PendingChanID:     chanID,
60✔
4601
                NodeID:            peerKey,
60✔
4602
                NodeAddr:          msg.Peer.Address(),
60✔
4603
                SubtractFees:      msg.SubtractFees,
60✔
4604
                LocalFundingAmt:   localAmt,
60✔
4605
                RemoteFundingAmt:  0,
60✔
4606
                FundUpToMaxAmt:    msg.FundUpToMaxAmt,
60✔
4607
                MinFundAmt:        msg.MinFundAmt,
60✔
4608
                RemoteChanReserve: chanReserve,
60✔
4609
                Outpoints:         outpoints,
60✔
4610
                CommitFeePerKw:    commitFeePerKw,
60✔
4611
                FundingFeePerKw:   msg.FundingFeePerKw,
60✔
4612
                PushMSat:          msg.PushAmt,
60✔
4613
                Flags:             channelFlags,
60✔
4614
                MinConfs:          msg.MinConfs,
60✔
4615
                CommitType:        commitType,
60✔
4616
                ChanFunder:        msg.ChanFunder,
60✔
4617
                // Unconfirmed Utxos which are marked by the sweeper subsystem
60✔
4618
                // are excluded from the coin selection because they are not
60✔
4619
                // final and can be RBFed by the sweeper subsystem.
60✔
4620
                AllowUtxoForFunding: func(u lnwallet.Utxo) bool {
121✔
4621
                        // Utxos with at least 1 confirmation are safe to use
61✔
4622
                        // for channel openings because they don't bare the risk
61✔
4623
                        // of being replaced (BIP 125 RBF).
61✔
4624
                        if u.Confirmations > 0 {
65✔
4625
                                return true
4✔
4626
                        }
4✔
4627

4628
                        // Query the sweeper storage to make sure we don't use
4629
                        // an unconfirmed utxo still in use by the sweeper
4630
                        // subsystem.
4631
                        return !f.cfg.IsSweeperOutpoint(u.OutPoint)
61✔
4632
                },
4633
                ZeroConf:         zeroConf,
4634
                OptionScidAlias:  scid,
4635
                ScidAliasFeature: scidFeatureVal,
4636
                Memo:             msg.Memo,
4637
        }
4638

4639
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
60✔
4640
        if err != nil {
64✔
4641
                msg.Err <- err
4✔
4642
                return
4✔
4643
        }
4✔
4644

4645
        if zeroConf {
66✔
4646
                // Store the alias for zero-conf channels in the underlying
6✔
4647
                // partial channel state.
6✔
4648
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
6✔
4649
                if err != nil {
6✔
4650
                        msg.Err <- err
×
4651
                        return
×
4652
                }
×
4653

4654
                reservation.AddAlias(aliasScid)
6✔
4655
        }
4656

4657
        // Set our upfront shutdown address in the existing reservation.
4658
        reservation.SetOurUpfrontShutdown(shutdown)
60✔
4659

60✔
4660
        // Now that we have successfully reserved funds for this channel in the
60✔
4661
        // wallet, we can fetch the final channel capacity. This is done at
60✔
4662
        // this point since the final capacity might change in case of
60✔
4663
        // SubtractFees=true.
60✔
4664
        capacity := reservation.Capacity()
60✔
4665

60✔
4666
        log.Infof("Target commit tx sat/kw for pendingID(%x): %v", chanID,
60✔
4667
                int64(commitFeePerKw))
60✔
4668

60✔
4669
        // If the remote CSV delay was not set in the open channel request,
60✔
4670
        // we'll use the RequiredRemoteDelay closure to compute the delay we
60✔
4671
        // require given the total amount of funds within the channel.
60✔
4672
        if remoteCsvDelay == 0 {
119✔
4673
                remoteCsvDelay = f.cfg.RequiredRemoteDelay(capacity)
59✔
4674
        }
59✔
4675

4676
        // If no minimum HTLC value was specified, use the default one.
4677
        if minHtlcIn == 0 {
119✔
4678
                minHtlcIn = f.cfg.DefaultMinHtlcIn
59✔
4679
        }
59✔
4680

4681
        // If no max value was specified, use the default one.
4682
        if maxValue == 0 {
119✔
4683
                maxValue = f.cfg.RequiredRemoteMaxValue(capacity)
59✔
4684
        }
59✔
4685

4686
        if maxHtlcs == 0 {
120✔
4687
                maxHtlcs = f.cfg.RequiredRemoteMaxHTLCs(capacity)
60✔
4688
        }
60✔
4689

4690
        // Once the reservation has been created, and indexed, queue a funding
4691
        // request to the remote peer, kicking off the funding workflow.
4692
        ourContribution := reservation.OurContribution()
60✔
4693

60✔
4694
        // Prepare the optional channel fee values from the initFundingMsg. If
60✔
4695
        // useBaseFee or useFeeRate are false the client did not provide fee
60✔
4696
        // values hence we assume default fee settings from the config.
60✔
4697
        forwardingPolicy := f.defaultForwardingPolicy(
60✔
4698
                ourContribution.ChannelConstraints,
60✔
4699
        )
60✔
4700
        if baseFee != nil {
65✔
4701
                forwardingPolicy.BaseFee = lnwire.MilliSatoshi(*baseFee)
5✔
4702
        }
5✔
4703

4704
        if feeRate != nil {
65✔
4705
                forwardingPolicy.FeeRate = lnwire.MilliSatoshi(*feeRate)
5✔
4706
        }
5✔
4707

4708
        // Fetch our dust limit which is part of the default channel
4709
        // constraints, and log it.
4710
        ourDustLimit := ourContribution.DustLimit
60✔
4711

60✔
4712
        log.Infof("Dust limit for pendingID(%x): %v", chanID, ourDustLimit)
60✔
4713

60✔
4714
        // If the channel reserve is not specified, then we calculate an
60✔
4715
        // appropriate amount here.
60✔
4716
        if chanReserve == 0 {
116✔
4717
                chanReserve = f.cfg.RequiredRemoteChanReserve(
56✔
4718
                        capacity, ourDustLimit,
56✔
4719
                )
56✔
4720
        }
56✔
4721

4722
        // If a pending channel map for this peer isn't already created, then
4723
        // we create one, ultimately allowing us to track this pending
4724
        // reservation within the target peer.
4725
        peerIDKey := newSerializedKey(peerKey)
60✔
4726
        f.resMtx.Lock()
60✔
4727
        if _, ok := f.activeReservations[peerIDKey]; !ok {
113✔
4728
                f.activeReservations[peerIDKey] = make(pendingChannels)
53✔
4729
        }
53✔
4730

4731
        resCtx := &reservationWithCtx{
60✔
4732
                chanAmt:           capacity,
60✔
4733
                forwardingPolicy:  *forwardingPolicy,
60✔
4734
                remoteCsvDelay:    remoteCsvDelay,
60✔
4735
                remoteMinHtlc:     minHtlcIn,
60✔
4736
                remoteMaxValue:    maxValue,
60✔
4737
                remoteMaxHtlcs:    maxHtlcs,
60✔
4738
                remoteChanReserve: chanReserve,
60✔
4739
                maxLocalCsv:       maxCSV,
60✔
4740
                channelType:       chanType,
60✔
4741
                reservation:       reservation,
60✔
4742
                peer:              msg.Peer,
60✔
4743
                updates:           msg.Updates,
60✔
4744
                err:               msg.Err,
60✔
4745
        }
60✔
4746
        f.activeReservations[peerIDKey][chanID] = resCtx
60✔
4747
        f.resMtx.Unlock()
60✔
4748

60✔
4749
        // Update the timestamp once the InitFundingMsg has been handled.
60✔
4750
        defer resCtx.updateTimestamp()
60✔
4751

60✔
4752
        // Check the sanity of the selected channel constraints.
60✔
4753
        channelConstraints := &channeldb.ChannelConstraints{
60✔
4754
                DustLimit:        ourDustLimit,
60✔
4755
                ChanReserve:      chanReserve,
60✔
4756
                MaxPendingAmount: maxValue,
60✔
4757
                MinHTLC:          minHtlcIn,
60✔
4758
                MaxAcceptedHtlcs: maxHtlcs,
60✔
4759
                CsvDelay:         remoteCsvDelay,
60✔
4760
        }
60✔
4761
        err = lnwallet.VerifyConstraints(
60✔
4762
                channelConstraints, resCtx.maxLocalCsv, capacity,
60✔
4763
        )
60✔
4764
        if err != nil {
62✔
4765
                _, reserveErr := f.cancelReservationCtx(peerKey, chanID, false)
2✔
4766
                if reserveErr != nil {
2✔
4767
                        log.Errorf("unable to cancel reservation: %v",
×
4768
                                reserveErr)
×
4769
                }
×
4770

4771
                msg.Err <- err
2✔
4772
                return
2✔
4773
        }
4774

4775
        // When opening a script enforced channel lease, include the required
4776
        // expiry TLV record in our proposal.
4777
        var leaseExpiry *lnwire.LeaseExpiry
58✔
4778
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
62✔
4779
                leaseExpiry = new(lnwire.LeaseExpiry)
4✔
4780
                *leaseExpiry = lnwire.LeaseExpiry(reservation.LeaseExpiry())
4✔
4781
        }
4✔
4782

4783
        log.Infof("Starting funding workflow with %v for pending_id(%x), "+
58✔
4784
                "committype=%v", msg.Peer.Address(), chanID, commitType)
58✔
4785

58✔
4786
        fundingOpen := lnwire.OpenChannel{
58✔
4787
                ChainHash:             *f.cfg.Wallet.Cfg.NetParams.GenesisHash,
58✔
4788
                PendingChannelID:      chanID,
58✔
4789
                FundingAmount:         capacity,
58✔
4790
                PushAmount:            msg.PushAmt,
58✔
4791
                DustLimit:             ourDustLimit,
58✔
4792
                MaxValueInFlight:      maxValue,
58✔
4793
                ChannelReserve:        chanReserve,
58✔
4794
                HtlcMinimum:           minHtlcIn,
58✔
4795
                FeePerKiloWeight:      uint32(commitFeePerKw),
58✔
4796
                CsvDelay:              remoteCsvDelay,
58✔
4797
                MaxAcceptedHTLCs:      maxHtlcs,
58✔
4798
                FundingKey:            ourContribution.MultiSigKey.PubKey,
58✔
4799
                RevocationPoint:       ourContribution.RevocationBasePoint.PubKey,
58✔
4800
                PaymentPoint:          ourContribution.PaymentBasePoint.PubKey,
58✔
4801
                HtlcPoint:             ourContribution.HtlcBasePoint.PubKey,
58✔
4802
                DelayedPaymentPoint:   ourContribution.DelayBasePoint.PubKey,
58✔
4803
                FirstCommitmentPoint:  ourContribution.FirstCommitmentPoint,
58✔
4804
                ChannelFlags:          channelFlags,
58✔
4805
                UpfrontShutdownScript: shutdown,
58✔
4806
                ChannelType:           chanType,
58✔
4807
                LeaseExpiry:           leaseExpiry,
58✔
4808
        }
58✔
4809

58✔
4810
        if commitType.IsTaproot() {
64✔
4811
                fundingOpen.LocalNonce = lnwire.SomeMusig2Nonce(
6✔
4812
                        ourContribution.LocalNonce.PubNonce,
6✔
4813
                )
6✔
4814
        }
6✔
4815

4816
        if err := msg.Peer.SendMessage(true, &fundingOpen); err != nil {
58✔
4817
                e := fmt.Errorf("unable to send funding request message: %w",
×
4818
                        err)
×
4819
                log.Errorf(e.Error())
×
4820

×
4821
                // Since we were unable to send the initial message to the peer
×
4822
                // and start the funding flow, we'll cancel this reservation.
×
4823
                _, err := f.cancelReservationCtx(peerKey, chanID, false)
×
4824
                if err != nil {
×
4825
                        log.Errorf("unable to cancel reservation: %v", err)
×
4826
                }
×
4827

4828
                msg.Err <- e
×
4829
                return
×
4830
        }
4831
}
4832

4833
// handleWarningMsg processes the warning which was received from remote peer.
4834
func (f *Manager) handleWarningMsg(peer lnpeer.Peer, msg *lnwire.Warning) {
42✔
4835
        log.Warnf("received warning message from peer %x: %v",
42✔
4836
                peer.IdentityKey().SerializeCompressed(), msg.Warning())
42✔
4837
}
42✔
4838

4839
// handleErrorMsg processes the error which was received from remote peer,
4840
// depending on the type of error we should do different clean up steps and
4841
// inform the user about it.
4842
func (f *Manager) handleErrorMsg(peer lnpeer.Peer, msg *lnwire.Error) {
4✔
4843
        chanID := msg.ChanID
4✔
4844
        peerKey := peer.IdentityKey()
4✔
4845

4✔
4846
        // First, we'll attempt to retrieve and cancel the funding workflow
4✔
4847
        // that this error was tied to. If we're unable to do so, then we'll
4✔
4848
        // exit early as this was an unwarranted error.
4✔
4849
        resCtx, err := f.cancelReservationCtx(peerKey, chanID, true)
4✔
4850
        if err != nil {
4✔
4851
                log.Warnf("Received error for non-existent funding "+
×
4852
                        "flow: %v (%v)", err, msg.Error())
×
4853
                return
×
4854
        }
×
4855

4856
        // If we did indeed find the funding workflow, then we'll return the
4857
        // error back to the caller (if any), and cancel the workflow itself.
4858
        fundingErr := fmt.Errorf("received funding error from %x: %v",
4✔
4859
                peerKey.SerializeCompressed(), msg.Error(),
4✔
4860
        )
4✔
4861
        log.Errorf(fundingErr.Error())
4✔
4862

4✔
4863
        // If this was a PSBT funding flow, the remote likely timed out because
4✔
4864
        // we waited too long. Return a nice error message to the user in that
4✔
4865
        // case so the user knows what's the problem.
4✔
4866
        if resCtx.reservation.IsPsbt() {
8✔
4867
                fundingErr = fmt.Errorf("%w: %v", chanfunding.ErrRemoteCanceled,
4✔
4868
                        fundingErr)
4✔
4869
        }
4✔
4870

4871
        resCtx.err <- fundingErr
4✔
4872
}
4873

4874
// pruneZombieReservations loops through all pending reservations and fails the
4875
// funding flow for any reservations that have not been updated since the
4876
// ReservationTimeout and are not locked waiting for the funding transaction.
4877
func (f *Manager) pruneZombieReservations() {
7✔
4878
        zombieReservations := make(pendingChannels)
7✔
4879

7✔
4880
        f.resMtx.RLock()
7✔
4881
        for _, pendingReservations := range f.activeReservations {
14✔
4882
                for pendingChanID, resCtx := range pendingReservations {
14✔
4883
                        if resCtx.isLocked() {
7✔
4884
                                continue
×
4885
                        }
4886

4887
                        // We don't want to expire PSBT funding reservations.
4888
                        // These reservations are always initiated by us and the
4889
                        // remote peer is likely going to cancel them after some
4890
                        // idle time anyway. So no need for us to also prune
4891
                        // them.
4892
                        sinceLastUpdate := time.Since(resCtx.lastUpdated)
7✔
4893
                        isExpired := sinceLastUpdate > f.cfg.ReservationTimeout
7✔
4894
                        if !resCtx.reservation.IsPsbt() && isExpired {
14✔
4895
                                zombieReservations[pendingChanID] = resCtx
7✔
4896
                        }
7✔
4897
                }
4898
        }
4899
        f.resMtx.RUnlock()
7✔
4900

7✔
4901
        for pendingChanID, resCtx := range zombieReservations {
14✔
4902
                err := fmt.Errorf("reservation timed out waiting for peer "+
7✔
4903
                        "(peer_id:%x, chan_id:%x)",
7✔
4904
                        resCtx.peer.IdentityKey().SerializeCompressed(),
7✔
4905
                        pendingChanID[:])
7✔
4906
                log.Warnf(err.Error())
7✔
4907

7✔
4908
                chanID := lnwire.NewChanIDFromOutPoint(
7✔
4909
                        *resCtx.reservation.FundingOutpoint(),
7✔
4910
                )
7✔
4911

7✔
4912
                // Create channel identifier and set the channel ID.
7✔
4913
                cid := newChanIdentifier(pendingChanID)
7✔
4914
                cid.setChanID(chanID)
7✔
4915

7✔
4916
                f.failFundingFlow(resCtx.peer, cid, err)
7✔
4917
        }
7✔
4918
}
4919

4920
// cancelReservationCtx does all needed work in order to securely cancel the
4921
// reservation.
4922
func (f *Manager) cancelReservationCtx(peerKey *btcec.PublicKey,
4923
        pendingChanID [32]byte, byRemote bool) (*reservationWithCtx, error) {
27✔
4924

27✔
4925
        log.Infof("Cancelling funding reservation for node_key=%x, "+
27✔
4926
                "chan_id=%x", peerKey.SerializeCompressed(), pendingChanID[:])
27✔
4927

27✔
4928
        peerIDKey := newSerializedKey(peerKey)
27✔
4929
        f.resMtx.Lock()
27✔
4930
        defer f.resMtx.Unlock()
27✔
4931

27✔
4932
        nodeReservations, ok := f.activeReservations[peerIDKey]
27✔
4933
        if !ok {
38✔
4934
                // No reservations for this node.
11✔
4935
                return nil, errors.Errorf("no active reservations for peer(%x)",
11✔
4936
                        peerIDKey[:])
11✔
4937
        }
11✔
4938

4939
        ctx, ok := nodeReservations[pendingChanID]
20✔
4940
        if !ok {
22✔
4941
                return nil, errors.Errorf("unknown channel (id: %x) for "+
2✔
4942
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
2✔
4943
        }
2✔
4944

4945
        // If the reservation was a PSBT funding flow and it was canceled by the
4946
        // remote peer, then we need to thread through a different error message
4947
        // to the subroutine that's waiting for the user input so it can return
4948
        // a nice error message to the user.
4949
        if ctx.reservation.IsPsbt() && byRemote {
22✔
4950
                ctx.reservation.RemoteCanceled()
4✔
4951
        }
4✔
4952

4953
        if err := ctx.reservation.Cancel(); err != nil {
18✔
4954
                return nil, errors.Errorf("unable to cancel reservation: %v",
×
4955
                        err)
×
4956
        }
×
4957

4958
        delete(nodeReservations, pendingChanID)
18✔
4959

18✔
4960
        // If this was the last active reservation for this peer, delete the
18✔
4961
        // peer's entry altogether.
18✔
4962
        if len(nodeReservations) == 0 {
36✔
4963
                delete(f.activeReservations, peerIDKey)
18✔
4964
        }
18✔
4965
        return ctx, nil
18✔
4966
}
4967

4968
// deleteReservationCtx deletes the reservation uniquely identified by the
4969
// target public key of the peer, and the specified pending channel ID.
4970
func (f *Manager) deleteReservationCtx(peerKey *btcec.PublicKey,
4971
        pendingChanID [32]byte) {
58✔
4972

58✔
4973
        peerIDKey := newSerializedKey(peerKey)
58✔
4974
        f.resMtx.Lock()
58✔
4975
        defer f.resMtx.Unlock()
58✔
4976

58✔
4977
        nodeReservations, ok := f.activeReservations[peerIDKey]
58✔
4978
        if !ok {
58✔
4979
                // No reservations for this node.
×
4980
                return
×
4981
        }
×
4982
        delete(nodeReservations, pendingChanID)
58✔
4983

58✔
4984
        // If this was the last active reservation for this peer, delete the
58✔
4985
        // peer's entry altogether.
58✔
4986
        if len(nodeReservations) == 0 {
109✔
4987
                delete(f.activeReservations, peerIDKey)
51✔
4988
        }
51✔
4989
}
4990

4991
// getReservationCtx returns the reservation context for a particular pending
4992
// channel ID for a target peer.
4993
func (f *Manager) getReservationCtx(peerKey *btcec.PublicKey,
4994
        pendingChanID [32]byte) (*reservationWithCtx, error) {
92✔
4995

92✔
4996
        peerIDKey := newSerializedKey(peerKey)
92✔
4997
        f.resMtx.RLock()
92✔
4998
        resCtx, ok := f.activeReservations[peerIDKey][pendingChanID]
92✔
4999
        f.resMtx.RUnlock()
92✔
5000

92✔
5001
        if !ok {
96✔
5002
                return nil, errors.Errorf("unknown channel (id: %x) for "+
4✔
5003
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
4✔
5004
        }
4✔
5005

5006
        return resCtx, nil
92✔
5007
}
5008

5009
// IsPendingChannel returns a boolean indicating whether the channel identified
5010
// by the pendingChanID and given peer is pending, meaning it is in the process
5011
// of being funded. After the funding transaction has been confirmed, the
5012
// channel will receive a new, permanent channel ID, and will no longer be
5013
// considered pending.
5014
func (f *Manager) IsPendingChannel(pendingChanID [32]byte,
5015
        peer lnpeer.Peer) bool {
4✔
5016

4✔
5017
        peerIDKey := newSerializedKey(peer.IdentityKey())
4✔
5018
        f.resMtx.RLock()
4✔
5019
        _, ok := f.activeReservations[peerIDKey][pendingChanID]
4✔
5020
        f.resMtx.RUnlock()
4✔
5021

4✔
5022
        return ok
4✔
5023
}
4✔
5024

5025
func copyPubKey(pub *btcec.PublicKey) *btcec.PublicKey {
379✔
5026
        var tmp btcec.JacobianPoint
379✔
5027
        pub.AsJacobian(&tmp)
379✔
5028
        tmp.ToAffine()
379✔
5029
        return btcec.NewPublicKey(&tmp.X, &tmp.Y)
379✔
5030
}
379✔
5031

5032
// defaultForwardingPolicy returns the default forwarding policy based on the
5033
// default routing policy and our local channel constraints.
5034
func (f *Manager) defaultForwardingPolicy(
5035
        constraints channeldb.ChannelConstraints) *models.ForwardingPolicy {
106✔
5036

106✔
5037
        return &models.ForwardingPolicy{
106✔
5038
                MinHTLCOut:    constraints.MinHTLC,
106✔
5039
                MaxHTLC:       constraints.MaxPendingAmount,
106✔
5040
                BaseFee:       f.cfg.DefaultRoutingPolicy.BaseFee,
106✔
5041
                FeeRate:       f.cfg.DefaultRoutingPolicy.FeeRate,
106✔
5042
                TimeLockDelta: f.cfg.DefaultRoutingPolicy.TimeLockDelta,
106✔
5043
        }
106✔
5044
}
106✔
5045

5046
// saveInitialForwardingPolicy saves the forwarding policy for the provided
5047
// chanPoint in the channelOpeningStateBucket.
5048
func (f *Manager) saveInitialForwardingPolicy(chanID lnwire.ChannelID,
5049
        forwardingPolicy *models.ForwardingPolicy) error {
71✔
5050

71✔
5051
        return f.cfg.ChannelDB.SaveInitialForwardingPolicy(
71✔
5052
                chanID, forwardingPolicy,
71✔
5053
        )
71✔
5054
}
71✔
5055

5056
// getInitialForwardingPolicy fetches the initial forwarding policy for a given
5057
// channel id from the database which will be applied during the channel
5058
// announcement phase.
5059
func (f *Manager) getInitialForwardingPolicy(
5060
        chanID lnwire.ChannelID) (*models.ForwardingPolicy, error) {
98✔
5061

98✔
5062
        return f.cfg.ChannelDB.GetInitialForwardingPolicy(chanID)
98✔
5063
}
98✔
5064

5065
// deleteInitialForwardingPolicy removes channel fees for this chanID from
5066
// the database.
5067
func (f *Manager) deleteInitialForwardingPolicy(chanID lnwire.ChannelID) error {
28✔
5068
        return f.cfg.ChannelDB.DeleteInitialForwardingPolicy(chanID)
28✔
5069
}
28✔
5070

5071
// saveChannelOpeningState saves the channelOpeningState for the provided
5072
// chanPoint to the channelOpeningStateBucket.
5073
func (f *Manager) saveChannelOpeningState(chanPoint *wire.OutPoint,
5074
        state channelOpeningState, shortChanID *lnwire.ShortChannelID) error {
96✔
5075

96✔
5076
        var outpointBytes bytes.Buffer
96✔
5077
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
96✔
5078
                return err
×
5079
        }
×
5080

5081
        // Save state and the uint64 representation of the shortChanID
5082
        // for later use.
5083
        scratch := make([]byte, 10)
96✔
5084
        byteOrder.PutUint16(scratch[:2], uint16(state))
96✔
5085
        byteOrder.PutUint64(scratch[2:], shortChanID.ToUint64())
96✔
5086

96✔
5087
        return f.cfg.ChannelDB.SaveChannelOpeningState(
96✔
5088
                outpointBytes.Bytes(), scratch,
96✔
5089
        )
96✔
5090
}
5091

5092
// getChannelOpeningState fetches the channelOpeningState for the provided
5093
// chanPoint from the database, or returns ErrChannelNotFound if the channel
5094
// is not found.
5095
func (f *Manager) getChannelOpeningState(chanPoint *wire.OutPoint) (
5096
        channelOpeningState, *lnwire.ShortChannelID, error) {
256✔
5097

256✔
5098
        var outpointBytes bytes.Buffer
256✔
5099
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
256✔
5100
                return 0, nil, err
×
5101
        }
×
5102

5103
        value, err := f.cfg.ChannelDB.GetChannelOpeningState(
256✔
5104
                outpointBytes.Bytes(),
256✔
5105
        )
256✔
5106
        if err != nil {
307✔
5107
                return 0, nil, err
51✔
5108
        }
51✔
5109

5110
        state := channelOpeningState(byteOrder.Uint16(value[:2]))
209✔
5111
        shortChanID := lnwire.NewShortChanIDFromInt(byteOrder.Uint64(value[2:]))
209✔
5112
        return state, &shortChanID, nil
209✔
5113
}
5114

5115
// deleteChannelOpeningState removes any state for chanPoint from the database.
5116
func (f *Manager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error {
28✔
5117
        var outpointBytes bytes.Buffer
28✔
5118
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
28✔
5119
                return err
×
5120
        }
×
5121

5122
        return f.cfg.ChannelDB.DeleteChannelOpeningState(
28✔
5123
                outpointBytes.Bytes(),
28✔
5124
        )
28✔
5125
}
5126

5127
// selectShutdownScript selects the shutdown script we should send to the peer.
5128
// If we can use taproot, then we prefer that, otherwise we'll use a p2wkh
5129
// script.
5130
func (f *Manager) selectShutdownScript(taprootOK bool,
5131
) (lnwire.DeliveryAddress, error) {
×
5132

×
5133
        addrType := lnwallet.WitnessPubKey
×
5134
        if taprootOK {
×
5135
                addrType = lnwallet.TaprootPubkey
×
5136
        }
×
5137

5138
        addr, err := f.cfg.Wallet.NewAddress(
×
5139
                addrType, false, lnwallet.DefaultAccountName,
×
5140
        )
×
5141
        if err != nil {
×
5142
                return nil, err
×
5143
        }
×
5144

5145
        return txscript.PayToAddrScript(addr)
×
5146
}
5147

5148
// waitForPeerOnline blocks until the peer specified by peerPubkey comes online
5149
// and then returns the online peer.
5150
func (f *Manager) waitForPeerOnline(peerPubkey *btcec.PublicKey) (lnpeer.Peer,
5151
        error) {
109✔
5152

109✔
5153
        peerChan := make(chan lnpeer.Peer, 1)
109✔
5154

109✔
5155
        var peerKey [33]byte
109✔
5156
        copy(peerKey[:], peerPubkey.SerializeCompressed())
109✔
5157

109✔
5158
        f.cfg.NotifyWhenOnline(peerKey, peerChan)
109✔
5159

109✔
5160
        var peer lnpeer.Peer
109✔
5161
        select {
109✔
5162
        case peer = <-peerChan:
108✔
5163
        case <-f.quit:
1✔
5164
                return peer, ErrFundingManagerShuttingDown
1✔
5165
        }
5166
        return peer, nil
108✔
5167
}
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