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

lightningnetwork / lnd / 21485572389

29 Jan 2026 04:09PM UTC coverage: 65.247% (+0.2%) from 65.074%
21485572389

Pull #10089

github

web-flow
Merge 22d34d15e into 19b2ad797
Pull Request #10089: Onion message forwarding

1152 of 1448 new or added lines in 23 files covered. (79.56%)

4109 existing lines in 29 files now uncovered.

139515 of 213825 relevant lines covered (65.25%)

20529.09 hits per line

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

73.66
/funding/manager.go
1
package funding
2

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

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

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

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

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

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

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

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

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

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

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

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

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

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

102
        msgBufferSize = 50
103

104
        // pendingChansLimit is the maximum number of pending channels that we
105
        // can have. After this point, pending channel opens will start to be
106
        // rejected.
107
        pendingChansLimit = 50
108
)
109

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

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

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

129
        zeroID [32]byte
130
)
131

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

145
        chanAmt btcutil.Amount
146

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

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

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

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

164
        updateMtx   sync.RWMutex
165
        lastUpdated time.Time
166

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

572
        // AuxChannelNegotiator is an optional interface that allows aux channel
573
        // implementations to inject and process custom records over channel
574
        // related wire messages.
575
        AuxChannelNegotiator fn.Option[lnwallet.AuxChannelNegotiator]
576

577
        // ShutdownScript is an optional upfront-shutdown script to which our
578
        // funds should be paid on a cooperative close.
579
        ShutdownScript fn.Option[lnwire.DeliveryAddress]
580
}
581

582
// Manager acts as an orchestrator/bridge between the wallet's
583
// 'ChannelReservation' workflow, and the wire protocol's funding initiation
584
// messages. Any requests to initiate the funding workflow for a channel,
585
// either kicked-off locally or remotely are handled by the funding manager.
586
// Once a channel's funding workflow has been completed, any local callers, the
587
// local peer, and possibly the remote peer are notified of the completion of
588
// the channel workflow. Additionally, any temporary or permanent access
589
// controls between the wallet and remote peers are enforced via the funding
590
// manager.
591
type Manager struct {
592
        started sync.Once
593
        stopped sync.Once
594

595
        // cfg is a copy of the configuration struct that the FundingManager
596
        // was initialized with.
597
        cfg *Config
598

599
        // chanIDKey is a cryptographically random key that's used to generate
600
        // temporary channel ID's.
601
        chanIDKey [32]byte
602

603
        // chanIDNonce is a nonce that's incremented for each new funding
604
        // reservation created.
605
        chanIDNonce atomic.Uint64
606

607
        // nonceMtx is a mutex that guards the pendingMusigNonces.
608
        nonceMtx sync.RWMutex
609

610
        // pendingMusigNonces is used to store the musig2 nonce we generate to
611
        // send funding locked until we receive a funding locked message from
612
        // the remote party. We'll use this to keep track of the nonce we
613
        // generated, so we send the local+remote nonces to the peer state
614
        // machine.
615
        //
616
        // NOTE: This map is protected by the nonceMtx above.
617
        //
618
        // TODO(roasbeef): replace w/ generic concurrent map
619
        pendingMusigNonces map[lnwire.ChannelID]*musig2.Nonces
620

621
        // activeReservations is a map which houses the state of all pending
622
        // funding workflows.
623
        activeReservations map[serializedPubKey]pendingChannels
624

625
        // signedReservations is a utility map that maps the permanent channel
626
        // ID of a funding reservation to its temporary channel ID. This is
627
        // required as mid funding flow, we switch to referencing the channel
628
        // by its full channel ID once the commitment transactions have been
629
        // signed by both parties.
630
        signedReservations map[lnwire.ChannelID]PendingChanID
631

632
        // resMtx guards both of the maps above to ensure that all access is
633
        // goroutine safe.
634
        resMtx sync.RWMutex
635

636
        // fundingMsgs is a channel that relays fundingMsg structs from
637
        // external sub-systems using the ProcessFundingMsg call.
638
        fundingMsgs chan *fundingMsg
639

640
        // fundingRequests is a channel used to receive channel initiation
641
        // requests from a local subsystem within the daemon.
642
        fundingRequests chan *InitFundingMsg
643

644
        localDiscoverySignals *lnutils.SyncMap[lnwire.ChannelID, chan struct{}]
645

646
        handleChannelReadyBarriers *lnutils.SyncMap[lnwire.ChannelID, struct{}]
647

648
        quit chan struct{}
649
        wg   sync.WaitGroup
650
}
651

652
// channelOpeningState represents the different states a channel can be in
653
// between the funding transaction has been confirmed and the channel is
654
// announced to the network and ready to be used.
655
type channelOpeningState uint8
656

657
const (
658
        // markedOpen is the opening state of a channel if the funding
659
        // transaction is confirmed on-chain, but channelReady is not yet
660
        // successfully sent to the other peer.
661
        markedOpen channelOpeningState = iota
662

663
        // channelReadySent is the opening state of a channel if the
664
        // channelReady message has successfully been sent to the other peer,
665
        // but we still haven't announced the channel to the network.
666
        channelReadySent
667

668
        // addedToGraph is the opening state of a channel if the channel has
669
        // been successfully added to the graph immediately after the
670
        // channelReady message has been sent, but we still haven't announced
671
        // the channel to the network.
672
        addedToGraph
673
)
674

675
func (c channelOpeningState) String() string {
2✔
676
        switch c {
2✔
677
        case markedOpen:
2✔
678
                return "markedOpen"
2✔
679
        case channelReadySent:
2✔
680
                return "channelReadySent"
2✔
681
        case addedToGraph:
2✔
682
                return "addedToGraph"
2✔
683
        default:
×
684
                return "unknown"
×
685
        }
686
}
687

688
// NewFundingManager creates and initializes a new instance of the
689
// fundingManager.
690
func NewFundingManager(cfg Config) (*Manager, error) {
111✔
691
        return &Manager{
111✔
692
                cfg:       &cfg,
111✔
693
                chanIDKey: cfg.TempChanIDSeed,
111✔
694
                activeReservations: make(
111✔
695
                        map[serializedPubKey]pendingChannels,
111✔
696
                ),
111✔
697
                signedReservations: make(
111✔
698
                        map[lnwire.ChannelID][32]byte,
111✔
699
                ),
111✔
700
                fundingMsgs: make(
111✔
701
                        chan *fundingMsg, msgBufferSize,
111✔
702
                ),
111✔
703
                fundingRequests: make(
111✔
704
                        chan *InitFundingMsg, msgBufferSize,
111✔
705
                ),
111✔
706
                localDiscoverySignals: &lnutils.SyncMap[
111✔
707
                        lnwire.ChannelID, chan struct{},
111✔
708
                ]{},
111✔
709
                handleChannelReadyBarriers: &lnutils.SyncMap[
111✔
710
                        lnwire.ChannelID, struct{},
111✔
711
                ]{},
111✔
712
                pendingMusigNonces: make(
111✔
713
                        map[lnwire.ChannelID]*musig2.Nonces,
111✔
714
                ),
111✔
715
                quit: make(chan struct{}),
111✔
716
        }, nil
111✔
717
}
111✔
718

719
// Start launches all helper goroutines required for handling requests sent
720
// to the funding manager.
721
func (f *Manager) Start() error {
111✔
722
        var err error
111✔
723
        f.started.Do(func() {
222✔
724
                log.Info("Funding manager starting")
111✔
725
                err = f.start()
111✔
726
        })
111✔
727
        return err
111✔
728
}
729

730
func (f *Manager) start() error {
111✔
731
        // Upon restart, the Funding Manager will check the database to load any
111✔
732
        // channels that were  waiting for their funding transactions to be
111✔
733
        // confirmed on the blockchain at the time when the daemon last went
111✔
734
        // down.
111✔
735
        // TODO(roasbeef): store height that funding finished?
111✔
736
        //  * would then replace call below
111✔
737
        allChannels, err := f.cfg.ChannelDB.FetchAllChannels()
111✔
738
        if err != nil {
111✔
739
                return err
×
740
        }
×
741

742
        for _, channel := range allChannels {
122✔
743
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
11✔
744

11✔
745
                // For any channels that were in a pending state when the
11✔
746
                // daemon was last connected, the Funding Manager will
11✔
747
                // re-initialize the channel barriers, and republish the
11✔
748
                // funding transaction if we're the initiator.
11✔
749
                if channel.IsPending {
14✔
750
                        log.Tracef("Loading pending ChannelPoint(%v), "+
3✔
751
                                "creating chan barrier",
3✔
752
                                channel.FundingOutpoint)
3✔
753

3✔
754
                        f.localDiscoverySignals.Store(
3✔
755
                                chanID, make(chan struct{}),
3✔
756
                        )
3✔
757

3✔
758
                        // Rebroadcast the funding transaction for any pending
3✔
759
                        // channel that we initiated. No error will be returned
3✔
760
                        // if the transaction already has been broadcast.
3✔
761
                        chanType := channel.ChanType
3✔
762
                        if chanType.IsSingleFunder() &&
3✔
763
                                chanType.HasFundingTx() &&
3✔
764
                                channel.IsInitiator {
6✔
765

3✔
766
                                f.rebroadcastFundingTx(channel)
3✔
767
                        }
3✔
768
                } else if channel.ChanType.IsSingleFunder() &&
10✔
769
                        channel.ChanType.HasFundingTx() &&
10✔
770
                        channel.IsZeroConf() && channel.IsInitiator &&
10✔
771
                        !channel.ZeroConfConfirmed() {
12✔
772

2✔
773
                        // Rebroadcast the funding transaction for unconfirmed
2✔
774
                        // zero-conf channels if we have the funding tx and are
2✔
775
                        // also the initiator.
2✔
776
                        f.rebroadcastFundingTx(channel)
2✔
777
                }
2✔
778

779
                // We will restart the funding state machine for all channels,
780
                // which will wait for the channel's funding transaction to be
781
                // confirmed on the blockchain, and transmit the messages
782
                // necessary for the channel to be operational.
783
                f.wg.Add(1)
11✔
784
                go f.advanceFundingState(channel, chanID, nil)
11✔
785
        }
786

787
        f.wg.Add(1) // TODO(roasbeef): tune
111✔
788
        go f.reservationCoordinator()
111✔
789

111✔
790
        return nil
111✔
791
}
792

793
// Stop signals all helper goroutines to execute a graceful shutdown. This
794
// method will block until all goroutines have exited.
795
func (f *Manager) Stop() error {
108✔
796
        f.stopped.Do(func() {
215✔
797
                log.Info("Funding manager shutting down...")
107✔
798
                defer log.Debug("Funding manager shutdown complete")
107✔
799

107✔
800
                close(f.quit)
107✔
801
                f.wg.Wait()
107✔
802
        })
107✔
803

804
        return nil
108✔
805
}
806

807
// rebroadcastFundingTx publishes the funding tx on startup for each
808
// unconfirmed channel.
809
func (f *Manager) rebroadcastFundingTx(c *channeldb.OpenChannel) {
5✔
810
        var fundingTxBuf bytes.Buffer
5✔
811
        err := c.FundingTxn.Serialize(&fundingTxBuf)
5✔
812
        if err != nil {
5✔
813
                log.Errorf("Unable to serialize funding transaction %v: %v",
×
814
                        c.FundingTxn.TxHash(), err)
×
815

×
816
                // Clear the buffer of any bytes that were written before the
×
817
                // serialization error to prevent logging an incomplete
×
818
                // transaction.
×
819
                fundingTxBuf.Reset()
×
820
        } else {
5✔
821
                log.Debugf("Rebroadcasting funding tx for ChannelPoint(%v): "+
5✔
822
                        "%x", c.FundingOutpoint, fundingTxBuf.Bytes())
5✔
823
        }
5✔
824

825
        // Set a nil short channel ID at this stage because we do not know it
826
        // until our funding tx confirms.
827
        label := labels.MakeLabel(labels.LabelTypeChannelOpen, nil)
5✔
828

5✔
829
        err = f.cfg.PublishTransaction(c.FundingTxn, label)
5✔
830
        if err != nil {
5✔
831
                log.Errorf("Unable to rebroadcast funding tx %x for "+
×
832
                        "ChannelPoint(%v): %v", fundingTxBuf.Bytes(),
×
833
                        c.FundingOutpoint, err)
×
834
        }
×
835
}
836

837
// PendingChanID is a type that represents a pending channel ID. This might be
838
// selected by the caller, but if not, will be automatically selected.
839
type PendingChanID = [32]byte
840

841
// nextPendingChanID returns the next free pending channel ID to be used to
842
// identify a particular future channel funding workflow.
843
func (f *Manager) nextPendingChanID() PendingChanID {
59✔
844
        // Obtain a fresh nonce. We do this by encoding the incremented nonce.
59✔
845
        nextNonce := f.chanIDNonce.Add(1)
59✔
846

59✔
847
        var nonceBytes [8]byte
59✔
848
        binary.LittleEndian.PutUint64(nonceBytes[:], nextNonce)
59✔
849

59✔
850
        // We'll generate the next pending channelID by "encrypting" 32-bytes
59✔
851
        // of zeroes which'll extract 32 random bytes from our stream cipher.
59✔
852
        var (
59✔
853
                nextChanID PendingChanID
59✔
854
                zeroes     [32]byte
59✔
855
        )
59✔
856
        salsa20.XORKeyStream(
59✔
857
                nextChanID[:], zeroes[:], nonceBytes[:], &f.chanIDKey,
59✔
858
        )
59✔
859

59✔
860
        return nextChanID
59✔
861
}
59✔
862

863
// CancelPeerReservations cancels all active reservations associated with the
864
// passed node. This will ensure any outputs which have been pre committed,
865
// (and thus locked from coin selection), are properly freed.
866
func (f *Manager) CancelPeerReservations(nodePub [33]byte) {
2✔
867
        log.Debugf("Cancelling all reservations for peer %x", nodePub[:])
2✔
868

2✔
869
        f.resMtx.Lock()
2✔
870
        defer f.resMtx.Unlock()
2✔
871

2✔
872
        // We'll attempt to look up this node in the set of active
2✔
873
        // reservations.  If they don't have any, then there's no further work
2✔
874
        // to be done.
2✔
875
        nodeReservations, ok := f.activeReservations[nodePub]
2✔
876
        if !ok {
4✔
877
                log.Debugf("No active reservations for node: %x", nodePub[:])
2✔
878
                return
2✔
879
        }
2✔
880

881
        // If they do have any active reservations, then we'll cancel all of
882
        // them (which releases any locked UTXO's), and also delete it from the
883
        // reservation map.
884
        for pendingID, resCtx := range nodeReservations {
×
885
                if err := resCtx.reservation.Cancel(); err != nil {
×
886
                        log.Errorf("unable to cancel reservation for "+
×
887
                                "node=%x: %v", nodePub[:], err)
×
888
                }
×
889

890
                resCtx.err <- fmt.Errorf("peer disconnected")
×
891
                delete(nodeReservations, pendingID)
×
892
        }
893

894
        // Finally, we'll delete the node itself from the set of reservations.
895
        delete(f.activeReservations, nodePub)
×
896
}
897

898
// chanIdentifier wraps pending channel ID and channel ID into one struct so
899
// it's easier to identify a specific channel.
900
//
901
// TODO(yy): move to a different package to hide the private fields so direct
902
// access is disabled.
903
type chanIdentifier struct {
904
        // tempChanID is the pending channel ID created by the funder when
905
        // initializing the funding flow. For fundee, it's received from the
906
        // `open_channel` message.
907
        tempChanID lnwire.ChannelID
908

909
        // chanID is the channel ID created by the funder once the
910
        // `accept_channel` message is received. For fundee, it's received from
911
        // the `funding_created` message.
912
        chanID lnwire.ChannelID
913

914
        // chanIDSet is a boolean indicates whether the active channel ID is
915
        // set for this identifier. For zero conf channels, the `chanID` can be
916
        // all-zero, which is the same as the empty value of `ChannelID`. To
917
        // avoid the confusion, we use this boolean to explicitly signal
918
        // whether the `chanID` is set or not.
919
        chanIDSet bool
920
}
921

922
// newChanIdentifier creates a new chanIdentifier.
923
func newChanIdentifier(tempChanID lnwire.ChannelID) *chanIdentifier {
150✔
924
        return &chanIdentifier{
150✔
925
                tempChanID: tempChanID,
150✔
926
        }
150✔
927
}
150✔
928

929
// setChanID updates the `chanIdentifier` with the active channel ID.
930
func (c *chanIdentifier) setChanID(chanID lnwire.ChannelID) {
93✔
931
        c.chanID = chanID
93✔
932
        c.chanIDSet = true
93✔
933
}
93✔
934

935
// hasChanID returns true if the active channel ID has been set.
936
func (c *chanIdentifier) hasChanID() bool {
23✔
937
        return c.chanIDSet
23✔
938
}
23✔
939

940
// failFundingFlow will fail the active funding flow with the target peer,
941
// identified by its unique temporary channel ID. This method will send an
942
// error to the remote peer, and also remove the reservation from our set of
943
// pending reservations.
944
//
945
// TODO(roasbeef): if peer disconnects, and haven't yet broadcast funding
946
// transaction, then all reservations should be cleared.
947
func (f *Manager) failFundingFlow(peer lnpeer.Peer, cid *chanIdentifier,
948
        fundingErr error) {
23✔
949

23✔
950
        log.Debugf("Failing funding flow for pending_id=%v: %v",
23✔
951
                cid.tempChanID, fundingErr)
23✔
952

23✔
953
        // First, notify Brontide to remove the pending channel.
23✔
954
        //
23✔
955
        // NOTE: depending on where we fail the flow, we may not have the
23✔
956
        // active channel ID yet.
23✔
957
        if cid.hasChanID() {
30✔
958
                err := peer.RemovePendingChannel(cid.chanID)
7✔
959
                if err != nil {
7✔
960
                        log.Errorf("Unable to remove channel %v with peer %x: "+
×
961
                                "%v", cid,
×
962
                                peer.IdentityKey().SerializeCompressed(), err)
×
963
                }
×
964
        }
965

966
        ctx, err := f.cancelReservationCtx(
23✔
967
                peer.IdentityKey(), cid.tempChanID, false,
23✔
968
        )
23✔
969
        if err != nil {
34✔
970
                log.Errorf("unable to cancel reservation: %v", err)
11✔
971
        }
11✔
972

973
        // In case the case where the reservation existed, send the funding
974
        // error on the error channel.
975
        if ctx != nil {
37✔
976
                ctx.err <- fundingErr
14✔
977
        }
14✔
978

979
        // We only send the exact error if it is part of out whitelisted set of
980
        // errors (lnwire.FundingError or lnwallet.ReservationError).
981
        var msg lnwire.ErrorData
23✔
982
        switch e := fundingErr.(type) {
23✔
983
        // Let the actual error message be sent to the remote for the
984
        // whitelisted types.
985
        case lnwallet.ReservationError:
7✔
986
                msg = lnwire.ErrorData(e.Error())
7✔
987
        case lnwire.FundingError:
6✔
988
                msg = lnwire.ErrorData(e.Error())
6✔
989
        case chanacceptor.ChanAcceptError:
2✔
990
                msg = lnwire.ErrorData(e.Error())
2✔
991

992
        // For all other error types we just send a generic error.
993
        default:
14✔
994
                msg = lnwire.ErrorData("funding failed due to internal error")
14✔
995
        }
996

997
        errMsg := &lnwire.Error{
23✔
998
                ChanID: cid.tempChanID,
23✔
999
                Data:   msg,
23✔
1000
        }
23✔
1001

23✔
1002
        log.Debugf("Sending funding error to peer (%x): %v",
23✔
1003
                peer.IdentityKey().SerializeCompressed(),
23✔
1004
                lnutils.SpewLogClosure(errMsg))
23✔
1005

23✔
1006
        if err := peer.SendMessage(false, errMsg); err != nil {
23✔
UNCOV
1007
                log.Errorf("unable to send error message to peer %v", err)
×
UNCOV
1008
        }
×
1009
}
1010

1011
// sendWarning sends a new warning message to the target peer, targeting the
1012
// specified cid with the passed funding error.
1013
func (f *Manager) sendWarning(peer lnpeer.Peer, cid *chanIdentifier,
1014
        fundingErr error) {
×
1015

×
1016
        msg := fundingErr.Error()
×
1017

×
1018
        errMsg := &lnwire.Warning{
×
1019
                ChanID: cid.tempChanID,
×
1020
                Data:   lnwire.WarningData(msg),
×
1021
        }
×
1022

×
1023
        log.Debugf("Sending funding warning to peer (%x): %v",
×
1024
                peer.IdentityKey().SerializeCompressed(),
×
1025
                lnutils.SpewLogClosure(errMsg),
×
1026
        )
×
1027

×
1028
        if err := peer.SendMessage(false, errMsg); err != nil {
×
1029
                log.Errorf("unable to send error message to peer %v", err)
×
1030
        }
×
1031
}
1032

1033
// reservationCoordinator is the primary goroutine tasked with progressing the
1034
// funding workflow between the wallet, and any outside peers or local callers.
1035
//
1036
// NOTE: This MUST be run as a goroutine.
1037
func (f *Manager) reservationCoordinator() {
111✔
1038
        defer f.wg.Done()
111✔
1039

111✔
1040
        zombieSweepTicker := time.NewTicker(f.cfg.ZombieSweeperInterval)
111✔
1041
        defer zombieSweepTicker.Stop()
111✔
1042

111✔
1043
        for {
494✔
1044
                select {
383✔
1045
                case fmsg := <-f.fundingMsgs:
217✔
1046
                        switch msg := fmsg.msg.(type) {
217✔
1047
                        case *lnwire.OpenChannel:
56✔
1048
                                f.fundeeProcessOpenChannel(fmsg.peer, msg)
56✔
1049

1050
                        case *lnwire.AcceptChannel:
35✔
1051
                                f.funderProcessAcceptChannel(fmsg.peer, msg)
35✔
1052

1053
                        case *lnwire.FundingCreated:
30✔
1054
                                f.fundeeProcessFundingCreated(fmsg.peer, msg)
30✔
1055

1056
                        case *lnwire.FundingSigned:
30✔
1057
                                f.funderProcessFundingSigned(fmsg.peer, msg)
30✔
1058

1059
                        case *lnwire.ChannelReady:
30✔
1060
                                f.wg.Add(1)
30✔
1061
                                go f.handleChannelReady(fmsg.peer, msg)
30✔
1062

1063
                        case *lnwire.Warning:
44✔
1064
                                f.handleWarningMsg(fmsg.peer, msg)
44✔
1065

1066
                        case *lnwire.Error:
2✔
1067
                                f.handleErrorMsg(fmsg.peer, msg)
2✔
1068
                        }
1069
                case req := <-f.fundingRequests:
59✔
1070
                        f.handleInitFundingMsg(req)
59✔
1071

1072
                case <-zombieSweepTicker.C:
2✔
1073
                        f.pruneZombieReservations()
2✔
1074

1075
                case <-f.quit:
107✔
1076
                        return
107✔
1077
                }
1078
        }
1079
}
1080

1081
// advanceFundingState will advance the channel through the steps after the
1082
// funding transaction is broadcasted, up until the point where the channel is
1083
// ready for operation. This includes waiting for the funding transaction to
1084
// confirm, sending channel_ready to the peer, adding the channel to the graph,
1085
// and announcing the channel. The updateChan can be set non-nil to get
1086
// OpenStatusUpdates.
1087
//
1088
// NOTE: This MUST be run as a goroutine.
1089
func (f *Manager) advanceFundingState(channel *channeldb.OpenChannel,
1090
        pendingChanID PendingChanID,
1091
        updateChan chan<- *lnrpc.OpenStatusUpdate) {
67✔
1092

67✔
1093
        defer f.wg.Done()
67✔
1094

67✔
1095
        // If the channel is still pending we must wait for the funding
67✔
1096
        // transaction to confirm.
67✔
1097
        if channel.IsPending {
126✔
1098
                err := f.advancePendingChannelState(channel, pendingChanID)
59✔
1099
                if err != nil {
84✔
1100
                        log.Errorf("Unable to advance pending state of "+
25✔
1101
                                "ChannelPoint(%v): %v",
25✔
1102
                                channel.FundingOutpoint, err)
25✔
1103
                        return
25✔
1104
                }
25✔
1105
        }
1106

1107
        var chanOpts []lnwallet.ChannelOpt
44✔
1108
        f.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
86✔
1109
                chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
42✔
1110
        })
42✔
1111
        f.cfg.AuxSigner.WhenSome(func(s lnwallet.AuxSigner) {
86✔
1112
                chanOpts = append(chanOpts, lnwallet.WithAuxSigner(s))
42✔
1113
        })
42✔
1114
        f.cfg.AuxResolver.WhenSome(func(s lnwallet.AuxContractResolver) {
44✔
1115
                chanOpts = append(chanOpts, lnwallet.WithAuxResolver(s))
×
1116
        })
×
1117

1118
        // We create the state-machine object which wraps the database state.
1119
        lnChannel, err := lnwallet.NewLightningChannel(
44✔
1120
                nil, channel, nil, chanOpts...,
44✔
1121
        )
44✔
1122
        if err != nil {
44✔
1123
                log.Errorf("Unable to create LightningChannel(%v): %v",
×
1124
                        channel.FundingOutpoint, err)
×
1125
                return
×
1126
        }
×
1127

1128
        for {
194✔
1129
                channelState, shortChanID, err := f.getChannelOpeningState(
150✔
1130
                        &channel.FundingOutpoint,
150✔
1131
                )
150✔
1132
                if err == channeldb.ErrChannelNotFound {
177✔
1133
                        // Channel not in fundingManager's opening database,
27✔
1134
                        // meaning it was successfully announced to the
27✔
1135
                        // network.
27✔
1136
                        // TODO(halseth): could do graph consistency check
27✔
1137
                        // here, and re-add the edge if missing.
27✔
1138
                        log.Debugf("ChannelPoint(%v) with chan_id=%x not "+
27✔
1139
                                "found in opening database, assuming already "+
27✔
1140
                                "announced to the network",
27✔
1141
                                channel.FundingOutpoint, pendingChanID)
27✔
1142
                        return
27✔
1143
                } else if err != nil {
152✔
1144
                        log.Errorf("Unable to query database for "+
×
1145
                                "channel opening state(%v): %v",
×
1146
                                channel.FundingOutpoint, err)
×
1147
                        return
×
1148
                }
×
1149

1150
                // If we did find the channel in the opening state database, we
1151
                // have seen the funding transaction being confirmed, but there
1152
                // are still steps left of the setup procedure. We continue the
1153
                // procedure where we left off.
1154
                err = f.stateStep(
125✔
1155
                        channel, lnChannel, shortChanID, pendingChanID,
125✔
1156
                        channelState, updateChan,
125✔
1157
                )
125✔
1158
                if err != nil {
144✔
1159
                        log.Errorf("Unable to advance state(%v): %v",
19✔
1160
                                channel.FundingOutpoint, err)
19✔
1161
                        return
19✔
1162
                }
19✔
1163
        }
1164
}
1165

1166
// stateStep advances the confirmed channel one step in the funding state
1167
// machine. This method is synchronous and the new channel opening state will
1168
// have been written to the database when it successfully returns. The
1169
// updateChan can be set non-nil to get OpenStatusUpdates.
1170
func (f *Manager) stateStep(channel *channeldb.OpenChannel,
1171
        lnChannel *lnwallet.LightningChannel,
1172
        shortChanID *lnwire.ShortChannelID, pendingChanID PendingChanID,
1173
        channelState channelOpeningState,
1174
        updateChan chan<- *lnrpc.OpenStatusUpdate) error {
125✔
1175

125✔
1176
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
125✔
1177
        log.Debugf("Channel(%v) with ShortChanID %v has opening state %v",
125✔
1178
                chanID, shortChanID, channelState)
125✔
1179

125✔
1180
        switch channelState {
125✔
1181
        // The funding transaction was confirmed, but we did not successfully
1182
        // send the channelReady message to the peer, so let's do that now.
1183
        case markedOpen:
37✔
1184
                err := f.sendChannelReady(channel, lnChannel)
37✔
1185
                if err != nil {
38✔
1186
                        return fmt.Errorf("failed sending channelReady: %w",
1✔
1187
                                err)
1✔
1188
                }
1✔
1189

1190
                // As the channelReady message is now sent to the peer, the
1191
                // channel is moved to the next state of the state machine. It
1192
                // will be moved to the last state (actually deleted from the
1193
                // database) after the channel is finally announced.
1194
                err = f.saveChannelOpeningState(
36✔
1195
                        &channel.FundingOutpoint, channelReadySent,
36✔
1196
                        shortChanID,
36✔
1197
                )
36✔
1198
                if err != nil {
36✔
1199
                        return fmt.Errorf("error setting channel state to"+
×
1200
                                " channelReadySent: %w", err)
×
1201
                }
×
1202

1203
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
36✔
1204
                        "sent ChannelReady", chanID, shortChanID)
36✔
1205

36✔
1206
                return nil
36✔
1207

1208
        // channelReady was sent to peer, but the channel was not added to the
1209
        // graph and the channel announcement was not sent.
1210
        case channelReadySent:
62✔
1211
                // We must wait until we've received the peer's channel_ready
62✔
1212
                // before sending a channel_update according to BOLT#07.
62✔
1213
                received, err := f.receivedChannelReady(
62✔
1214
                        channel.IdentityPub, chanID,
62✔
1215
                )
62✔
1216
                if err != nil {
62✔
UNCOV
1217
                        return fmt.Errorf("failed to check if channel_ready "+
×
UNCOV
1218
                                "was received: %v", err)
×
UNCOV
1219
                }
×
1220

1221
                if !received {
100✔
1222
                        // We haven't received ChannelReady, so we'll continue
38✔
1223
                        // to the next iteration of the loop after sleeping for
38✔
1224
                        // checkPeerChannelReadyInterval.
38✔
1225
                        select {
38✔
1226
                        case <-time.After(checkPeerChannelReadyInterval):
26✔
1227
                        case <-f.quit:
14✔
1228
                                return ErrFundingManagerShuttingDown
14✔
1229
                        }
1230

1231
                        return nil
26✔
1232
                }
1233

1234
                return f.handleChannelReadyReceived(
26✔
1235
                        channel, shortChanID, pendingChanID, updateChan,
26✔
1236
                )
26✔
1237

1238
        // The channel was added to the Router's topology, but the channel
1239
        // announcement was not sent.
1240
        case addedToGraph:
30✔
1241
                if channel.IsZeroConf() {
38✔
1242
                        // If this is a zero-conf channel, then we will wait
8✔
1243
                        // for it to be confirmed before announcing it to the
8✔
1244
                        // greater network.
8✔
1245
                        err := f.waitForZeroConfChannel(channel)
8✔
1246
                        if err != nil {
12✔
1247
                                return fmt.Errorf("failed waiting for zero "+
4✔
1248
                                        "channel: %v", err)
4✔
1249
                        }
4✔
1250

1251
                        // Update the local shortChanID variable such that
1252
                        // annAfterSixConfs uses the confirmed SCID.
1253
                        confirmedScid := channel.ZeroConfRealScid()
6✔
1254
                        shortChanID = &confirmedScid
6✔
1255
                }
1256

1257
                err := f.annAfterSixConfs(channel, shortChanID)
28✔
1258
                if err != nil {
32✔
1259
                        return fmt.Errorf("error sending channel "+
4✔
1260
                                "announcement: %v", err)
4✔
1261
                }
4✔
1262

1263
                // We delete the channel opening state from our internal
1264
                // database as the opening process has succeeded. We can do
1265
                // this because we assume the AuthenticatedGossiper queues the
1266
                // announcement messages, and persists them in case of a daemon
1267
                // shutdown.
1268
                err = f.deleteChannelOpeningState(&channel.FundingOutpoint)
26✔
1269
                if err != nil {
26✔
1270
                        return fmt.Errorf("error deleting channel state: %w",
×
1271
                                err)
×
1272
                }
×
1273

1274
                // After the fee parameters have been stored in the
1275
                // announcement we can delete them from the database. For
1276
                // private channels we do not announce the channel policy to
1277
                // the network but still need to delete them from the database.
1278
                err = f.deleteInitialForwardingPolicy(chanID)
26✔
1279
                if err != nil {
26✔
1280
                        log.Infof("Could not delete initial policy for chanId "+
×
1281
                                "%x", chanID)
×
1282
                }
×
1283

1284
                log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
26✔
1285
                        "announced", chanID, shortChanID)
26✔
1286

26✔
1287
                return nil
26✔
1288
        }
1289

1290
        return fmt.Errorf("undefined channelState: %v", channelState)
×
1291
}
1292

1293
// advancePendingChannelState waits for a pending channel's funding tx to
1294
// confirm, and marks it open in the database when that happens.
1295
func (f *Manager) advancePendingChannelState(channel *channeldb.OpenChannel,
1296
        pendingChanID PendingChanID) error {
59✔
1297

59✔
1298
        if channel.IsZeroConf() {
65✔
1299
                // Persist the alias to the alias database.
6✔
1300
                baseScid := channel.ShortChannelID
6✔
1301
                err := f.cfg.AliasManager.AddLocalAlias(
6✔
1302
                        baseScid, baseScid, true, false,
6✔
1303
                )
6✔
1304
                if err != nil {
6✔
1305
                        return fmt.Errorf("error adding local alias to "+
×
1306
                                "store: %v", err)
×
1307
                }
×
1308

1309
                // We don't wait for zero-conf channels to be confirmed and
1310
                // instead immediately proceed with the rest of the funding
1311
                // flow. The channel opening state is stored under the alias
1312
                // SCID.
1313
                err = f.saveChannelOpeningState(
6✔
1314
                        &channel.FundingOutpoint, markedOpen,
6✔
1315
                        &channel.ShortChannelID,
6✔
1316
                )
6✔
1317
                if err != nil {
6✔
1318
                        return fmt.Errorf("error setting zero-conf channel "+
×
1319
                                "state to markedOpen: %v", err)
×
1320
                }
×
1321

1322
                // The ShortChannelID is already set since it's an alias, but
1323
                // we still need to mark the channel as no longer pending.
1324
                err = channel.MarkAsOpen(channel.ShortChannelID)
6✔
1325
                if err != nil {
6✔
1326
                        return fmt.Errorf("error setting zero-conf channel's "+
×
1327
                                "pending flag to false: %v", err)
×
1328
                }
×
1329

1330
                // Inform the ChannelNotifier that the channel has transitioned
1331
                // from pending open to open.
1332
                f.cfg.NotifyOpenChannelEvent(
6✔
1333
                        channel.FundingOutpoint, channel.IdentityPub,
6✔
1334
                )
6✔
1335

6✔
1336
                // Find and close the discoverySignal for this channel such
6✔
1337
                // that ChannelReady messages will be processed.
6✔
1338
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
6✔
1339
                discoverySignal, ok := f.localDiscoverySignals.Load(chanID)
6✔
1340
                if ok {
12✔
1341
                        close(discoverySignal)
6✔
1342
                }
6✔
1343

1344
                return nil
6✔
1345
        }
1346

1347
        confChannel, err := f.waitForFundingWithTimeout(channel)
55✔
1348
        if err == ErrConfirmationTimeout {
59✔
1349
                return f.fundingTimeout(channel, pendingChanID)
4✔
1350
        } else if err != nil {
80✔
1351
                return fmt.Errorf("error waiting for funding "+
23✔
1352
                        "confirmation for ChannelPoint(%v): %v",
23✔
1353
                        channel.FundingOutpoint, err)
23✔
1354
        }
23✔
1355

1356
        if blockchain.IsCoinBaseTx(confChannel.fundingTx) {
34✔
1357
                // If it's a coinbase transaction, we need to wait for it to
2✔
1358
                // mature. We wait out an additional MinAcceptDepth on top of
2✔
1359
                // the coinbase maturity as an extra margin of safety.
2✔
1360
                maturity := f.cfg.Wallet.Cfg.NetParams.CoinbaseMaturity
2✔
1361
                numCoinbaseConfs := uint32(maturity)
2✔
1362

2✔
1363
                if channel.NumConfsRequired > maturity {
2✔
1364
                        numCoinbaseConfs = uint32(channel.NumConfsRequired)
×
1365
                }
×
1366

1367
                txid := &channel.FundingOutpoint.Hash
2✔
1368
                fundingScript, err := MakeFundingScript(channel)
2✔
1369
                if err != nil {
2✔
1370
                        log.Errorf("unable to create funding script for "+
×
1371
                                "ChannelPoint(%v): %v",
×
1372
                                channel.FundingOutpoint, err)
×
1373

×
1374
                        return err
×
1375
                }
×
1376

1377
                confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
2✔
1378
                        txid, fundingScript, numCoinbaseConfs,
2✔
1379
                        channel.BroadcastHeight(),
2✔
1380
                )
2✔
1381
                if err != nil {
2✔
1382
                        log.Errorf("Unable to register for confirmation of "+
×
1383
                                "ChannelPoint(%v): %v",
×
1384
                                channel.FundingOutpoint, err)
×
1385

×
1386
                        return err
×
1387
                }
×
1388

1389
                select {
2✔
1390
                case _, ok := <-confNtfn.Confirmed:
2✔
1391
                        if !ok {
2✔
1392
                                return fmt.Errorf("ChainNotifier shutting "+
×
1393
                                        "down, can't complete funding flow "+
×
1394
                                        "for ChannelPoint(%v)",
×
1395
                                        channel.FundingOutpoint)
×
1396
                        }
×
1397

1398
                case <-f.quit:
×
1399
                        return ErrFundingManagerShuttingDown
×
1400
                }
1401
        }
1402

1403
        // Success, funding transaction was confirmed.
1404
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
32✔
1405
        log.Debugf("ChannelID(%v) is now fully confirmed! "+
32✔
1406
                "(shortChanID=%v)", chanID, confChannel.shortChanID)
32✔
1407

32✔
1408
        err = f.handleFundingConfirmation(channel, confChannel)
32✔
1409
        if err != nil {
32✔
1410
                return fmt.Errorf("unable to handle funding "+
×
1411
                        "confirmation for ChannelPoint(%v): %v",
×
1412
                        channel.FundingOutpoint, err)
×
1413
        }
×
1414

1415
        return nil
32✔
1416
}
1417

1418
// ProcessFundingMsg sends a message to the internal fundingManager goroutine,
1419
// allowing it to handle the lnwire.Message.
1420
func (f *Manager) ProcessFundingMsg(msg lnwire.Message, peer lnpeer.Peer) {
218✔
1421
        select {
218✔
1422
        case f.fundingMsgs <- &fundingMsg{msg, peer}:
218✔
1423
        case <-f.quit:
×
1424
                return
×
1425
        }
1426
}
1427

1428
// fundeeProcessOpenChannel creates an initial 'ChannelReservation' within the
1429
// wallet, then responds to the source peer with an accept channel message
1430
// progressing the funding workflow.
1431
//
1432
// TODO(roasbeef): add error chan to all, let channelManager handle
1433
// error+propagate.
1434
//
1435
//nolint:funlen
1436
func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
1437
        msg *lnwire.OpenChannel) {
56✔
1438

56✔
1439
        // Check number of pending channels to be smaller than maximum allowed
56✔
1440
        // number and send ErrorGeneric to remote peer if condition is
56✔
1441
        // violated.
56✔
1442
        peerPubKey := peer.IdentityKey()
56✔
1443
        peerIDKey := newSerializedKey(peerPubKey)
56✔
1444

56✔
1445
        amt := msg.FundingAmount
56✔
1446

56✔
1447
        // We get all pending channels for this peer. This is the list of the
56✔
1448
        // active reservations and the channels pending open in the database.
56✔
1449
        f.resMtx.RLock()
56✔
1450
        reservations := f.activeReservations[peerIDKey]
56✔
1451

56✔
1452
        // We don't count reservations that were created from a canned funding
56✔
1453
        // shim. The user has registered the shim and therefore expects this
56✔
1454
        // channel to arrive.
56✔
1455
        numPending := 0
56✔
1456
        for _, res := range reservations {
68✔
1457
                if !res.reservation.IsCannedShim() {
24✔
1458
                        numPending++
12✔
1459
                }
12✔
1460
        }
1461
        f.resMtx.RUnlock()
56✔
1462

56✔
1463
        // Create the channel identifier.
56✔
1464
        cid := newChanIdentifier(msg.PendingChannelID)
56✔
1465

56✔
1466
        // Also count the channels that are already pending. There we don't know
56✔
1467
        // the underlying intent anymore, unfortunately.
56✔
1468
        channels, err := f.cfg.ChannelDB.FetchOpenChannels(peerPubKey)
56✔
1469
        if err != nil {
56✔
1470
                f.failFundingFlow(peer, cid, err)
×
1471
                return
×
1472
        }
×
1473

1474
        for _, c := range channels {
70✔
1475
                // Pending channels that have a non-zero thaw height were also
14✔
1476
                // created through a canned funding shim. Those also don't
14✔
1477
                // count towards the DoS protection limit.
14✔
1478
                //
14✔
1479
                // TODO(guggero): Properly store the funding type (wallet, shim,
14✔
1480
                // PSBT) on the channel so we don't need to use the thaw height.
14✔
1481
                if c.IsPending && c.ThawHeight == 0 {
24✔
1482
                        numPending++
10✔
1483
                }
10✔
1484
        }
1485

1486
        // TODO(roasbeef): modify to only accept a _single_ pending channel per
1487
        // block unless white listed
1488
        if numPending >= f.cfg.MaxPendingChannels {
62✔
1489
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
6✔
1490

6✔
1491
                return
6✔
1492
        }
6✔
1493

1494
        // Ensure that the pendingChansLimit is respected.
1495
        pendingChans, err := f.cfg.ChannelDB.FetchPendingChannels()
52✔
1496
        if err != nil {
52✔
1497
                f.failFundingFlow(peer, cid, err)
×
1498
                return
×
1499
        }
×
1500

1501
        if len(pendingChans) > pendingChansLimit {
52✔
1502
                f.failFundingFlow(peer, cid, lnwire.ErrMaxPendingChannels)
×
1503
                return
×
1504
        }
×
1505

1506
        // We'll also reject any requests to create channels until we're fully
1507
        // synced to the network as we won't be able to properly validate the
1508
        // confirmation of the funding transaction.
1509
        isSynced, _, err := f.cfg.Wallet.IsSynced()
52✔
1510
        if err != nil || !isSynced {
52✔
1511
                if err != nil {
×
1512
                        log.Errorf("unable to query wallet: %v", err)
×
1513
                }
×
1514
                err := errors.New("Synchronizing blockchain")
×
1515
                f.failFundingFlow(peer, cid, err)
×
1516
                return
×
1517
        }
1518

1519
        // Ensure that the remote party respects our maximum channel size.
1520
        if amt > f.cfg.MaxChanSize {
56✔
1521
                f.failFundingFlow(
4✔
1522
                        peer, cid,
4✔
1523
                        lnwallet.ErrChanTooLarge(amt, f.cfg.MaxChanSize),
4✔
1524
                )
4✔
1525
                return
4✔
1526
        }
4✔
1527

1528
        // We'll, also ensure that the remote party isn't attempting to propose
1529
        // a channel that's below our current min channel size.
1530
        if amt < f.cfg.MinChanSize {
52✔
1531
                f.failFundingFlow(
2✔
1532
                        peer, cid,
2✔
1533
                        lnwallet.ErrChanTooSmall(amt, f.cfg.MinChanSize),
2✔
1534
                )
2✔
1535
                return
2✔
1536
        }
2✔
1537

1538
        // If request specifies non-zero push amount and 'rejectpush' is set,
1539
        // signal an error.
1540
        if f.cfg.RejectPush && msg.PushAmount > 0 {
51✔
1541
                f.failFundingFlow(peer, cid, lnwallet.ErrNonZeroPushAmount())
1✔
1542
                return
1✔
1543
        }
1✔
1544

1545
        // Send the OpenChannel request to the ChannelAcceptor to determine
1546
        // whether this node will accept the channel.
1547
        chanReq := &chanacceptor.ChannelAcceptRequest{
49✔
1548
                Node:        peer.IdentityKey(),
49✔
1549
                OpenChanMsg: msg,
49✔
1550
        }
49✔
1551

49✔
1552
        // Query our channel acceptor to determine whether we should reject
49✔
1553
        // the channel.
49✔
1554
        acceptorResp := f.cfg.OpenChannelPredicate.Accept(chanReq)
49✔
1555
        if acceptorResp.RejectChannel() {
51✔
1556
                f.failFundingFlow(peer, cid, acceptorResp.ChanAcceptError)
2✔
1557
                return
2✔
1558
        }
2✔
1559

1560
        log.Infof("Recv'd fundingRequest(amt=%v, push=%v, delay=%v, "+
49✔
1561
                "pendingId=%x) from peer(%x)", amt, msg.PushAmount,
49✔
1562
                msg.CsvDelay, msg.PendingChannelID,
49✔
1563
                peer.IdentityKey().SerializeCompressed())
49✔
1564

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

1586
        var scidFeatureVal bool
49✔
1587
        if hasFeatures(
49✔
1588
                peer.LocalFeatures(), peer.RemoteFeatures(),
49✔
1589
                lnwire.ScidAliasOptional,
49✔
1590
        ) {
54✔
1591

5✔
1592
                scidFeatureVal = true
5✔
1593
        }
5✔
1594

1595
        var (
49✔
1596
                zeroConf bool
49✔
1597
                scid     bool
49✔
1598
        )
49✔
1599

49✔
1600
        // Only echo back a channel type in AcceptChannel if we actually used
49✔
1601
        // explicit negotiation above.
49✔
1602
        if chanType != nil {
55✔
1603
                // Check if the channel type includes the zero-conf or
6✔
1604
                // scid-alias bits.
6✔
1605
                featureVec := lnwire.RawFeatureVector(*chanType)
6✔
1606
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
6✔
1607
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
6✔
1608

6✔
1609
                // If the zero-conf channel type was negotiated, ensure that
6✔
1610
                // the acceptor allows it.
6✔
1611
                if zeroConf && !acceptorResp.ZeroConf {
6✔
1612
                        // Fail the funding flow.
×
1613
                        flowErr := fmt.Errorf("channel acceptor blocked " +
×
1614
                                "zero-conf channel negotiation")
×
1615
                        log.Errorf("Cancelling funding flow for %v based on "+
×
1616
                                "channel acceptor response: %v", cid, flowErr)
×
1617
                        f.failFundingFlow(peer, cid, flowErr)
×
1618
                        return
×
1619
                }
×
1620

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

1638
                        // Set zeroConf to true to enable the zero-conf flow.
1639
                        zeroConf = true
×
1640
                }
1641
        }
1642

1643
        public := msg.ChannelFlags&lnwire.FFAnnounceChannel != 0
49✔
1644
        switch {
49✔
1645
        // Sending the option-scid-alias channel type for a public channel is
1646
        // disallowed.
1647
        case public && scid:
×
1648
                err = fmt.Errorf("option-scid-alias chantype for public " +
×
1649
                        "channel")
×
1650
                log.Errorf("Cancelling funding flow for public channel %v "+
×
1651
                        "with scid-alias: %v", cid, err)
×
1652
                f.failFundingFlow(peer, cid, err)
×
1653

×
1654
                return
×
1655

1656
        // The current variant of taproot channels can only be used with
1657
        // unadvertised channels for now.
1658
        case commitType.IsTaproot() && public:
×
1659
                err = fmt.Errorf("taproot channel type for public channel")
×
1660
                log.Errorf("Cancelling funding flow for public taproot "+
×
1661
                        "channel %v: %v", cid, err)
×
1662
                f.failFundingFlow(peer, cid, err)
×
1663

×
1664
                return
×
1665
        }
1666

1667
        // At this point, if we have an AuxFundingController active, we'll
1668
        // check to see if we have a special tapscript root to use in our
1669
        // MuSig funding output.
1670
        tapscriptRoot, err := fn.MapOptionZ(
49✔
1671
                f.cfg.AuxFundingController,
49✔
1672
                func(c AuxFundingController) AuxTapscriptResult {
49✔
1673
                        return c.DeriveTapscriptRoot(msg.PendingChannelID)
×
1674
                },
×
1675
        ).Unpack()
1676
        if err != nil {
49✔
1677
                err = fmt.Errorf("error deriving tapscript root: %w", err)
×
1678
                log.Error(err)
×
1679
                f.failFundingFlow(peer, cid, err)
×
1680

×
1681
                return
×
1682
        }
×
1683

1684
        req := &lnwallet.InitFundingReserveMsg{
49✔
1685
                ChainHash:        &msg.ChainHash,
49✔
1686
                PendingChanID:    msg.PendingChannelID,
49✔
1687
                NodeID:           peer.IdentityKey(),
49✔
1688
                NodeAddr:         peer.Address(),
49✔
1689
                LocalFundingAmt:  0,
49✔
1690
                RemoteFundingAmt: amt,
49✔
1691
                CommitFeePerKw:   chainfee.SatPerKWeight(msg.FeePerKiloWeight),
49✔
1692
                FundingFeePerKw:  0,
49✔
1693
                PushMSat:         msg.PushAmount,
49✔
1694
                Flags:            msg.ChannelFlags,
49✔
1695
                MinConfs:         1,
49✔
1696
                CommitType:       commitType,
49✔
1697
                ZeroConf:         zeroConf,
49✔
1698
                OptionScidAlias:  scid,
49✔
1699
                ScidAliasFeature: scidFeatureVal,
49✔
1700
                TapscriptRoot:    tapscriptRoot,
49✔
1701
        }
49✔
1702

49✔
1703
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
49✔
1704
        if err != nil {
49✔
1705
                log.Errorf("Unable to initialize reservation: %v", err)
×
1706
                f.failFundingFlow(peer, cid, err)
×
1707
                return
×
1708
        }
×
1709

1710
        log.Debugf("Initialized channel reservation: zeroConf=%v, psbt=%v, "+
49✔
1711
                "cannedShim=%v", reservation.IsZeroConf(),
49✔
1712
                reservation.IsPsbt(), reservation.IsCannedShim())
49✔
1713

49✔
1714
        if zeroConf {
53✔
1715
                // Store an alias for zero-conf channels. Other option-scid
4✔
1716
                // channels will do this at a later point.
4✔
1717
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
4✔
1718
                if err != nil {
4✔
1719
                        log.Errorf("Unable to request alias: %v", err)
×
1720
                        f.failFundingFlow(peer, cid, err)
×
1721
                        return
×
1722
                }
×
1723

1724
                reservation.AddAlias(aliasScid)
4✔
1725
        }
1726

1727
        // As we're the responder, we get to specify the number of confirmations
1728
        // that we require before both of us consider the channel open. We'll
1729
        // use our mapping to derive the proper number of confirmations based on
1730
        // the amount of the channel, and also if any funds are being pushed to
1731
        // us. If a depth value was set by our channel acceptor, we will use
1732
        // that value instead.
1733
        numConfsReq := f.cfg.NumRequiredConfs(msg.FundingAmount, msg.PushAmount)
49✔
1734
        if acceptorResp.MinAcceptDepth != 0 {
49✔
1735
                numConfsReq = acceptorResp.MinAcceptDepth
×
1736
        }
×
1737

1738
        // We'll ignore the min_depth calculated above if this is a zero-conf
1739
        // channel.
1740
        if zeroConf {
53✔
1741
                numConfsReq = 0
4✔
1742
        }
4✔
1743

1744
        reservation.SetNumConfsRequired(numConfsReq)
49✔
1745

49✔
1746
        // We'll also validate and apply all the constraints the initiating
49✔
1747
        // party is attempting to dictate for our commitment transaction.
49✔
1748
        stateBounds := &channeldb.ChannelStateBounds{
49✔
1749
                ChanReserve:      msg.ChannelReserve,
49✔
1750
                MaxPendingAmount: msg.MaxValueInFlight,
49✔
1751
                MinHTLC:          msg.HtlcMinimum,
49✔
1752
                MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs,
49✔
1753
        }
49✔
1754
        commitParams := &channeldb.CommitmentParams{
49✔
1755
                DustLimit: msg.DustLimit,
49✔
1756
                CsvDelay:  msg.CsvDelay,
49✔
1757
        }
49✔
1758
        err = reservation.CommitConstraints(
49✔
1759
                stateBounds, commitParams, f.cfg.MaxLocalCSVDelay, true,
49✔
1760
        )
49✔
1761
        if err != nil {
49✔
UNCOV
1762
                log.Errorf("Unacceptable channel constraints: %v", err)
×
UNCOV
1763
                f.failFundingFlow(peer, cid, err)
×
UNCOV
1764
                return
×
UNCOV
1765
        }
×
1766

1767
        // If the fundee didn't provide an upfront-shutdown address via
1768
        // the channel acceptor, fall back to the configured shutdown
1769
        // script (if any).
1770
        shutdownScript := acceptorResp.UpfrontShutdown
49✔
1771
        if len(shutdownScript) == 0 {
98✔
1772
                f.cfg.ShutdownScript.WhenSome(
49✔
1773
                        func(script lnwire.DeliveryAddress) {
51✔
1774
                                shutdownScript = script
2✔
1775
                        },
2✔
1776
                )
1777
        }
1778

1779
        // Check whether the peer supports upfront shutdown, and get a new
1780
        // wallet address if our node is configured to set shutdown addresses by
1781
        // default. We use the upfront shutdown script provided by our channel
1782
        // acceptor (if any) in lieu of user input.
1783
        shutdown, err := getUpfrontShutdownScript(
49✔
1784
                f.cfg.EnableUpfrontShutdown, peer, shutdownScript,
49✔
1785
                f.selectShutdownScript,
49✔
1786
        )
49✔
1787
        if err != nil {
49✔
1788
                f.failFundingFlow(
×
1789
                        peer, cid,
×
1790
                        fmt.Errorf("getUpfrontShutdownScript error: %w", err),
×
1791
                )
×
1792
                return
×
1793
        }
×
1794
        reservation.SetOurUpfrontShutdown(shutdown)
49✔
1795

49✔
1796
        // If a script enforced channel lease is being proposed, we'll need to
49✔
1797
        // validate its custom TLV records.
49✔
1798
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
51✔
1799
                if msg.LeaseExpiry == nil {
2✔
1800
                        err := errors.New("missing lease expiry")
×
1801
                        f.failFundingFlow(peer, cid, err)
×
1802
                        return
×
1803
                }
×
1804

1805
                // If we had a shim registered for this channel prior to
1806
                // receiving its corresponding OpenChannel message, then we'll
1807
                // validate the proposed LeaseExpiry against what was registered
1808
                // in our shim.
1809
                if reservation.LeaseExpiry() != 0 {
4✔
1810
                        if uint32(*msg.LeaseExpiry) !=
2✔
1811
                                reservation.LeaseExpiry() {
2✔
1812

×
1813
                                err := errors.New("lease expiry mismatch")
×
1814
                                f.failFundingFlow(peer, cid, err)
×
1815
                                return
×
1816
                        }
×
1817
                }
1818
        }
1819

1820
        log.Infof("Requiring %v confirmations for pendingChan(%x): "+
49✔
1821
                "amt=%v, push_amt=%v, committype=%v, upfrontShutdown=%x",
49✔
1822
                numConfsReq, msg.PendingChannelID, amt, msg.PushAmount,
49✔
1823
                commitType, msg.UpfrontShutdownScript)
49✔
1824

49✔
1825
        // Generate our required constraints for the remote party, using the
49✔
1826
        // values provided by the channel acceptor if they are non-zero.
49✔
1827
        remoteCsvDelay := f.cfg.RequiredRemoteDelay(amt)
49✔
1828
        if acceptorResp.CSVDelay != 0 {
49✔
1829
                remoteCsvDelay = acceptorResp.CSVDelay
×
1830
        }
×
1831

1832
        // If our default dust limit was above their ChannelReserve, we change
1833
        // it to the ChannelReserve. We must make sure the ChannelReserve we
1834
        // send in the AcceptChannel message is above both dust limits.
1835
        // Therefore, take the maximum of msg.DustLimit and our dust limit.
1836
        //
1837
        // NOTE: Even with this bounding, the ChannelAcceptor may return an
1838
        // BOLT#02-invalid ChannelReserve.
1839
        maxDustLimit := reservation.OurContribution().DustLimit
49✔
1840
        if msg.DustLimit > maxDustLimit {
49✔
1841
                maxDustLimit = msg.DustLimit
×
1842
        }
×
1843

1844
        chanReserve := f.cfg.RequiredRemoteChanReserve(amt, maxDustLimit)
49✔
1845
        if acceptorResp.Reserve != 0 {
49✔
1846
                chanReserve = acceptorResp.Reserve
×
1847
        }
×
1848

1849
        remoteMaxValue := f.cfg.RequiredRemoteMaxValue(amt)
49✔
1850
        if acceptorResp.InFlightTotal != 0 {
49✔
1851
                remoteMaxValue = acceptorResp.InFlightTotal
×
1852
        }
×
1853

1854
        maxHtlcs := f.cfg.RequiredRemoteMaxHTLCs(amt)
49✔
1855
        if acceptorResp.HtlcLimit != 0 {
49✔
1856
                maxHtlcs = acceptorResp.HtlcLimit
×
1857
        }
×
1858

1859
        // Default to our default minimum hltc value, replacing it with the
1860
        // channel acceptor's value if it is set.
1861
        minHtlc := f.cfg.DefaultMinHtlcIn
49✔
1862
        if acceptorResp.MinHtlcIn != 0 {
49✔
1863
                minHtlc = acceptorResp.MinHtlcIn
×
1864
        }
×
1865

1866
        // If we are handling a FundingOpen request then we need to specify the
1867
        // default channel fees since they are not provided by the responder
1868
        // interactively.
1869
        ourContribution := reservation.OurContribution()
49✔
1870
        forwardingPolicy := f.defaultForwardingPolicy(
49✔
1871
                ourContribution.ChannelStateBounds,
49✔
1872
        )
49✔
1873

49✔
1874
        // Once the reservation has been created successfully, we add it to
49✔
1875
        // this peer's map of pending reservations to track this particular
49✔
1876
        // reservation until either abort or completion.
49✔
1877
        f.resMtx.Lock()
49✔
1878
        if _, ok := f.activeReservations[peerIDKey]; !ok {
94✔
1879
                f.activeReservations[peerIDKey] = make(pendingChannels)
45✔
1880
        }
45✔
1881
        resCtx := &reservationWithCtx{
49✔
1882
                reservation:       reservation,
49✔
1883
                chanAmt:           amt,
49✔
1884
                forwardingPolicy:  *forwardingPolicy,
49✔
1885
                remoteCsvDelay:    remoteCsvDelay,
49✔
1886
                remoteMinHtlc:     minHtlc,
49✔
1887
                remoteMaxValue:    remoteMaxValue,
49✔
1888
                remoteMaxHtlcs:    maxHtlcs,
49✔
1889
                remoteChanReserve: chanReserve,
49✔
1890
                maxLocalCsv:       f.cfg.MaxLocalCSVDelay,
49✔
1891
                channelType:       chanType,
49✔
1892
                err:               make(chan error, 1),
49✔
1893
                peer:              peer,
49✔
1894
        }
49✔
1895
        f.activeReservations[peerIDKey][msg.PendingChannelID] = resCtx
49✔
1896
        f.resMtx.Unlock()
49✔
1897

49✔
1898
        // Update the timestamp once the fundingOpenMsg has been handled.
49✔
1899
        defer resCtx.updateTimestamp()
49✔
1900

49✔
1901
        cfg := channeldb.ChannelConfig{
49✔
1902
                ChannelStateBounds: channeldb.ChannelStateBounds{
49✔
1903
                        MaxPendingAmount: remoteMaxValue,
49✔
1904
                        ChanReserve:      chanReserve,
49✔
1905
                        MinHTLC:          minHtlc,
49✔
1906
                        MaxAcceptedHtlcs: maxHtlcs,
49✔
1907
                },
49✔
1908
                CommitmentParams: channeldb.CommitmentParams{
49✔
1909
                        DustLimit: msg.DustLimit,
49✔
1910
                        CsvDelay:  remoteCsvDelay,
49✔
1911
                },
49✔
1912
                MultiSigKey: keychain.KeyDescriptor{
49✔
1913
                        PubKey: copyPubKey(msg.FundingKey),
49✔
1914
                },
49✔
1915
                RevocationBasePoint: keychain.KeyDescriptor{
49✔
1916
                        PubKey: copyPubKey(msg.RevocationPoint),
49✔
1917
                },
49✔
1918
                PaymentBasePoint: keychain.KeyDescriptor{
49✔
1919
                        PubKey: copyPubKey(msg.PaymentPoint),
49✔
1920
                },
49✔
1921
                DelayBasePoint: keychain.KeyDescriptor{
49✔
1922
                        PubKey: copyPubKey(msg.DelayedPaymentPoint),
49✔
1923
                },
49✔
1924
                HtlcBasePoint: keychain.KeyDescriptor{
49✔
1925
                        PubKey: copyPubKey(msg.HtlcPoint),
49✔
1926
                },
49✔
1927
        }
49✔
1928

49✔
1929
        // With our parameters set, we'll now process their contribution so we
49✔
1930
        // can move the funding workflow ahead.
49✔
1931
        remoteContribution := &lnwallet.ChannelContribution{
49✔
1932
                FundingAmount:        amt,
49✔
1933
                FirstCommitmentPoint: msg.FirstCommitmentPoint,
49✔
1934
                ChannelConfig:        &cfg,
49✔
1935
                UpfrontShutdown:      msg.UpfrontShutdownScript,
49✔
1936
        }
49✔
1937

49✔
1938
        if resCtx.reservation.IsTaproot() {
53✔
1939
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
4✔
1940
                if err != nil {
4✔
1941
                        log.Error(errNoLocalNonce)
×
1942

×
1943
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
1944

×
1945
                        return
×
1946
                }
×
1947

1948
                remoteContribution.LocalNonce = &musig2.Nonces{
4✔
1949
                        PubNonce: localNonce,
4✔
1950
                }
4✔
1951
        }
1952

1953
        err = reservation.ProcessSingleContribution(remoteContribution)
49✔
1954
        if err != nil {
55✔
1955
                log.Errorf("unable to add contribution reservation: %v", err)
6✔
1956
                f.failFundingFlow(peer, cid, err)
6✔
1957
                return
6✔
1958
        }
6✔
1959

1960
        log.Infof("Sending fundingResp for pending_id(%x)",
43✔
1961
                msg.PendingChannelID)
43✔
1962
        bounds := remoteContribution.ChannelConfig.ChannelStateBounds
43✔
1963
        log.Debugf("Remote party accepted channel state space bounds: %v",
43✔
1964
                lnutils.SpewLogClosure(bounds))
43✔
1965
        params := remoteContribution.ChannelConfig.CommitmentParams
43✔
1966
        log.Debugf("Remote party accepted commitment rendering params: %v",
43✔
1967
                lnutils.SpewLogClosure(params))
43✔
1968

43✔
1969
        reservation.SetState(lnwallet.SentAcceptChannel)
43✔
1970

43✔
1971
        // With the initiator's contribution recorded, respond with our
43✔
1972
        // contribution in the next message of the workflow.
43✔
1973
        fundingAccept := lnwire.AcceptChannel{
43✔
1974
                PendingChannelID:      msg.PendingChannelID,
43✔
1975
                DustLimit:             ourContribution.DustLimit,
43✔
1976
                MaxValueInFlight:      remoteMaxValue,
43✔
1977
                ChannelReserve:        chanReserve,
43✔
1978
                MinAcceptDepth:        uint32(numConfsReq),
43✔
1979
                HtlcMinimum:           minHtlc,
43✔
1980
                CsvDelay:              remoteCsvDelay,
43✔
1981
                MaxAcceptedHTLCs:      maxHtlcs,
43✔
1982
                FundingKey:            ourContribution.MultiSigKey.PubKey,
43✔
1983
                RevocationPoint:       ourContribution.RevocationBasePoint.PubKey,
43✔
1984
                PaymentPoint:          ourContribution.PaymentBasePoint.PubKey,
43✔
1985
                DelayedPaymentPoint:   ourContribution.DelayBasePoint.PubKey,
43✔
1986
                HtlcPoint:             ourContribution.HtlcBasePoint.PubKey,
43✔
1987
                FirstCommitmentPoint:  ourContribution.FirstCommitmentPoint,
43✔
1988
                UpfrontShutdownScript: ourContribution.UpfrontShutdown,
43✔
1989
                ChannelType:           chanType,
43✔
1990
                LeaseExpiry:           msg.LeaseExpiry,
43✔
1991
        }
43✔
1992

43✔
1993
        if commitType.IsTaproot() {
47✔
1994
                fundingAccept.LocalNonce = lnwire.SomeMusig2Nonce(
4✔
1995
                        ourContribution.LocalNonce.PubNonce,
4✔
1996
                )
4✔
1997
        }
4✔
1998

1999
        if err := peer.SendMessage(true, &fundingAccept); err != nil {
43✔
2000
                log.Errorf("unable to send funding response to peer: %v", err)
×
2001
                f.failFundingFlow(peer, cid, err)
×
2002
                return
×
2003
        }
×
2004
}
2005

2006
// funderProcessAcceptChannel processes a response to the workflow initiation
2007
// sent by the remote peer. This message then queues a message with the funding
2008
// outpoint, and a commitment signature to the remote peer.
2009
//
2010
//nolint:funlen
2011
func (f *Manager) funderProcessAcceptChannel(peer lnpeer.Peer,
2012
        msg *lnwire.AcceptChannel) {
35✔
2013

35✔
2014
        pendingChanID := msg.PendingChannelID
35✔
2015
        peerKey := peer.IdentityKey()
35✔
2016
        var peerKeyBytes []byte
35✔
2017
        if peerKey != nil {
70✔
2018
                peerKeyBytes = peerKey.SerializeCompressed()
35✔
2019
        }
35✔
2020

2021
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
35✔
2022
        if err != nil {
35✔
2023
                log.Warnf("Can't find reservation (peerKey:%x, chan_id:%v)",
×
2024
                        peerKeyBytes, pendingChanID)
×
2025
                return
×
2026
        }
×
2027

2028
        // Update the timestamp once the fundingAcceptMsg has been handled.
2029
        defer resCtx.updateTimestamp()
35✔
2030

35✔
2031
        if resCtx.reservation.State() != lnwallet.SentOpenChannel {
35✔
2032
                return
×
2033
        }
×
2034

2035
        log.Infof("Recv'd fundingResponse for pending_id(%x)",
35✔
2036
                pendingChanID[:])
35✔
2037

35✔
2038
        // Create the channel identifier.
35✔
2039
        cid := newChanIdentifier(msg.PendingChannelID)
35✔
2040

35✔
2041
        // Perform some basic validation of any custom TLV records included.
35✔
2042
        //
35✔
2043
        // TODO: Return errors as funding.Error to give context to remote peer?
35✔
2044
        if resCtx.channelType != nil {
41✔
2045
                // We'll want to quickly check that the ChannelType echoed by
6✔
2046
                // the channel request recipient matches what we proposed.
6✔
2047
                if msg.ChannelType == nil {
7✔
2048
                        err := errors.New("explicit channel type not echoed " +
1✔
2049
                                "back")
1✔
2050
                        f.failFundingFlow(peer, cid, err)
1✔
2051
                        return
1✔
2052
                }
1✔
2053
                proposedFeatures := lnwire.RawFeatureVector(*resCtx.channelType)
5✔
2054
                ackedFeatures := lnwire.RawFeatureVector(*msg.ChannelType)
5✔
2055
                if !proposedFeatures.Equals(&ackedFeatures) {
5✔
2056
                        err := errors.New("channel type mismatch")
×
2057
                        f.failFundingFlow(peer, cid, err)
×
2058
                        return
×
2059
                }
×
2060

2061
                // We'll want to do the same with the LeaseExpiry if one should
2062
                // be set.
2063
                if resCtx.reservation.LeaseExpiry() != 0 {
7✔
2064
                        if msg.LeaseExpiry == nil {
2✔
2065
                                err := errors.New("lease expiry not echoed " +
×
2066
                                        "back")
×
2067
                                f.failFundingFlow(peer, cid, err)
×
2068
                                return
×
2069
                        }
×
2070
                        if uint32(*msg.LeaseExpiry) !=
2✔
2071
                                resCtx.reservation.LeaseExpiry() {
2✔
2072

×
2073
                                err := errors.New("lease expiry mismatch")
×
2074
                                f.failFundingFlow(peer, cid, err)
×
2075
                                return
×
2076
                        }
×
2077
                }
2078
        } else if msg.ChannelType != nil {
29✔
2079
                // The spec isn't too clear about whether it's okay to set the
×
2080
                // channel type in the accept_channel response if we didn't
×
2081
                // explicitly set it in the open_channel message. For now, we
×
2082
                // check that it's the same type we'd have arrived through
×
2083
                // implicit negotiation. If it's another type, we fail the flow.
×
2084
                _, implicitCommitType := implicitNegotiateCommitmentType(
×
2085
                        peer.LocalFeatures(), peer.RemoteFeatures(),
×
2086
                )
×
2087

×
2088
                _, negotiatedCommitType, err := negotiateCommitmentType(
×
2089
                        msg.ChannelType, peer.LocalFeatures(),
×
2090
                        peer.RemoteFeatures(),
×
2091
                )
×
2092
                if err != nil {
×
2093
                        err := errors.New("received unexpected channel type")
×
2094
                        f.failFundingFlow(peer, cid, err)
×
2095
                        return
×
2096
                }
×
2097

2098
                if implicitCommitType != negotiatedCommitType {
×
2099
                        err := errors.New("negotiated unexpected channel type")
×
2100
                        f.failFundingFlow(peer, cid, err)
×
2101
                        return
×
2102
                }
×
2103
        }
2104

2105
        // The required number of confirmations should not be greater than the
2106
        // maximum number of confirmations required by the ChainNotifier to
2107
        // properly dispatch confirmations.
2108
        if msg.MinAcceptDepth > chainntnfs.MaxNumConfs {
35✔
2109
                err := lnwallet.ErrNumConfsTooLarge(
1✔
2110
                        msg.MinAcceptDepth, chainntnfs.MaxNumConfs,
1✔
2111
                )
1✔
2112
                log.Warnf("Unacceptable channel constraints: %v", err)
1✔
2113
                f.failFundingFlow(peer, cid, err)
1✔
2114
                return
1✔
2115
        }
1✔
2116

2117
        // Check that zero-conf channels have minimum depth set to 0.
2118
        if resCtx.reservation.IsZeroConf() && msg.MinAcceptDepth != 0 {
33✔
2119
                err = fmt.Errorf("zero-conf channel has min_depth non-zero")
×
2120
                log.Warn(err)
×
2121
                f.failFundingFlow(peer, cid, err)
×
2122
                return
×
2123
        }
×
2124

2125
        // If this is not a zero-conf channel but the peer responded with a
2126
        // min-depth of zero, we will use our minimum of 1 instead.
2127
        minDepth := msg.MinAcceptDepth
33✔
2128
        if !resCtx.reservation.IsZeroConf() && minDepth == 0 {
33✔
2129
                log.Infof("Responder to pending_id=%v sent a minimum "+
×
2130
                        "confirmation depth of 0 for non-zero-conf channel. "+
×
2131
                        "We will use a minimum depth of 1 instead.",
×
2132
                        cid.tempChanID)
×
2133

×
2134
                minDepth = 1
×
2135
        }
×
2136

2137
        // We'll also specify the responder's preference for the number of
2138
        // required confirmations, and also the set of channel constraints
2139
        // they've specified for commitment states we can create.
2140
        resCtx.reservation.SetNumConfsRequired(uint16(minDepth))
33✔
2141
        bounds := channeldb.ChannelStateBounds{
33✔
2142
                ChanReserve:      msg.ChannelReserve,
33✔
2143
                MaxPendingAmount: msg.MaxValueInFlight,
33✔
2144
                MinHTLC:          msg.HtlcMinimum,
33✔
2145
                MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs,
33✔
2146
        }
33✔
2147
        commitParams := channeldb.CommitmentParams{
33✔
2148
                DustLimit: msg.DustLimit,
33✔
2149
                CsvDelay:  msg.CsvDelay,
33✔
2150
        }
33✔
2151
        err = resCtx.reservation.CommitConstraints(
33✔
2152
                &bounds, &commitParams, resCtx.maxLocalCsv, false,
33✔
2153
        )
33✔
2154
        if err != nil {
34✔
2155
                log.Warnf("Unacceptable channel constraints: %v", err)
1✔
2156
                f.failFundingFlow(peer, cid, err)
1✔
2157
                return
1✔
2158
        }
1✔
2159

2160
        cfg := channeldb.ChannelConfig{
32✔
2161
                ChannelStateBounds: channeldb.ChannelStateBounds{
32✔
2162
                        MaxPendingAmount: resCtx.remoteMaxValue,
32✔
2163
                        ChanReserve:      resCtx.remoteChanReserve,
32✔
2164
                        MinHTLC:          resCtx.remoteMinHtlc,
32✔
2165
                        MaxAcceptedHtlcs: resCtx.remoteMaxHtlcs,
32✔
2166
                },
32✔
2167
                CommitmentParams: channeldb.CommitmentParams{
32✔
2168
                        DustLimit: msg.DustLimit,
32✔
2169
                        CsvDelay:  resCtx.remoteCsvDelay,
32✔
2170
                },
32✔
2171
                MultiSigKey: keychain.KeyDescriptor{
32✔
2172
                        PubKey: copyPubKey(msg.FundingKey),
32✔
2173
                },
32✔
2174
                RevocationBasePoint: keychain.KeyDescriptor{
32✔
2175
                        PubKey: copyPubKey(msg.RevocationPoint),
32✔
2176
                },
32✔
2177
                PaymentBasePoint: keychain.KeyDescriptor{
32✔
2178
                        PubKey: copyPubKey(msg.PaymentPoint),
32✔
2179
                },
32✔
2180
                DelayBasePoint: keychain.KeyDescriptor{
32✔
2181
                        PubKey: copyPubKey(msg.DelayedPaymentPoint),
32✔
2182
                },
32✔
2183
                HtlcBasePoint: keychain.KeyDescriptor{
32✔
2184
                        PubKey: copyPubKey(msg.HtlcPoint),
32✔
2185
                },
32✔
2186
        }
32✔
2187

32✔
2188
        // The remote node has responded with their portion of the channel
32✔
2189
        // contribution. At this point, we can process their contribution which
32✔
2190
        // allows us to construct and sign both the commitment transaction, and
32✔
2191
        // the funding transaction.
32✔
2192
        remoteContribution := &lnwallet.ChannelContribution{
32✔
2193
                FirstCommitmentPoint: msg.FirstCommitmentPoint,
32✔
2194
                ChannelConfig:        &cfg,
32✔
2195
                UpfrontShutdown:      msg.UpfrontShutdownScript,
32✔
2196
        }
32✔
2197

32✔
2198
        if resCtx.reservation.IsTaproot() {
36✔
2199
                localNonce, err := msg.LocalNonce.UnwrapOrErrV(errNoLocalNonce)
4✔
2200
                if err != nil {
4✔
2201
                        log.Error(errNoLocalNonce)
×
2202

×
2203
                        f.failFundingFlow(resCtx.peer, cid, errNoLocalNonce)
×
2204

×
2205
                        return
×
2206
                }
×
2207

2208
                remoteContribution.LocalNonce = &musig2.Nonces{
4✔
2209
                        PubNonce: localNonce,
4✔
2210
                }
4✔
2211
        }
2212

2213
        err = resCtx.reservation.ProcessContribution(remoteContribution)
32✔
2214

32✔
2215
        // The wallet has detected that a PSBT funding process was requested by
32✔
2216
        // the user and has halted the funding process after negotiating the
32✔
2217
        // multisig keys. We now have everything that is needed for the user to
32✔
2218
        // start constructing a PSBT that sends to the multisig funding address.
32✔
2219
        var psbtIntent *chanfunding.PsbtIntent
32✔
2220
        if psbtErr, ok := err.(*lnwallet.PsbtFundingRequired); ok {
34✔
2221
                // Return the information that is needed by the user to
2✔
2222
                // construct the PSBT back to the caller.
2✔
2223
                addr, amt, packet, err := psbtErr.Intent.FundingParams()
2✔
2224
                if err != nil {
2✔
2225
                        log.Errorf("Unable to process PSBT funding params "+
×
2226
                                "for contribution from %x: %v", peerKeyBytes,
×
2227
                                err)
×
2228
                        f.failFundingFlow(peer, cid, err)
×
2229
                        return
×
2230
                }
×
2231
                var buf bytes.Buffer
2✔
2232
                err = packet.Serialize(&buf)
2✔
2233
                if err != nil {
2✔
2234
                        log.Errorf("Unable to serialize PSBT for "+
×
2235
                                "contribution from %x: %v", peerKeyBytes, err)
×
2236
                        f.failFundingFlow(peer, cid, err)
×
2237
                        return
×
2238
                }
×
2239
                resCtx.updates <- &lnrpc.OpenStatusUpdate{
2✔
2240
                        PendingChanId: pendingChanID[:],
2✔
2241
                        Update: &lnrpc.OpenStatusUpdate_PsbtFund{
2✔
2242
                                PsbtFund: &lnrpc.ReadyForPsbtFunding{
2✔
2243
                                        FundingAddress: addr.EncodeAddress(),
2✔
2244
                                        FundingAmount:  amt,
2✔
2245
                                        Psbt:           buf.Bytes(),
2✔
2246
                                },
2✔
2247
                        },
2✔
2248
                }
2✔
2249
                psbtIntent = psbtErr.Intent
2✔
2250
        } else if err != nil {
32✔
2251
                log.Errorf("Unable to process contribution from %x: %v",
×
2252
                        peerKeyBytes, err)
×
2253
                f.failFundingFlow(peer, cid, err)
×
2254
                return
×
2255
        }
×
2256

2257
        log.Infof("pendingChan(%x): remote party proposes num_confs=%v, "+
32✔
2258
                "csv_delay=%v", pendingChanID[:], msg.MinAcceptDepth,
32✔
2259
                msg.CsvDelay)
32✔
2260
        bounds = remoteContribution.ChannelConfig.ChannelStateBounds
32✔
2261
        log.Debugf("Remote party accepted channel state space bounds: %v",
32✔
2262
                lnutils.SpewLogClosure(bounds))
32✔
2263
        commitParams = remoteContribution.ChannelConfig.CommitmentParams
32✔
2264
        log.Debugf("Remote party accepted commitment rendering params: %v",
32✔
2265
                lnutils.SpewLogClosure(commitParams))
32✔
2266

32✔
2267
        // If the user requested funding through a PSBT, we cannot directly
32✔
2268
        // continue now and need to wait for the fully funded and signed PSBT
32✔
2269
        // to arrive. To not block any other channels from opening, we wait in
32✔
2270
        // a separate goroutine.
32✔
2271
        if psbtIntent != nil {
34✔
2272
                f.wg.Add(1)
2✔
2273
                go func() {
4✔
2274
                        defer f.wg.Done()
2✔
2275

2✔
2276
                        f.waitForPsbt(psbtIntent, resCtx, cid)
2✔
2277
                }()
2✔
2278

2279
                // With the new goroutine spawned, we can now exit to unblock
2280
                // the main event loop.
2281
                return
2✔
2282
        }
2283

2284
        // In a normal, non-PSBT funding flow, we can jump directly to the next
2285
        // step where we expect our contribution to be finalized.
2286
        f.continueFundingAccept(resCtx, cid)
32✔
2287
}
2288

2289
// waitForPsbt blocks until either a signed PSBT arrives, an error occurs or
2290
// the funding manager shuts down. In the case of a valid PSBT, the funding flow
2291
// is continued.
2292
//
2293
// NOTE: This method must be called as a goroutine.
2294
func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
2295
        resCtx *reservationWithCtx, cid *chanIdentifier) {
2✔
2296

2✔
2297
        // failFlow is a helper that logs an error message with the current
2✔
2298
        // context and then fails the funding flow.
2✔
2299
        peerKey := resCtx.peer.IdentityKey()
2✔
2300
        failFlow := func(errMsg string, cause error) {
4✔
2301
                log.Errorf("Unable to handle funding accept message "+
2✔
2302
                        "for peer_key=%x, pending_chan_id=%x: %s: %v",
2✔
2303
                        peerKey.SerializeCompressed(), cid.tempChanID, errMsg,
2✔
2304
                        cause)
2✔
2305
                f.failFundingFlow(resCtx.peer, cid, cause)
2✔
2306
        }
2✔
2307

2308
        // We'll now wait until the intent has received the final and complete
2309
        // funding transaction. If the channel is closed without any error being
2310
        // sent, we know everything's going as expected.
2311
        select {
2✔
2312
        case err := <-intent.PsbtReady:
2✔
2313
                switch err {
2✔
2314
                // If the user canceled the funding reservation, we need to
2315
                // inform the other peer about us canceling the reservation.
2316
                case chanfunding.ErrUserCanceled:
2✔
2317
                        failFlow("aborting PSBT flow", err)
2✔
2318
                        return
2✔
2319

2320
                // If the remote canceled the funding reservation, we don't need
2321
                // to send another fail message. But we want to inform the user
2322
                // about what happened.
2323
                case chanfunding.ErrRemoteCanceled:
2✔
2324
                        log.Infof("Remote canceled, aborting PSBT flow "+
2✔
2325
                                "for peer_key=%x, pending_chan_id=%x",
2✔
2326
                                peerKey.SerializeCompressed(), cid.tempChanID)
2✔
2327
                        return
2✔
2328

2329
                // Nil error means the flow continues normally now.
2330
                case nil:
2✔
2331

2332
                // For any other error, we'll fail the funding flow.
2333
                default:
×
2334
                        failFlow("error waiting for PSBT flow", err)
×
2335
                        return
×
2336
                }
2337

2338
                // At this point, we'll see if there's an AuxFundingDesc we
2339
                // need to deliver so the funding process can continue
2340
                // properly.
2341
                auxFundingDesc, err := fn.MapOptionZ(
2✔
2342
                        f.cfg.AuxFundingController,
2✔
2343
                        func(c AuxFundingController) AuxFundingDescResult {
2✔
2344
                                return c.DescFromPendingChanID(
×
2345
                                        cid.tempChanID,
×
2346
                                        lnwallet.NewAuxChanState(
×
2347
                                                resCtx.reservation.ChanState(),
×
2348
                                        ),
×
2349
                                        resCtx.reservation.CommitmentKeyRings(),
×
2350
                                        true,
×
2351
                                )
×
2352
                        },
×
2353
                ).Unpack()
2354
                if err != nil {
2✔
2355
                        failFlow("error continuing PSBT flow", err)
×
2356
                        return
×
2357
                }
×
2358

2359
                // A non-nil error means we can continue the funding flow.
2360
                // Notify the wallet so it can prepare everything we need to
2361
                // continue.
2362
                //
2363
                // We'll also pass along the aux funding controller as well,
2364
                // which may be used to help process the finalized PSBT.
2365
                err = resCtx.reservation.ProcessPsbt(auxFundingDesc)
2✔
2366
                if err != nil {
2✔
2367
                        failFlow("error continuing PSBT flow", err)
×
2368
                        return
×
2369
                }
×
2370

2371
                // We are now ready to continue the funding flow.
2372
                f.continueFundingAccept(resCtx, cid)
2✔
2373

2374
        // Handle a server shutdown as well because the reservation won't
2375
        // survive a restart as it's in memory only.
2376
        case <-f.quit:
×
2377
                log.Errorf("Unable to handle funding accept message "+
×
2378
                        "for peer_key=%x, pending_chan_id=%x: funding manager "+
×
2379
                        "shutting down", peerKey.SerializeCompressed(),
×
2380
                        cid.tempChanID)
×
2381
                return
×
2382
        }
2383
}
2384

2385
// continueFundingAccept continues the channel funding flow once our
2386
// contribution is finalized, the channel output is known and the funding
2387
// transaction is signed.
2388
func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
2389
        cid *chanIdentifier) {
32✔
2390

32✔
2391
        // Now that we have their contribution, we can extract, then send over
32✔
2392
        // both the funding out point and our signature for their version of
32✔
2393
        // the commitment transaction to the remote peer.
32✔
2394
        outPoint := resCtx.reservation.FundingOutpoint()
32✔
2395
        _, sig := resCtx.reservation.OurSignatures()
32✔
2396

32✔
2397
        // A new channel has almost finished the funding process. In order to
32✔
2398
        // properly synchronize with the writeHandler goroutine, we add a new
32✔
2399
        // channel to the barriers map which will be closed once the channel is
32✔
2400
        // fully open.
32✔
2401
        channelID := lnwire.NewChanIDFromOutPoint(*outPoint)
32✔
2402
        log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
32✔
2403

32✔
2404
        // The next message that advances the funding flow will reference the
32✔
2405
        // channel via its permanent channel ID, so we'll set up this mapping
32✔
2406
        // so we can retrieve the reservation context once we get the
32✔
2407
        // FundingSigned message.
32✔
2408
        f.resMtx.Lock()
32✔
2409
        f.signedReservations[channelID] = cid.tempChanID
32✔
2410
        f.resMtx.Unlock()
32✔
2411

32✔
2412
        log.Infof("Generated ChannelPoint(%v) for pending_id(%x)", outPoint,
32✔
2413
                cid.tempChanID[:])
32✔
2414

32✔
2415
        // Before sending FundingCreated sent, we notify Brontide to keep track
32✔
2416
        // of this pending open channel.
32✔
2417
        err := resCtx.peer.AddPendingChannel(channelID, f.quit)
32✔
2418
        if err != nil {
32✔
2419
                pubKey := resCtx.peer.IdentityKey().SerializeCompressed()
×
2420
                log.Errorf("Unable to add pending channel %v with peer %x: %v",
×
2421
                        channelID, pubKey, err)
×
2422
        }
×
2423

2424
        // Once Brontide is aware of this channel, we need to set it in
2425
        // chanIdentifier so this channel will be removed from Brontide if the
2426
        // funding flow fails.
2427
        cid.setChanID(channelID)
32✔
2428

32✔
2429
        // Send the FundingCreated msg.
32✔
2430
        fundingCreated := &lnwire.FundingCreated{
32✔
2431
                PendingChannelID: cid.tempChanID,
32✔
2432
                FundingPoint:     *outPoint,
32✔
2433
        }
32✔
2434

32✔
2435
        // If this is a taproot channel, then we'll need to populate the musig2
32✔
2436
        // partial sig field instead of the regular commit sig field.
32✔
2437
        if resCtx.reservation.IsTaproot() {
36✔
2438
                partialSig, ok := sig.(*lnwallet.MusigPartialSig)
4✔
2439
                if !ok {
4✔
2440
                        err := fmt.Errorf("expected musig partial sig, got %T",
×
2441
                                sig)
×
2442
                        log.Error(err)
×
2443
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2444

×
2445
                        return
×
2446
                }
×
2447

2448
                fundingCreated.PartialSig = lnwire.MaybePartialSigWithNonce(
4✔
2449
                        partialSig.ToWireSig(),
4✔
2450
                )
4✔
2451
        } else {
30✔
2452
                fundingCreated.CommitSig, err = lnwire.NewSigFromSignature(sig)
30✔
2453
                if err != nil {
30✔
2454
                        log.Errorf("Unable to parse signature: %v", err)
×
2455
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2456
                        return
×
2457
                }
×
2458
        }
2459

2460
        resCtx.reservation.SetState(lnwallet.SentFundingCreated)
32✔
2461

32✔
2462
        if err := resCtx.peer.SendMessage(true, fundingCreated); err != nil {
32✔
2463
                log.Errorf("Unable to send funding complete message: %v", err)
×
2464
                f.failFundingFlow(resCtx.peer, cid, err)
×
2465
                return
×
2466
        }
×
2467
}
2468

2469
// fundeeProcessFundingCreated progresses the funding workflow when the daemon
2470
// is on the responding side of a single funder workflow. Once this message has
2471
// been processed, a signature is sent to the remote peer allowing it to
2472
// broadcast the funding transaction, progressing the workflow into the final
2473
// stage.
2474
//
2475
//nolint:funlen
2476
func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
2477
        msg *lnwire.FundingCreated) {
30✔
2478

30✔
2479
        peerKey := peer.IdentityKey()
30✔
2480
        pendingChanID := msg.PendingChannelID
30✔
2481

30✔
2482
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
30✔
2483
        if err != nil {
30✔
2484
                log.Warnf("can't find reservation (peer_id:%v, chan_id:%x)",
×
2485
                        peerKey, pendingChanID[:])
×
2486
                return
×
2487
        }
×
2488

2489
        // The channel initiator has responded with the funding outpoint of the
2490
        // final funding transaction, as well as a signature for our version of
2491
        // the commitment transaction. So at this point, we can validate the
2492
        // initiator's commitment transaction, then send our own if it's valid.
2493
        fundingOut := msg.FundingPoint
30✔
2494
        log.Infof("completing pending_id(%x) with ChannelPoint(%v)",
30✔
2495
                pendingChanID[:], fundingOut)
30✔
2496

30✔
2497
        if resCtx.reservation.State() != lnwallet.SentAcceptChannel {
30✔
2498
                return
×
2499
        }
×
2500

2501
        // Create the channel identifier without setting the active channel ID.
2502
        cid := newChanIdentifier(pendingChanID)
30✔
2503

30✔
2504
        // For taproot channels, the commit signature is actually the partial
30✔
2505
        // signature. Otherwise, we can convert the ECDSA commit signature into
30✔
2506
        // our internal input.Signature type.
30✔
2507
        var commitSig input.Signature
30✔
2508
        if resCtx.reservation.IsTaproot() {
34✔
2509
                partialSig, err := msg.PartialSig.UnwrapOrErrV(errNoPartialSig)
4✔
2510
                if err != nil {
4✔
2511
                        f.failFundingFlow(peer, cid, err)
×
2512

×
2513
                        return
×
2514
                }
×
2515

2516
                commitSig = new(lnwallet.MusigPartialSig).FromWireSig(
4✔
2517
                        &partialSig,
4✔
2518
                )
4✔
2519
        } else {
28✔
2520
                commitSig, err = msg.CommitSig.ToSignature()
28✔
2521
                if err != nil {
28✔
2522
                        log.Errorf("unable to parse signature: %v", err)
×
2523
                        f.failFundingFlow(peer, cid, err)
×
2524
                        return
×
2525
                }
×
2526
        }
2527

2528
        // At this point, we'll see if there's an AuxFundingDesc we need to
2529
        // deliver so the funding process can continue properly.
2530
        auxFundingDesc, err := fn.MapOptionZ(
30✔
2531
                f.cfg.AuxFundingController,
30✔
2532
                func(c AuxFundingController) AuxFundingDescResult {
30✔
2533
                        return c.DescFromPendingChanID(
×
2534
                                cid.tempChanID, lnwallet.NewAuxChanState(
×
2535
                                        resCtx.reservation.ChanState(),
×
2536
                                ), resCtx.reservation.CommitmentKeyRings(),
×
2537
                                true,
×
2538
                        )
×
2539
                },
×
2540
        ).Unpack()
2541
        if err != nil {
30✔
2542
                log.Errorf("error continuing PSBT flow: %v", err)
×
2543
                f.failFundingFlow(peer, cid, err)
×
2544
                return
×
2545
        }
×
2546

2547
        // With all the necessary data available, attempt to advance the
2548
        // funding workflow to the next stage. If this succeeds then the
2549
        // funding transaction will broadcast after our next message.
2550
        // CompleteReservationSingle will also mark the channel as 'IsPending'
2551
        // in the database.
2552
        //
2553
        // We'll also directly pass in the AuxFunding controller as well,
2554
        // which may be used by the reservation system to finalize funding our
2555
        // side.
2556
        completeChan, err := resCtx.reservation.CompleteReservationSingle(
30✔
2557
                &fundingOut, commitSig, auxFundingDesc,
30✔
2558
        )
30✔
2559
        if err != nil {
30✔
2560
                log.Errorf("unable to complete single reservation: %v", err)
×
2561
                f.failFundingFlow(peer, cid, err)
×
2562
                return
×
2563
        }
×
2564

2565
        // Get forwarding policy before deleting the reservation context.
2566
        forwardingPolicy := resCtx.forwardingPolicy
30✔
2567

30✔
2568
        // The channel is marked IsPending in the database, and can be removed
30✔
2569
        // from the set of active reservations.
30✔
2570
        f.deleteReservationCtx(peerKey, cid.tempChanID)
30✔
2571

30✔
2572
        // If something goes wrong before the funding transaction is confirmed,
30✔
2573
        // we use this convenience method to delete the pending OpenChannel
30✔
2574
        // from the database.
30✔
2575
        deleteFromDatabase := func() {
30✔
2576
                localBalance := completeChan.LocalCommitment.LocalBalance.ToSatoshis()
×
2577
                closeInfo := &channeldb.ChannelCloseSummary{
×
2578
                        ChanPoint:               completeChan.FundingOutpoint,
×
2579
                        ChainHash:               completeChan.ChainHash,
×
2580
                        RemotePub:               completeChan.IdentityPub,
×
2581
                        CloseType:               channeldb.FundingCanceled,
×
2582
                        Capacity:                completeChan.Capacity,
×
2583
                        SettledBalance:          localBalance,
×
2584
                        RemoteCurrentRevocation: completeChan.RemoteCurrentRevocation,
×
2585
                        RemoteNextRevocation:    completeChan.RemoteNextRevocation,
×
2586
                        LocalChanConfig:         completeChan.LocalChanCfg,
×
2587
                }
×
2588

×
2589
                // Close the channel with us as the initiator because we are
×
2590
                // deciding to exit the funding flow due to an internal error.
×
2591
                if err := completeChan.CloseChannel(
×
2592
                        closeInfo, channeldb.ChanStatusLocalCloseInitiator,
×
2593
                ); err != nil {
×
2594
                        log.Errorf("Failed closing channel %v: %v",
×
2595
                                completeChan.FundingOutpoint, err)
×
2596
                }
×
2597
        }
2598

2599
        // A new channel has almost finished the funding process. In order to
2600
        // properly synchronize with the writeHandler goroutine, we add a new
2601
        // channel to the barriers map which will be closed once the channel is
2602
        // fully open.
2603
        channelID := lnwire.NewChanIDFromOutPoint(fundingOut)
30✔
2604
        log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
30✔
2605

30✔
2606
        fundingSigned := &lnwire.FundingSigned{}
30✔
2607

30✔
2608
        // For taproot channels, we'll need to send over a partial signature
30✔
2609
        // that includes the nonce along side the signature.
30✔
2610
        _, sig := resCtx.reservation.OurSignatures()
30✔
2611
        if resCtx.reservation.IsTaproot() {
34✔
2612
                partialSig, ok := sig.(*lnwallet.MusigPartialSig)
4✔
2613
                if !ok {
4✔
2614
                        err := fmt.Errorf("expected musig partial sig, got %T",
×
2615
                                sig)
×
2616
                        log.Error(err)
×
2617
                        f.failFundingFlow(resCtx.peer, cid, err)
×
2618
                        deleteFromDatabase()
×
2619

×
2620
                        return
×
2621
                }
×
2622

2623
                fundingSigned.PartialSig = lnwire.MaybePartialSigWithNonce(
4✔
2624
                        partialSig.ToWireSig(),
4✔
2625
                )
4✔
2626
        } else {
28✔
2627
                fundingSigned.CommitSig, err = lnwire.NewSigFromSignature(sig)
28✔
2628
                if err != nil {
28✔
2629
                        log.Errorf("unable to parse signature: %v", err)
×
2630
                        f.failFundingFlow(peer, cid, err)
×
2631
                        deleteFromDatabase()
×
2632

×
2633
                        return
×
2634
                }
×
2635
        }
2636

2637
        // Before sending FundingSigned, we notify Brontide first to keep track
2638
        // of this pending open channel.
2639
        if err := peer.AddPendingChannel(channelID, f.quit); err != nil {
30✔
2640
                pubKey := peer.IdentityKey().SerializeCompressed()
×
2641
                log.Errorf("Unable to add pending channel %v with peer %x: %v",
×
2642
                        cid.chanID, pubKey, err)
×
2643
        }
×
2644

2645
        // Once Brontide is aware of this channel, we need to set it in
2646
        // chanIdentifier so this channel will be removed from Brontide if the
2647
        // funding flow fails.
2648
        cid.setChanID(channelID)
30✔
2649

30✔
2650
        fundingSigned.ChanID = cid.chanID
30✔
2651

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

30✔
2655
        // With their signature for our version of the commitment transaction
30✔
2656
        // verified, we can now send over our signature to the remote peer.
30✔
2657
        if err := peer.SendMessage(true, fundingSigned); err != nil {
30✔
2658
                log.Errorf("unable to send FundingSigned message: %v", err)
×
2659
                f.failFundingFlow(peer, cid, err)
×
2660
                deleteFromDatabase()
×
2661
                return
×
2662
        }
×
2663

2664
        // With a permanent channel id established we can save the respective
2665
        // forwarding policy in the database. In the channel announcement phase
2666
        // this forwarding policy is retrieved and applied.
2667
        err = f.saveInitialForwardingPolicy(cid.chanID, &forwardingPolicy)
30✔
2668
        if err != nil {
30✔
2669
                log.Errorf("Unable to store the forwarding policy: %v", err)
×
2670
        }
×
2671

2672
        // Now that we've sent over our final signature for this channel, we'll
2673
        // send it to the ChainArbitrator so it can watch for any on-chain
2674
        // actions during this final confirmation stage.
2675
        if err := f.cfg.WatchNewChannel(completeChan, peerKey); err != nil {
30✔
2676
                log.Errorf("Unable to send new ChannelPoint(%v) for "+
×
2677
                        "arbitration: %v", fundingOut, err)
×
2678
        }
×
2679

2680
        // Create an entry in the local discovery map so we can ensure that we
2681
        // process the channel confirmation fully before we receive a
2682
        // channel_ready message.
2683
        f.localDiscoverySignals.Store(cid.chanID, make(chan struct{}))
30✔
2684

30✔
2685
        // Inform the ChannelNotifier that the channel has entered
30✔
2686
        // pending open state.
30✔
2687
        f.cfg.NotifyPendingOpenChannelEvent(
30✔
2688
                fundingOut, completeChan, completeChan.IdentityPub,
30✔
2689
        )
30✔
2690

30✔
2691
        // At this point we have sent our last funding message to the
30✔
2692
        // initiating peer before the funding transaction will be broadcast.
30✔
2693
        // With this last message, our job as the responder is now complete.
30✔
2694
        // We'll wait for the funding transaction to reach the specified number
30✔
2695
        // of confirmations, then start normal operations.
30✔
2696
        //
30✔
2697
        // When we get to this point we have sent the signComplete message to
30✔
2698
        // the channel funder, and BOLT#2 specifies that we MUST remember the
30✔
2699
        // channel for reconnection. The channel is already marked
30✔
2700
        // as pending in the database, so in case of a disconnect or restart,
30✔
2701
        // we will continue waiting for the confirmation the next time we start
30✔
2702
        // the funding manager. In case the funding transaction never appears
30✔
2703
        // on the blockchain, we must forget this channel. We therefore
30✔
2704
        // completely forget about this channel if we haven't seen the funding
30✔
2705
        // transaction in 288 blocks (~ 48 hrs), by canceling the reservation
30✔
2706
        // and canceling the wait for the funding confirmation.
30✔
2707
        f.wg.Add(1)
30✔
2708
        go f.advanceFundingState(completeChan, pendingChanID, nil)
30✔
2709
}
2710

2711
// funderProcessFundingSigned processes the final message received in a single
2712
// funder workflow. Once this message is processed, the funding transaction is
2713
// broadcast. Once the funding transaction reaches a sufficient number of
2714
// confirmations, a message is sent to the responding peer along with a compact
2715
// encoding of the location of the channel within the blockchain.
2716
func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
2717
        msg *lnwire.FundingSigned) {
30✔
2718

30✔
2719
        // As the funding signed message will reference the reservation by its
30✔
2720
        // permanent channel ID, we'll need to perform an intermediate look up
30✔
2721
        // before we can obtain the reservation.
30✔
2722
        f.resMtx.Lock()
30✔
2723
        pendingChanID, ok := f.signedReservations[msg.ChanID]
30✔
2724
        delete(f.signedReservations, msg.ChanID)
30✔
2725
        f.resMtx.Unlock()
30✔
2726

30✔
2727
        // Create the channel identifier and set the channel ID.
30✔
2728
        //
30✔
2729
        // NOTE: we may get an empty pending channel ID here if the key cannot
30✔
2730
        // be found, which means when we cancel the reservation context in
30✔
2731
        // `failFundingFlow`, we will get an error. In this case, we will send
30✔
2732
        // an error msg to our peer using the active channel ID.
30✔
2733
        //
30✔
2734
        // TODO(yy): refactor the funding flow to fix this case.
30✔
2735
        cid := newChanIdentifier(pendingChanID)
30✔
2736
        cid.setChanID(msg.ChanID)
30✔
2737

30✔
2738
        // If the pending channel ID is not found, fail the funding flow.
30✔
2739
        if !ok {
30✔
2740
                // NOTE: we directly overwrite the pending channel ID here for
×
2741
                // this rare case since we don't have a valid pending channel
×
2742
                // ID.
×
2743
                cid.tempChanID = msg.ChanID
×
2744

×
2745
                err := fmt.Errorf("unable to find signed reservation for "+
×
2746
                        "chan_id=%x", msg.ChanID)
×
2747
                log.Warnf(err.Error())
×
2748
                f.failFundingFlow(peer, cid, err)
×
2749
                return
×
2750
        }
×
2751

2752
        peerKey := peer.IdentityKey()
30✔
2753
        resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
30✔
2754
        if err != nil {
30✔
2755
                log.Warnf("Unable to find reservation (peer_id:%v, "+
×
2756
                        "chan_id:%x)", peerKey, pendingChanID[:])
×
2757
                // TODO: add ErrChanNotFound?
×
2758
                f.failFundingFlow(peer, cid, err)
×
2759
                return
×
2760
        }
×
2761

2762
        if resCtx.reservation.State() != lnwallet.SentFundingCreated {
30✔
2763
                err := fmt.Errorf("unable to find reservation for chan_id=%x",
×
2764
                        msg.ChanID)
×
2765
                f.failFundingFlow(peer, cid, err)
×
2766

×
2767
                return
×
2768
        }
×
2769

2770
        // Create an entry in the local discovery map so we can ensure that we
2771
        // process the channel confirmation fully before we receive a
2772
        // channel_ready message.
2773
        fundingPoint := resCtx.reservation.FundingOutpoint()
30✔
2774
        permChanID := lnwire.NewChanIDFromOutPoint(*fundingPoint)
30✔
2775
        f.localDiscoverySignals.Store(permChanID, make(chan struct{}))
30✔
2776

30✔
2777
        // We have to store the forwardingPolicy before the reservation context
30✔
2778
        // is deleted. The policy will then be read and applied in
30✔
2779
        // newChanAnnouncement.
30✔
2780
        err = f.saveInitialForwardingPolicy(
30✔
2781
                permChanID, &resCtx.forwardingPolicy,
30✔
2782
        )
30✔
2783
        if err != nil {
30✔
2784
                log.Errorf("Unable to store the forwarding policy: %v", err)
×
2785
        }
×
2786

2787
        // For taproot channels, the commit signature is actually the partial
2788
        // signature. Otherwise, we can convert the ECDSA commit signature into
2789
        // our internal input.Signature type.
2790
        var commitSig input.Signature
30✔
2791
        if resCtx.reservation.IsTaproot() {
34✔
2792
                partialSig, err := msg.PartialSig.UnwrapOrErrV(errNoPartialSig)
4✔
2793
                if err != nil {
4✔
2794
                        f.failFundingFlow(peer, cid, err)
×
2795

×
2796
                        return
×
2797
                }
×
2798

2799
                commitSig = new(lnwallet.MusigPartialSig).FromWireSig(
4✔
2800
                        &partialSig,
4✔
2801
                )
4✔
2802
        } else {
28✔
2803
                commitSig, err = msg.CommitSig.ToSignature()
28✔
2804
                if err != nil {
28✔
2805
                        log.Errorf("unable to parse signature: %v", err)
×
2806
                        f.failFundingFlow(peer, cid, err)
×
2807
                        return
×
2808
                }
×
2809
        }
2810

2811
        completeChan, err := resCtx.reservation.CompleteReservation(
30✔
2812
                nil, commitSig,
30✔
2813
        )
30✔
2814
        if err != nil {
30✔
2815
                log.Errorf("Unable to complete reservation sign "+
×
2816
                        "complete: %v", err)
×
2817
                f.failFundingFlow(peer, cid, err)
×
2818
                return
×
2819
        }
×
2820

2821
        // The channel is now marked IsPending in the database, and we can
2822
        // delete it from our set of active reservations.
2823
        f.deleteReservationCtx(peerKey, pendingChanID)
30✔
2824

30✔
2825
        // Broadcast the finalized funding transaction to the network, but only
30✔
2826
        // if we actually have the funding transaction.
30✔
2827
        if completeChan.ChanType.HasFundingTx() {
59✔
2828
                fundingTx := completeChan.FundingTxn
29✔
2829
                var fundingTxBuf bytes.Buffer
29✔
2830
                if err := fundingTx.Serialize(&fundingTxBuf); err != nil {
29✔
2831
                        log.Errorf("Unable to serialize funding "+
×
2832
                                "transaction %v: %v", fundingTx.TxHash(), err)
×
2833

×
2834
                        // Clear the buffer of any bytes that were written
×
2835
                        // before the serialization error to prevent logging an
×
2836
                        // incomplete transaction.
×
2837
                        fundingTxBuf.Reset()
×
2838
                }
×
2839

2840
                log.Infof("Broadcasting funding tx for ChannelPoint(%v): %x",
29✔
2841
                        completeChan.FundingOutpoint, fundingTxBuf.Bytes())
29✔
2842

29✔
2843
                // Set a nil short channel ID at this stage because we do not
29✔
2844
                // know it until our funding tx confirms.
29✔
2845
                label := labels.MakeLabel(
29✔
2846
                        labels.LabelTypeChannelOpen, nil,
29✔
2847
                )
29✔
2848

29✔
2849
                err = f.cfg.PublishTransaction(fundingTx, label)
29✔
2850
                if err != nil {
29✔
2851
                        log.Errorf("Unable to broadcast funding tx %x for "+
×
2852
                                "ChannelPoint(%v): %v", fundingTxBuf.Bytes(),
×
2853
                                completeChan.FundingOutpoint, err)
×
2854

×
2855
                        // We failed to broadcast the funding transaction, but
×
2856
                        // watch the channel regardless, in case the
×
2857
                        // transaction made it to the network. We will retry
×
2858
                        // broadcast at startup.
×
2859
                        //
×
2860
                        // TODO(halseth): retry more often? Handle with CPFP?
×
2861
                        // Just delete from the DB?
×
2862
                }
×
2863
        }
2864

2865
        // Before we proceed, if we have a funding hook that wants a
2866
        // notification that it's safe to broadcast the funding transaction,
2867
        // then we'll send that now.
2868
        err = fn.MapOptionZ(
30✔
2869
                f.cfg.AuxFundingController,
30✔
2870
                func(controller AuxFundingController) error {
30✔
2871
                        return controller.ChannelFinalized(cid.tempChanID)
×
2872
                },
×
2873
        )
2874
        if err != nil {
30✔
2875
                log.Errorf("Failed to inform aux funding controller about "+
×
2876
                        "ChannelPoint(%v) being finalized: %v", fundingPoint,
×
2877
                        err)
×
2878
        }
×
2879

2880
        // Now that we have a finalized reservation for this funding flow,
2881
        // we'll send the to be active channel to the ChainArbitrator so it can
2882
        // watch for any on-chain actions before the channel has fully
2883
        // confirmed.
2884
        if err := f.cfg.WatchNewChannel(completeChan, peerKey); err != nil {
30✔
2885
                log.Errorf("Unable to send new ChannelPoint(%v) for "+
×
2886
                        "arbitration: %v", fundingPoint, err)
×
2887
        }
×
2888

2889
        log.Infof("Finalizing pending_id(%x) over ChannelPoint(%v), "+
30✔
2890
                "waiting for channel open on-chain", pendingChanID[:],
30✔
2891
                fundingPoint)
30✔
2892

30✔
2893
        // Send an update to the upstream client that the negotiation process
30✔
2894
        // is over.
30✔
2895
        upd := &lnrpc.OpenStatusUpdate{
30✔
2896
                Update: &lnrpc.OpenStatusUpdate_ChanPending{
30✔
2897
                        ChanPending: &lnrpc.PendingUpdate{
30✔
2898
                                Txid:        fundingPoint.Hash[:],
30✔
2899
                                OutputIndex: fundingPoint.Index,
30✔
2900
                        },
30✔
2901
                },
30✔
2902
                PendingChanId: pendingChanID[:],
30✔
2903
        }
30✔
2904

30✔
2905
        select {
30✔
2906
        case resCtx.updates <- upd:
30✔
2907
                // Inform the ChannelNotifier that the channel has entered
30✔
2908
                // pending open state.
30✔
2909
                f.cfg.NotifyPendingOpenChannelEvent(
30✔
2910
                        *fundingPoint, completeChan, completeChan.IdentityPub,
30✔
2911
                )
30✔
2912

2913
        case <-f.quit:
×
2914
                return
×
2915
        }
2916

2917
        // At this point we have broadcast the funding transaction and done all
2918
        // necessary processing.
2919
        f.wg.Add(1)
30✔
2920
        go f.advanceFundingState(completeChan, pendingChanID, resCtx.updates)
30✔
2921
}
2922

2923
// confirmedChannel wraps a confirmed funding transaction, as well as the short
2924
// channel ID which identifies that channel into a single struct. We'll use
2925
// this to pass around the final state of a channel after it has been
2926
// confirmed.
2927
type confirmedChannel struct {
2928
        // shortChanID expresses where in the block the funding transaction was
2929
        // located.
2930
        shortChanID lnwire.ShortChannelID
2931

2932
        // fundingTx is the funding transaction that created the channel.
2933
        fundingTx *wire.MsgTx
2934
}
2935

2936
// fundingTimeout is called when callers of waitForFundingWithTimeout receive
2937
// an ErrConfirmationTimeout. It is used to clean-up channel state and mark the
2938
// channel as closed. The error is only returned for the responder of the
2939
// channel flow.
2940
func (f *Manager) fundingTimeout(c *channeldb.OpenChannel,
2941
        pendingID PendingChanID) error {
4✔
2942

4✔
2943
        // We'll get a timeout if the number of blocks mined since the channel
4✔
2944
        // was initiated reaches MaxWaitNumBlocksFundingConf and we are not the
4✔
2945
        // channel initiator.
4✔
2946
        localBalance := c.LocalCommitment.LocalBalance.ToSatoshis()
4✔
2947
        closeInfo := &channeldb.ChannelCloseSummary{
4✔
2948
                ChainHash:               c.ChainHash,
4✔
2949
                ChanPoint:               c.FundingOutpoint,
4✔
2950
                RemotePub:               c.IdentityPub,
4✔
2951
                Capacity:                c.Capacity,
4✔
2952
                SettledBalance:          localBalance,
4✔
2953
                CloseType:               channeldb.FundingCanceled,
4✔
2954
                RemoteCurrentRevocation: c.RemoteCurrentRevocation,
4✔
2955
                RemoteNextRevocation:    c.RemoteNextRevocation,
4✔
2956
                LocalChanConfig:         c.LocalChanCfg,
4✔
2957
        }
4✔
2958

4✔
2959
        // Close the channel with us as the initiator because we are timing the
4✔
2960
        // channel out.
4✔
2961
        if err := c.CloseChannel(
4✔
2962
                closeInfo, channeldb.ChanStatusLocalCloseInitiator,
4✔
2963
        ); err != nil {
4✔
2964
                return fmt.Errorf("failed closing channel %v: %w",
×
2965
                        c.FundingOutpoint, err)
×
2966
        }
×
2967

2968
        // Notify other subsystems about the funding timeout.
2969
        f.cfg.NotifyFundingTimeout(c.FundingOutpoint, c.IdentityPub)
4✔
2970

4✔
2971
        timeoutErr := fmt.Errorf("timeout waiting for funding tx (%v) to "+
4✔
2972
                "confirm", c.FundingOutpoint)
4✔
2973

4✔
2974
        // When the peer comes online, we'll notify it that we are now
4✔
2975
        // considering the channel flow canceled.
4✔
2976
        f.wg.Add(1)
4✔
2977
        go func() {
8✔
2978
                defer f.wg.Done()
4✔
2979

4✔
2980
                peer, err := f.waitForPeerOnline(c.IdentityPub)
4✔
2981
                switch err {
4✔
2982
                // We're already shutting down, so we can just return.
2983
                case ErrFundingManagerShuttingDown:
×
2984
                        return
×
2985

2986
                // nil error means we continue on.
2987
                case nil:
4✔
2988

2989
                // For unexpected errors, we print the error and still try to
2990
                // fail the funding flow.
2991
                default:
×
2992
                        log.Errorf("Unexpected error while waiting for peer "+
×
2993
                                "to come online: %v", err)
×
2994
                }
2995

2996
                // Create channel identifier and set the channel ID.
2997
                cid := newChanIdentifier(pendingID)
4✔
2998
                cid.setChanID(lnwire.NewChanIDFromOutPoint(c.FundingOutpoint))
4✔
2999

4✔
3000
                // TODO(halseth): should this send be made
4✔
3001
                // reliable?
4✔
3002

4✔
3003
                // The reservation won't exist at this point, but we'll send an
4✔
3004
                // Error message over anyways with ChanID set to pendingID.
4✔
3005
                f.failFundingFlow(peer, cid, timeoutErr)
4✔
3006
        }()
3007

3008
        return timeoutErr
4✔
3009
}
3010

3011
// waitForFundingWithTimeout is a wrapper around waitForFundingConfirmation and
3012
// waitForTimeout that will return ErrConfirmationTimeout if we are not the
3013
// channel initiator and the MaxWaitNumBlocksFundingConf has passed from the
3014
// funding broadcast height. In case of confirmation, the short channel ID of
3015
// the channel and the funding transaction will be returned.
3016
func (f *Manager) waitForFundingWithTimeout(
3017
        ch *channeldb.OpenChannel) (*confirmedChannel, error) {
61✔
3018

61✔
3019
        confChan := make(chan *confirmedChannel)
61✔
3020
        timeoutChan := make(chan error, 1)
61✔
3021
        cancelChan := make(chan struct{})
61✔
3022

61✔
3023
        f.wg.Add(1)
61✔
3024
        go f.waitForFundingConfirmation(ch, cancelChan, confChan)
61✔
3025

61✔
3026
        // If we are not the initiator, we have no money at stake and will
61✔
3027
        // timeout waiting for the funding transaction to confirm after a
61✔
3028
        // while.
61✔
3029
        if !ch.IsInitiator && !ch.IsZeroConf() {
89✔
3030
                f.wg.Add(1)
28✔
3031
                go f.waitForTimeout(ch, cancelChan, timeoutChan)
28✔
3032
        }
28✔
3033
        defer close(cancelChan)
61✔
3034

61✔
3035
        select {
61✔
3036
        case err := <-timeoutChan:
4✔
3037
                if err != nil {
4✔
3038
                        return nil, err
×
3039
                }
×
3040
                return nil, ErrConfirmationTimeout
4✔
3041

3042
        case <-f.quit:
25✔
3043
                // The fundingManager is shutting down, and will resume wait on
25✔
3044
                // startup.
25✔
3045
                return nil, ErrFundingManagerShuttingDown
25✔
3046

3047
        case confirmedChannel, ok := <-confChan:
36✔
3048
                if !ok {
36✔
3049
                        return nil, fmt.Errorf("waiting for funding" +
×
3050
                                "confirmation failed")
×
3051
                }
×
3052
                return confirmedChannel, nil
36✔
3053
        }
3054
}
3055

3056
// MakeFundingScript re-creates the funding script for the funding transaction
3057
// of the target channel.
3058
func MakeFundingScript(channel *channeldb.OpenChannel) ([]byte, error) {
86✔
3059
        localKey := channel.LocalChanCfg.MultiSigKey.PubKey
86✔
3060
        remoteKey := channel.RemoteChanCfg.MultiSigKey.PubKey
86✔
3061

86✔
3062
        if channel.ChanType.IsTaproot() {
93✔
3063
                pkScript, _, err := input.GenTaprootFundingScript(
7✔
3064
                        localKey, remoteKey, int64(channel.Capacity),
7✔
3065
                        channel.TapscriptRoot,
7✔
3066
                )
7✔
3067
                if err != nil {
7✔
3068
                        return nil, err
×
3069
                }
×
3070

3071
                return pkScript, nil
7✔
3072
        }
3073

3074
        multiSigScript, err := input.GenMultiSigScript(
81✔
3075
                localKey.SerializeCompressed(),
81✔
3076
                remoteKey.SerializeCompressed(),
81✔
3077
        )
81✔
3078
        if err != nil {
81✔
3079
                return nil, err
×
3080
        }
×
3081

3082
        return input.WitnessScriptHash(multiSigScript)
81✔
3083
}
3084

3085
// waitForFundingConfirmation handles the final stages of the channel funding
3086
// process once the funding transaction has been broadcast. The primary
3087
// function of waitForFundingConfirmation is to wait for blockchain
3088
// confirmation, and then to notify the other systems that must be notified
3089
// when a channel has become active for lightning transactions. It also updates
3090
// the channel’s opening transaction block height in the database.
3091
// The wait can be canceled by closing the cancelChan. In case of success,
3092
// a *lnwire.ShortChannelID will be passed to confChan.
3093
//
3094
// NOTE: This MUST be run as a goroutine.
3095
func (f *Manager) waitForFundingConfirmation(
3096
        completeChan *channeldb.OpenChannel, cancelChan <-chan struct{},
3097
        confChan chan<- *confirmedChannel) {
61✔
3098

61✔
3099
        defer f.wg.Done()
61✔
3100
        defer close(confChan)
61✔
3101

61✔
3102
        // Register with the ChainNotifier for a notification once the funding
61✔
3103
        // transaction reaches `numConfs` confirmations.
61✔
3104
        txid := completeChan.FundingOutpoint.Hash
61✔
3105
        fundingScript, err := MakeFundingScript(completeChan)
61✔
3106
        if err != nil {
61✔
3107
                log.Errorf("unable to create funding script for "+
×
3108
                        "ChannelPoint(%v): %v", completeChan.FundingOutpoint,
×
3109
                        err)
×
3110
                return
×
3111
        }
×
3112
        numConfs := uint32(completeChan.NumConfsRequired)
61✔
3113

61✔
3114
        // If the underlying channel is a zero-conf channel, we'll set numConfs
61✔
3115
        // to 6, since it will be zero here.
61✔
3116
        if completeChan.IsZeroConf() {
69✔
3117
                numConfs = 6
8✔
3118
        }
8✔
3119

3120
        confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
61✔
3121
                &txid, fundingScript, numConfs,
61✔
3122
                completeChan.BroadcastHeight(),
61✔
3123
        )
61✔
3124
        if err != nil {
61✔
3125
                log.Errorf("Unable to register for confirmation of "+
×
3126
                        "ChannelPoint(%v): %v", completeChan.FundingOutpoint,
×
3127
                        err)
×
3128
                return
×
3129
        }
×
3130

3131
        log.Infof("Waiting for funding tx (%v) to reach %v confirmations",
61✔
3132
                txid, numConfs)
61✔
3133

61✔
3134
        // Wait until the specified number of confirmations has been reached,
61✔
3135
        // we get a cancel signal, or the wallet signals a shutdown.
61✔
3136
        for {
148✔
3137
                select {
87✔
3138
                case updDetails, ok := <-confNtfn.Updates:
26✔
3139
                        if !ok {
26✔
3140
                                log.Warnf("ChainNotifier shutting down, "+
×
3141
                                        "cannot process updates for "+
×
3142
                                        "ChannelPoint(%v)",
×
3143
                                        completeChan.FundingOutpoint)
×
3144

×
3145
                                return
×
3146
                        }
×
3147

3148
                        log.Debugf("funding tx %s received confirmation in "+
26✔
3149
                                "block %d, %d confirmations left", txid,
26✔
3150
                                updDetails.BlockHeight, updDetails.NumConfsLeft)
26✔
3151

26✔
3152
                        // Only update the ConfirmationHeight the first time a
26✔
3153
                        // confirmation is received, since on subsequent
26✔
3154
                        // confirmations the block height will remain the same.
26✔
3155
                        if completeChan.ConfirmationHeight == 0 {
52✔
3156
                                err := completeChan.MarkConfirmationHeight(
26✔
3157
                                        updDetails.BlockHeight,
26✔
3158
                                )
26✔
3159
                                if err != nil {
26✔
3160
                                        log.Errorf("failed to update "+
×
3161
                                                "confirmed state for "+
×
3162
                                                "ChannelPoint(%v): %v",
×
3163
                                                completeChan.FundingOutpoint,
×
3164
                                                err)
×
3165

×
3166
                                        return
×
3167
                                }
×
3168
                        }
3169

3170
                case _, ok := <-confNtfn.NegativeConf:
4✔
3171
                        if !ok {
4✔
3172
                                log.Warnf("ChainNotifier shutting down, "+
×
3173
                                        "cannot track negative confirmations "+
×
3174
                                        "for ChannelPoint(%v)",
×
3175
                                        completeChan.FundingOutpoint)
×
3176

×
3177
                                return
×
3178
                        }
×
3179

3180
                        log.Warnf("funding tx %s was reorged out; channel "+
4✔
3181
                                "point: %s", txid, completeChan.FundingOutpoint)
4✔
3182

4✔
3183
                        // Reset the confirmation height to 0 because the
4✔
3184
                        // funding transaction was reorged out.
4✔
3185
                        err := completeChan.MarkConfirmationHeight(uint32(0))
4✔
3186
                        if err != nil {
4✔
3187
                                log.Errorf("failed to update state for "+
×
3188
                                        "ChannelPoint(%v): %v",
×
3189
                                        completeChan.FundingOutpoint, err)
×
3190

×
3191
                                return
×
3192
                        }
×
3193

3194
                case confDetails, ok := <-confNtfn.Confirmed:
36✔
3195
                        if !ok {
36✔
3196
                                log.Warnf("ChainNotifier shutting down, "+
×
3197
                                        "cannot complete funding flow for "+
×
3198
                                        "ChannelPoint(%v)",
×
3199
                                        completeChan.FundingOutpoint)
×
3200

×
3201
                                return
×
3202
                        }
×
3203

3204
                        log.Debugf("funding tx %s for ChannelPoint(%v) "+
36✔
3205
                                "confirmed in block %d", txid,
36✔
3206
                                completeChan.FundingOutpoint,
36✔
3207
                                confDetails.BlockHeight)
36✔
3208

36✔
3209
                        // In the case of requiring a single confirmation, it
36✔
3210
                        // can happen that the `Confirmed` channel is read
36✔
3211
                        // from first, in which case the confirmation height
36✔
3212
                        // will not be set. If this happens, we take the
36✔
3213
                        // confirmation height from the `Confirmed` channel.
36✔
3214
                        if completeChan.ConfirmationHeight == 0 {
50✔
3215
                                err := completeChan.MarkConfirmationHeight(
14✔
3216
                                        confDetails.BlockHeight,
14✔
3217
                                )
14✔
3218
                                if err != nil {
14✔
3219
                                        log.Errorf("failed to update "+
×
3220
                                                "confirmed state for "+
×
3221
                                                "ChannelPoint(%v): %v",
×
3222
                                                completeChan.FundingOutpoint,
×
3223
                                                err)
×
3224

×
3225
                                        return
×
3226
                                }
×
3227
                        }
3228

3229
                        err := f.handleConfirmation(
36✔
3230
                                confDetails, completeChan, confChan,
36✔
3231
                        )
36✔
3232
                        if err != nil {
36✔
3233
                                log.Errorf("Error handling confirmation for "+
×
3234
                                        "ChannelPoint(%v), txid=%v: %v",
×
3235
                                        completeChan.FundingOutpoint, txid, err)
×
3236
                        }
×
3237

3238
                        return
36✔
3239

3240
                case <-cancelChan:
5✔
3241
                        log.Warnf("canceled waiting for funding confirmation, "+
5✔
3242
                                "stopping funding flow for ChannelPoint(%v)",
5✔
3243
                                completeChan.FundingOutpoint)
5✔
3244

5✔
3245
                        return
5✔
3246

3247
                case <-f.quit:
24✔
3248
                        log.Warnf("fundingManager shutting down, stopping "+
24✔
3249
                                "funding flow for ChannelPoint(%v)",
24✔
3250
                                completeChan.FundingOutpoint)
24✔
3251

24✔
3252
                        return
24✔
3253
                }
3254
        }
3255
}
3256

3257
// handleConfirmation is a helper function that constructs a ShortChannelID
3258
// based on the confirmation details and sends this information, along with the
3259
// funding transaction, to the provided confirmation channel.
3260
func (f *Manager) handleConfirmation(confDetails *chainntnfs.TxConfirmation,
3261
        completeChan *channeldb.OpenChannel,
3262
        confChan chan<- *confirmedChannel) error {
36✔
3263

36✔
3264
        fundingPoint := completeChan.FundingOutpoint
36✔
3265
        log.Infof("ChannelPoint(%v) is now active: ChannelID(%v)",
36✔
3266
                fundingPoint, lnwire.NewChanIDFromOutPoint(fundingPoint))
36✔
3267

36✔
3268
        // With the block height and the transaction index known, we can
36✔
3269
        // construct the compact chanID which is used on the network to unique
36✔
3270
        // identify channels.
36✔
3271
        shortChanID := lnwire.ShortChannelID{
36✔
3272
                BlockHeight: confDetails.BlockHeight,
36✔
3273
                TxIndex:     confDetails.TxIndex,
36✔
3274
                TxPosition:  uint16(fundingPoint.Index),
36✔
3275
        }
36✔
3276

36✔
3277
        select {
36✔
3278
        case confChan <- &confirmedChannel{
3279
                shortChanID: shortChanID,
3280
                fundingTx:   confDetails.Tx,
3281
        }:
36✔
3282
        case <-f.quit:
×
3283
                return fmt.Errorf("manager shutting down")
×
3284
        }
3285

3286
        return nil
36✔
3287
}
3288

3289
// waitForTimeout will close the timeout channel if MaxWaitNumBlocksFundingConf
3290
// has passed from the broadcast height of the given channel. In case of error,
3291
// the error is sent on timeoutChan. The wait can be canceled by closing the
3292
// cancelChan.
3293
//
3294
// NOTE: timeoutChan MUST be buffered.
3295
// NOTE: This MUST be run as a goroutine.
3296
func (f *Manager) waitForTimeout(completeChan *channeldb.OpenChannel,
3297
        cancelChan <-chan struct{}, timeoutChan chan<- error) {
28✔
3298

28✔
3299
        defer f.wg.Done()
28✔
3300

28✔
3301
        epochClient, err := f.cfg.Notifier.RegisterBlockEpochNtfn(nil)
28✔
3302
        if err != nil {
28✔
3303
                timeoutChan <- fmt.Errorf("unable to register for epoch "+
×
3304
                        "notification: %v", err)
×
3305
                return
×
3306
        }
×
3307

3308
        defer epochClient.Cancel()
28✔
3309

28✔
3310
        // The value of waitBlocksForFundingConf is adjusted in a development
28✔
3311
        // environment to enhance test capabilities. Otherwise, it is set to
28✔
3312
        // DefaultMaxWaitNumBlocksFundingConf.
28✔
3313
        waitBlocksForFundingConf := uint32(
28✔
3314
                lncfg.DefaultMaxWaitNumBlocksFundingConf,
28✔
3315
        )
28✔
3316

28✔
3317
        if lncfg.IsDevBuild() {
30✔
3318
                waitBlocksForFundingConf =
2✔
3319
                        f.cfg.Dev.MaxWaitNumBlocksFundingConf
2✔
3320
        }
2✔
3321

3322
        // On block maxHeight we will cancel the funding confirmation wait.
3323
        broadcastHeight := completeChan.BroadcastHeight()
28✔
3324
        maxHeight := broadcastHeight + waitBlocksForFundingConf
28✔
3325
        for {
58✔
3326
                select {
30✔
3327
                case epoch, ok := <-epochClient.Epochs:
6✔
3328
                        if !ok {
6✔
3329
                                timeoutChan <- fmt.Errorf("epoch client " +
×
3330
                                        "shutting down")
×
3331
                                return
×
3332
                        }
×
3333

3334
                        // Close the timeout channel and exit if the block is
3335
                        // above the max height.
3336
                        if uint32(epoch.Height) >= maxHeight {
10✔
3337
                                log.Warnf("Waited for %v blocks without "+
4✔
3338
                                        "seeing funding transaction confirmed,"+
4✔
3339
                                        " cancelling.",
4✔
3340
                                        waitBlocksForFundingConf)
4✔
3341

4✔
3342
                                // Notify the caller of the timeout.
4✔
3343
                                close(timeoutChan)
4✔
3344
                                return
4✔
3345
                        }
4✔
3346

3347
                        // TODO: If we are the channel initiator implement
3348
                        // a method for recovering the funds from the funding
3349
                        // transaction
3350

3351
                case <-cancelChan:
17✔
3352
                        return
17✔
3353

3354
                case <-f.quit:
11✔
3355
                        // The fundingManager is shutting down, will resume
11✔
3356
                        // waiting for the funding transaction on startup.
11✔
3357
                        return
11✔
3358
                }
3359
        }
3360
}
3361

3362
// makeLabelForTx updates the label for the confirmed funding transaction. If
3363
// we opened the channel, and lnd's wallet published our funding tx (which is
3364
// not the case for some channels) then we update our transaction label with
3365
// our short channel ID, which is known now that our funding transaction has
3366
// confirmed. We do not label transactions we did not publish, because our
3367
// wallet has no knowledge of them.
3368
func (f *Manager) makeLabelForTx(c *channeldb.OpenChannel) {
36✔
3369
        if c.IsInitiator && c.ChanType.HasFundingTx() {
54✔
3370
                shortChanID := c.ShortChanID()
18✔
3371

18✔
3372
                // For zero-conf channels, we'll use the actually-confirmed
18✔
3373
                // short channel id.
18✔
3374
                if c.IsZeroConf() {
22✔
3375
                        shortChanID = c.ZeroConfRealScid()
4✔
3376
                }
4✔
3377

3378
                label := labels.MakeLabel(
18✔
3379
                        labels.LabelTypeChannelOpen, &shortChanID,
18✔
3380
                )
18✔
3381

18✔
3382
                err := f.cfg.UpdateLabel(c.FundingOutpoint.Hash, label)
18✔
3383
                if err != nil {
18✔
3384
                        log.Errorf("unable to update label: %v", err)
×
3385
                }
×
3386
        }
3387
}
3388

3389
// handleFundingConfirmation marks a channel as open in the database, and set
3390
// the channelOpeningState markedOpen. In addition it will report the now
3391
// decided short channel ID to the switch, and close the local discovery signal
3392
// for this channel.
3393
func (f *Manager) handleFundingConfirmation(
3394
        completeChan *channeldb.OpenChannel,
3395
        confChannel *confirmedChannel) error {
32✔
3396

32✔
3397
        fundingPoint := completeChan.FundingOutpoint
32✔
3398
        chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
32✔
3399

32✔
3400
        // TODO(roasbeef): ideally persistent state update for chan above
32✔
3401
        // should be abstracted
32✔
3402

32✔
3403
        // Now that that the channel has been fully confirmed, we'll request
32✔
3404
        // that the wallet fully verify this channel to ensure that it can be
32✔
3405
        // used.
32✔
3406
        err := f.cfg.Wallet.ValidateChannel(completeChan, confChannel.fundingTx)
32✔
3407
        if err != nil {
32✔
3408
                // TODO(roasbeef): delete chan state?
×
3409
                return fmt.Errorf("unable to validate channel: %w", err)
×
3410
        }
×
3411

3412
        // Now that the channel has been validated, we'll persist an alias for
3413
        // this channel if the option-scid-alias feature-bit was negotiated.
3414
        if completeChan.NegotiatedAliasFeature() {
36✔
3415
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
4✔
3416
                if err != nil {
4✔
3417
                        return fmt.Errorf("unable to request alias: %w", err)
×
3418
                }
×
3419

3420
                err = f.cfg.AliasManager.AddLocalAlias(
4✔
3421
                        aliasScid, confChannel.shortChanID, true, false,
4✔
3422
                )
4✔
3423
                if err != nil {
4✔
3424
                        return fmt.Errorf("unable to request alias: %w", err)
×
3425
                }
×
3426
        }
3427

3428
        // The funding transaction now being confirmed, we add this channel to
3429
        // the fundingManager's internal persistent state machine that we use
3430
        // to track the remaining process of the channel opening. This is
3431
        // useful to resume the opening process in case of restarts. We set the
3432
        // opening state before we mark the channel opened in the database,
3433
        // such that we can receover from one of the db writes failing.
3434
        err = f.saveChannelOpeningState(
32✔
3435
                &fundingPoint, markedOpen, &confChannel.shortChanID,
32✔
3436
        )
32✔
3437
        if err != nil {
32✔
3438
                return fmt.Errorf("error setting channel state to "+
×
3439
                        "markedOpen: %v", err)
×
3440
        }
×
3441

3442
        // Now that the channel has been fully confirmed and we successfully
3443
        // saved the opening state, we'll mark it as open within the database.
3444
        err = completeChan.MarkAsOpen(confChannel.shortChanID)
32✔
3445
        if err != nil {
32✔
3446
                return fmt.Errorf("error setting channel pending flag to "+
×
3447
                        "false:        %v", err)
×
3448
        }
×
3449

3450
        // Update the confirmed funding transaction label.
3451
        f.makeLabelForTx(completeChan)
32✔
3452

32✔
3453
        // Inform the ChannelNotifier that the channel has transitioned from
32✔
3454
        // pending open to open.
32✔
3455
        f.cfg.NotifyOpenChannelEvent(
32✔
3456
                completeChan.FundingOutpoint, completeChan.IdentityPub,
32✔
3457
        )
32✔
3458

32✔
3459
        // Close the discoverySignal channel, indicating to a separate
32✔
3460
        // goroutine that the channel now is marked as open in the database
32✔
3461
        // and that it is acceptable to process channel_ready messages
32✔
3462
        // from the peer.
32✔
3463
        if discoverySignal, ok := f.localDiscoverySignals.Load(chanID); ok {
64✔
3464
                close(discoverySignal)
32✔
3465
        }
32✔
3466

3467
        return nil
32✔
3468
}
3469

3470
// sendChannelReady creates and sends the channelReady message.
3471
// This should be called after the funding transaction has been confirmed,
3472
// and the channelState is 'markedOpen'.
3473
func (f *Manager) sendChannelReady(completeChan *channeldb.OpenChannel,
3474
        channel *lnwallet.LightningChannel) error {
37✔
3475

37✔
3476
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
37✔
3477

37✔
3478
        var peerKey [33]byte
37✔
3479
        copy(peerKey[:], completeChan.IdentityPub.SerializeCompressed())
37✔
3480

37✔
3481
        // Next, we'll send over the channel_ready message which marks that we
37✔
3482
        // consider the channel open by presenting the remote party with our
37✔
3483
        // next revocation key. Without the revocation key, the remote party
37✔
3484
        // will be unable to propose state transitions.
37✔
3485
        nextRevocation, err := channel.NextRevocationKey()
37✔
3486
        if err != nil {
37✔
3487
                return fmt.Errorf("unable to create next revocation: %w", err)
×
3488
        }
×
3489
        channelReadyMsg := lnwire.NewChannelReady(chanID, nextRevocation)
37✔
3490

37✔
3491
        // If this is a taproot channel, then we also need to send along our
37✔
3492
        // set of musig2 nonces as well.
37✔
3493
        if completeChan.ChanType.IsTaproot() {
43✔
3494
                log.Infof("ChanID(%v): generating musig2 nonces...",
6✔
3495
                        chanID)
6✔
3496

6✔
3497
                f.nonceMtx.Lock()
6✔
3498
                localNonce, ok := f.pendingMusigNonces[chanID]
6✔
3499
                if !ok {
12✔
3500
                        // If we don't have any nonces generated yet for this
6✔
3501
                        // first state, then we'll generate them now and stow
6✔
3502
                        // them away.  When we receive the funding locked
6✔
3503
                        // message, we'll then pass along this same set of
6✔
3504
                        // nonces.
6✔
3505
                        newNonce, err := channel.GenMusigNonces()
6✔
3506
                        if err != nil {
6✔
3507
                                f.nonceMtx.Unlock()
×
3508
                                return err
×
3509
                        }
×
3510

3511
                        // Now that we've generated the nonce for this channel,
3512
                        // we'll store it in the set of pending nonces.
3513
                        localNonce = newNonce
6✔
3514
                        f.pendingMusigNonces[chanID] = localNonce
6✔
3515
                }
3516
                f.nonceMtx.Unlock()
6✔
3517

6✔
3518
                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce(
6✔
3519
                        localNonce.PubNonce,
6✔
3520
                )
6✔
3521
        }
3522

3523
        // If the channel negotiated the option-scid-alias feature bit, we'll
3524
        // send a TLV segment that includes an alias the peer can use in their
3525
        // invoice hop hints. We'll send the first alias we find for the
3526
        // channel since it does not matter which alias we send. We'll error
3527
        // out in the odd case that no aliases are found.
3528
        if completeChan.NegotiatedAliasFeature() {
45✔
3529
                aliases := f.cfg.AliasManager.GetAliases(
8✔
3530
                        completeChan.ShortChanID(),
8✔
3531
                )
8✔
3532
                if len(aliases) == 0 {
8✔
3533
                        return fmt.Errorf("no aliases found")
×
3534
                }
×
3535

3536
                // We can use a pointer to aliases since GetAliases returns a
3537
                // copy of the alias slice.
3538
                channelReadyMsg.AliasScid = &aliases[0]
8✔
3539
        }
3540

3541
        // If the peer has disconnected before we reach this point, we will need
3542
        // to wait for him to come back online before sending the channelReady
3543
        // message. This is special for channelReady, since failing to send any
3544
        // of the previous messages in the funding flow just cancels the flow.
3545
        // But now the funding transaction is confirmed, the channel is open
3546
        // and we have to make sure the peer gets the channelReady message when
3547
        // it comes back online. This is also crucial during restart of lnd,
3548
        // where we might try to resend the channelReady message before the
3549
        // server has had the time to connect to the peer. We keep trying to
3550
        // send channelReady until we succeed, or the fundingManager is shut
3551
        // down.
3552
        for {
74✔
3553
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
37✔
3554
                if err != nil {
38✔
3555
                        return err
1✔
3556
                }
1✔
3557

3558
                localAlias := peer.LocalFeatures().HasFeature(
36✔
3559
                        lnwire.ScidAliasOptional,
36✔
3560
                )
36✔
3561
                remoteAlias := peer.RemoteFeatures().HasFeature(
36✔
3562
                        lnwire.ScidAliasOptional,
36✔
3563
                )
36✔
3564

36✔
3565
                // We could also refresh the channel state instead of checking
36✔
3566
                // whether the feature was negotiated, but this saves us a
36✔
3567
                // database read.
36✔
3568
                if channelReadyMsg.AliasScid == nil && localAlias &&
36✔
3569
                        remoteAlias {
36✔
3570

×
3571
                        // If an alias was not assigned above and the scid
×
3572
                        // alias feature was negotiated, check if we already
×
3573
                        // have an alias stored in case handleChannelReady was
×
3574
                        // called before this. If an alias exists, use that in
×
3575
                        // channel_ready. Otherwise, request and store an
×
3576
                        // alias and use that.
×
3577
                        aliases := f.cfg.AliasManager.GetAliases(
×
3578
                                completeChan.ShortChannelID,
×
3579
                        )
×
3580
                        if len(aliases) == 0 {
×
3581
                                // No aliases were found.
×
3582
                                alias, err := f.cfg.AliasManager.RequestAlias()
×
3583
                                if err != nil {
×
3584
                                        return err
×
3585
                                }
×
3586

3587
                                err = f.cfg.AliasManager.AddLocalAlias(
×
3588
                                        alias, completeChan.ShortChannelID,
×
3589
                                        false, false,
×
3590
                                )
×
3591
                                if err != nil {
×
3592
                                        return err
×
3593
                                }
×
3594

3595
                                channelReadyMsg.AliasScid = &alias
×
3596
                        } else {
×
3597
                                channelReadyMsg.AliasScid = &aliases[0]
×
3598
                        }
×
3599
                }
3600

3601
                log.Infof("Peer(%x) is online, sending ChannelReady "+
36✔
3602
                        "for ChannelID(%v)", peerKey, chanID)
36✔
3603

36✔
3604
                if err := peer.SendMessage(true, channelReadyMsg); err == nil {
72✔
3605
                        // Sending succeeded, we can break out and continue the
36✔
3606
                        // funding flow.
36✔
3607
                        break
36✔
3608
                }
3609

3610
                log.Warnf("Unable to send channelReady to peer %x: %v. "+
×
3611
                        "Will retry when online", peerKey, err)
×
3612
        }
3613

3614
        return nil
36✔
3615
}
3616

3617
// receivedChannelReady checks whether or not we've received a ChannelReady
3618
// from the remote peer. If we have, RemoteNextRevocation will be set.
3619
func (f *Manager) receivedChannelReady(node *btcec.PublicKey,
3620
        chanID lnwire.ChannelID) (bool, error) {
62✔
3621

62✔
3622
        // If the funding manager has exited, return an error to stop looping.
62✔
3623
        // Note that the peer may appear as online while the funding manager
62✔
3624
        // has stopped due to the shutdown order in the server.
62✔
3625
        select {
62✔
3626
        case <-f.quit:
×
3627
                return false, ErrFundingManagerShuttingDown
×
3628
        default:
62✔
3629
        }
3630

3631
        // Avoid a tight loop if peer is offline.
3632
        if _, err := f.waitForPeerOnline(node); err != nil {
62✔
UNCOV
3633
                log.Errorf("Wait for peer online failed: %v", err)
×
UNCOV
3634
                return false, err
×
UNCOV
3635
        }
×
3636

3637
        // If we cannot find the channel, then we haven't processed the
3638
        // remote's channelReady message.
3639
        channel, err := f.cfg.FindChannel(node, chanID)
62✔
3640
        if err != nil {
62✔
3641
                log.Errorf("Unable to locate ChannelID(%v) to determine if "+
×
3642
                        "ChannelReady was received", chanID)
×
3643
                return false, err
×
3644
        }
×
3645

3646
        // If we haven't insert the next revocation point, we haven't finished
3647
        // processing the channel ready message.
3648
        if channel.RemoteNextRevocation == nil {
98✔
3649
                return false, nil
36✔
3650
        }
36✔
3651

3652
        // Finally, the barrier signal is removed once we finish
3653
        // `handleChannelReady`. If we can still find the signal, we haven't
3654
        // finished processing it yet.
3655
        _, loaded := f.handleChannelReadyBarriers.Load(chanID)
28✔
3656

28✔
3657
        return !loaded, nil
28✔
3658
}
3659

3660
// extractAnnounceParams extracts the various channel announcement and update
3661
// parameters that will be needed to construct a ChannelAnnouncement and a
3662
// ChannelUpdate.
3663
func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) (
3664
        lnwire.MilliSatoshi, lnwire.MilliSatoshi) {
28✔
3665

28✔
3666
        // We'll obtain the min HTLC value we can forward in our direction, as
28✔
3667
        // we'll use this value within our ChannelUpdate. This constraint is
28✔
3668
        // originally set by the remote node, as it will be the one that will
28✔
3669
        // need to determine the smallest HTLC it deems economically relevant.
28✔
3670
        fwdMinHTLC := c.LocalChanCfg.MinHTLC
28✔
3671

28✔
3672
        // We don't necessarily want to go as low as the remote party allows.
28✔
3673
        // Check it against our default forwarding policy.
28✔
3674
        if fwdMinHTLC < f.cfg.DefaultRoutingPolicy.MinHTLCOut {
30✔
3675
                fwdMinHTLC = f.cfg.DefaultRoutingPolicy.MinHTLCOut
2✔
3676
        }
2✔
3677

3678
        // We'll obtain the max HTLC value we can forward in our direction, as
3679
        // we'll use this value within our ChannelUpdate. This value must be <=
3680
        // channel capacity and <= the maximum in-flight msats set by the peer.
3681
        fwdMaxHTLC := c.LocalChanCfg.MaxPendingAmount
28✔
3682
        capacityMSat := lnwire.NewMSatFromSatoshis(c.Capacity)
28✔
3683
        if fwdMaxHTLC > capacityMSat {
28✔
3684
                fwdMaxHTLC = capacityMSat
×
3685
        }
×
3686

3687
        return fwdMinHTLC, fwdMaxHTLC
28✔
3688
}
3689

3690
// addToGraph sends a ChannelAnnouncement and a ChannelUpdate to the
3691
// gossiper so that the channel is added to the graph builder's internal graph.
3692
// These announcement messages are NOT broadcasted to the greater network,
3693
// only to the channel counter party. The proofs required to announce the
3694
// channel to the greater network will be created and sent in annAfterSixConfs.
3695
// The peerAlias is used for zero-conf channels to give the counter-party a
3696
// ChannelUpdate they understand. ourPolicy may be set for various
3697
// option-scid-alias channels to re-use the same policy.
3698
func (f *Manager) addToGraph(completeChan *channeldb.OpenChannel,
3699
        shortChanID *lnwire.ShortChannelID,
3700
        peerAlias *lnwire.ShortChannelID,
3701
        ourPolicy *models.ChannelEdgePolicy) error {
28✔
3702

28✔
3703
        chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
28✔
3704

28✔
3705
        fwdMinHTLC, fwdMaxHTLC := f.extractAnnounceParams(completeChan)
28✔
3706

28✔
3707
        ann, err := f.newChanAnnouncement(
28✔
3708
                f.cfg.IDKey, completeChan.IdentityPub,
28✔
3709
                &completeChan.LocalChanCfg.MultiSigKey,
28✔
3710
                completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
28✔
3711
                chanID, fwdMinHTLC, fwdMaxHTLC, ourPolicy,
28✔
3712
                completeChan.ChanType,
28✔
3713
        )
28✔
3714
        if err != nil {
28✔
3715
                return fmt.Errorf("error generating channel "+
×
3716
                        "announcement: %v", err)
×
3717
        }
×
3718

3719
        // Send ChannelAnnouncement and ChannelUpdate to the gossiper to add
3720
        // to the Router's topology.
3721
        errChan := f.cfg.SendAnnouncement(
28✔
3722
                ann.chanAnn, discovery.ChannelCapacity(completeChan.Capacity),
28✔
3723
                discovery.ChannelPoint(completeChan.FundingOutpoint),
28✔
3724
                discovery.TapscriptRoot(completeChan.TapscriptRoot),
28✔
3725
        )
28✔
3726
        select {
28✔
3727
        case err := <-errChan:
28✔
3728
                if err != nil {
28✔
3729
                        if graph.IsError(err, graph.ErrOutdated,
×
3730
                                graph.ErrIgnored) {
×
3731

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

3743
        errChan = f.cfg.SendAnnouncement(
28✔
3744
                ann.chanUpdateAnn, discovery.RemoteAlias(peerAlias),
28✔
3745
        )
28✔
3746
        select {
28✔
3747
        case err := <-errChan:
28✔
3748
                if err != nil {
28✔
3749
                        if graph.IsError(err, graph.ErrOutdated,
×
3750
                                graph.ErrIgnored) {
×
3751

×
3752
                                log.Debugf("Graph rejected "+
×
3753
                                        "ChannelUpdate: %v", err)
×
3754
                        } else {
×
3755
                                return fmt.Errorf("error sending channel "+
×
3756
                                        "update: %v", err)
×
3757
                        }
×
3758
                }
3759
        case <-f.quit:
×
3760
                return ErrFundingManagerShuttingDown
×
3761
        }
3762

3763
        return nil
28✔
3764
}
3765

3766
// annAfterSixConfs broadcasts the necessary channel announcement messages to
3767
// the network after 6 confs. Should be called after the channelReady message
3768
// is sent and the channel is added to the graph (channelState is
3769
// 'addedToGraph') and the channel is ready to be used. This is the last
3770
// step in the channel opening process, and the opening state will be deleted
3771
// from the database if successful.
3772
func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
3773
        shortChanID *lnwire.ShortChannelID) error {
28✔
3774

28✔
3775
        // If this channel is not meant to be announced to the greater network,
28✔
3776
        // we'll only send our NodeAnnouncement1 to our counterparty to ensure
28✔
3777
        // we don't leak any of our information.
28✔
3778
        announceChan := completeChan.ChannelFlags&lnwire.FFAnnounceChannel != 0
28✔
3779
        if !announceChan {
38✔
3780
                log.Debugf("Will not announce private channel %v.",
10✔
3781
                        shortChanID.ToUint64())
10✔
3782

10✔
3783
                peer, err := f.waitForPeerOnline(completeChan.IdentityPub)
10✔
3784
                if err != nil {
10✔
3785
                        return err
×
3786
                }
×
3787

3788
                nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
10✔
3789
                if err != nil {
10✔
3790
                        return fmt.Errorf("unable to retrieve current node "+
×
3791
                                "announcement: %v", err)
×
3792
                }
×
3793

3794
                chanID := lnwire.NewChanIDFromOutPoint(
10✔
3795
                        completeChan.FundingOutpoint,
10✔
3796
                )
10✔
3797
                pubKey := peer.PubKey()
10✔
3798
                log.Debugf("Sending our NodeAnnouncement1 for "+
10✔
3799
                        "ChannelID(%v) to %x", chanID, pubKey)
10✔
3800

10✔
3801
                // TODO(halseth): make reliable. If the peer is not online this
10✔
3802
                // will fail, and the opening process will stop. Should instead
10✔
3803
                // block here, waiting for the peer to come online.
10✔
3804
                if err := peer.SendMessage(true, &nodeAnn); err != nil {
10✔
3805
                        return fmt.Errorf("unable to send node announcement "+
×
3806
                                "to peer %x: %v", pubKey, err)
×
3807
                }
×
3808
        } else {
20✔
3809
                // Otherwise, we'll wait until the funding transaction has
20✔
3810
                // reached 6 confirmations before announcing it.
20✔
3811
                numConfs := uint32(completeChan.NumConfsRequired)
20✔
3812
                if numConfs < 6 {
40✔
3813
                        numConfs = 6
20✔
3814
                }
20✔
3815
                txid := completeChan.FundingOutpoint.Hash
20✔
3816
                log.Debugf("Will announce channel %v after ChannelPoint"+
20✔
3817
                        "(%v) has gotten %d confirmations",
20✔
3818
                        shortChanID.ToUint64(), completeChan.FundingOutpoint,
20✔
3819
                        numConfs)
20✔
3820

20✔
3821
                fundingScript, err := MakeFundingScript(completeChan)
20✔
3822
                if err != nil {
20✔
3823
                        return fmt.Errorf("unable to create funding script "+
×
3824
                                "for ChannelPoint(%v): %v",
×
3825
                                completeChan.FundingOutpoint, err)
×
3826
                }
×
3827

3828
                // Register with the ChainNotifier for a notification once the
3829
                // funding transaction reaches at least 6 confirmations.
3830
                confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
20✔
3831
                        &txid, fundingScript, numConfs,
20✔
3832
                        completeChan.BroadcastHeight(),
20✔
3833
                )
20✔
3834
                if err != nil {
20✔
3835
                        return fmt.Errorf("unable to register for "+
×
3836
                                "confirmation of ChannelPoint(%v): %v",
×
3837
                                completeChan.FundingOutpoint, err)
×
3838
                }
×
3839

3840
                // Wait until 6 confirmations has been reached or the wallet
3841
                // signals a shutdown.
3842
                select {
20✔
3843
                case _, ok := <-confNtfn.Confirmed:
18✔
3844
                        if !ok {
18✔
3845
                                return fmt.Errorf("ChainNotifier shutting "+
×
3846
                                        "down, cannot complete funding flow "+
×
3847
                                        "for ChannelPoint(%v)",
×
3848
                                        completeChan.FundingOutpoint)
×
3849
                        }
×
3850
                        // Fallthrough.
3851

3852
                case <-f.quit:
4✔
3853
                        return fmt.Errorf("%v, stopping funding flow for "+
4✔
3854
                                "ChannelPoint(%v)",
4✔
3855
                                ErrFundingManagerShuttingDown,
4✔
3856
                                completeChan.FundingOutpoint)
4✔
3857
                }
3858

3859
                fundingPoint := completeChan.FundingOutpoint
18✔
3860
                chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
18✔
3861

18✔
3862
                log.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
18✔
3863
                        &fundingPoint, shortChanID)
18✔
3864

18✔
3865
                // If this is a non-zero-conf option-scid-alias channel, we'll
18✔
3866
                // delete the mappings the gossiper uses so that ChannelUpdates
18✔
3867
                // with aliases won't be accepted. This is done elsewhere for
18✔
3868
                // zero-conf channels.
18✔
3869
                isScidFeature := completeChan.NegotiatedAliasFeature()
18✔
3870
                isZeroConf := completeChan.IsZeroConf()
18✔
3871
                if isScidFeature && !isZeroConf {
20✔
3872
                        baseScid := completeChan.ShortChanID()
2✔
3873
                        err := f.cfg.AliasManager.DeleteSixConfs(baseScid)
2✔
3874
                        if err != nil {
2✔
3875
                                return fmt.Errorf("failed deleting six confs "+
×
3876
                                        "maps: %v", err)
×
3877
                        }
×
3878

3879
                        // We'll delete the edge and add it again via
3880
                        // addToGraph. This is because the peer may have
3881
                        // sent us a ChannelUpdate with an alias and we don't
3882
                        // want to relay this.
3883
                        ourPolicy, err := f.cfg.DeleteAliasEdge(baseScid)
2✔
3884
                        if err != nil {
2✔
3885
                                return fmt.Errorf("failed deleting real edge "+
×
3886
                                        "for alias channel from graph: %v",
×
3887
                                        err)
×
3888
                        }
×
3889

3890
                        err = f.addToGraph(
2✔
3891
                                completeChan, &baseScid, nil, ourPolicy,
2✔
3892
                        )
2✔
3893
                        if err != nil {
2✔
3894
                                return fmt.Errorf("failed to re-add to "+
×
3895
                                        "graph: %v", err)
×
3896
                        }
×
3897
                }
3898

3899
                // Create and broadcast the proofs required to make this channel
3900
                // public and usable for other nodes for routing.
3901
                err = f.announceChannel(
18✔
3902
                        f.cfg.IDKey, completeChan.IdentityPub,
18✔
3903
                        &completeChan.LocalChanCfg.MultiSigKey,
18✔
3904
                        completeChan.RemoteChanCfg.MultiSigKey.PubKey,
18✔
3905
                        *shortChanID, chanID, completeChan.ChanType,
18✔
3906
                )
18✔
3907
                if err != nil {
20✔
3908
                        return fmt.Errorf("channel announcement failed: %w",
2✔
3909
                                err)
2✔
3910
                }
2✔
3911

3912
                log.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
18✔
3913
                        "sent to gossiper", &fundingPoint, shortChanID)
18✔
3914
        }
3915

3916
        return nil
26✔
3917
}
3918

3919
// waitForZeroConfChannel is called when the state is addedToGraph with
3920
// a zero-conf channel. This will wait for the real confirmation, add the
3921
// confirmed SCID to the router graph, and then announce after six confs.
3922
func (f *Manager) waitForZeroConfChannel(c *channeldb.OpenChannel) error {
8✔
3923
        // First we'll check whether the channel is confirmed on-chain. If it
8✔
3924
        // is already confirmed, the chainntnfs subsystem will return with the
8✔
3925
        // confirmed tx. Otherwise, we'll wait here until confirmation occurs.
8✔
3926
        confChan, err := f.waitForFundingWithTimeout(c)
8✔
3927
        if err != nil {
12✔
3928
                return fmt.Errorf("error waiting for zero-conf funding "+
4✔
3929
                        "confirmation for ChannelPoint(%v): %v",
4✔
3930
                        c.FundingOutpoint, err)
4✔
3931
        }
4✔
3932

3933
        // We'll need to refresh the channel state so that things are properly
3934
        // populated when validating the channel state. Otherwise, a panic may
3935
        // occur due to inconsistency in the OpenChannel struct.
3936
        err = c.Refresh()
6✔
3937
        if err != nil {
8✔
3938
                return fmt.Errorf("unable to refresh channel state: %w", err)
2✔
3939
        }
2✔
3940

3941
        // Now that we have the confirmed transaction and the proper SCID,
3942
        // we'll call ValidateChannel to ensure the confirmed tx is properly
3943
        // formatted.
3944
        err = f.cfg.Wallet.ValidateChannel(c, confChan.fundingTx)
6✔
3945
        if err != nil {
6✔
3946
                return fmt.Errorf("unable to validate zero-conf channel: "+
×
3947
                        "%v", err)
×
3948
        }
×
3949

3950
        // Once we know the confirmed ShortChannelID, we'll need to save it to
3951
        // the database and refresh the OpenChannel struct with it.
3952
        err = c.MarkRealScid(confChan.shortChanID)
6✔
3953
        if err != nil {
6✔
3954
                return fmt.Errorf("unable to set confirmed SCID for zero "+
×
3955
                        "channel: %v", err)
×
3956
        }
×
3957

3958
        // Six confirmations have been reached. If this channel is public,
3959
        // we'll delete some of the alias mappings the gossiper uses.
3960
        //
3961
        // Tell the Switch to refresh the relevant ChannelLink so that forwards
3962
        // under the confirmed SCID are possible. We do this BEFORE updating the
3963
        // graph to avoid a race where other nodes learn about the confirmed
3964
        // SCID from gossip before our switch is ready to handle forwards using
3965
        // it. This is especially important for integration tests.
3966
        err = f.cfg.ReportShortChanID(c.FundingOutpoint)
6✔
3967
        if err != nil {
6✔
3968
                // This should only fail if the link is not found in the
×
3969
                // Switch's linkIndex map. If this is the case, then the peer
×
3970
                // has gone offline and the next time the link is loaded, it
×
3971
                // will have a refreshed state. Just log an error here.
×
3972
                log.Errorf("unable to report scid for zero-conf channel "+
×
3973
                        "channel: %v", err)
×
3974
        }
×
3975

3976
        isPublic := c.ChannelFlags&lnwire.FFAnnounceChannel != 0
6✔
3977
        if isPublic {
10✔
3978
                err = f.cfg.AliasManager.DeleteSixConfs(c.ShortChannelID)
4✔
3979
                if err != nil {
4✔
3980
                        return fmt.Errorf("unable to delete base alias after "+
×
3981
                                "six confirmations: %v", err)
×
3982
                }
×
3983

3984
                // TODO: Make this atomic!
3985
                ourPolicy, err := f.cfg.DeleteAliasEdge(c.ShortChanID())
4✔
3986
                if err != nil {
4✔
3987
                        return fmt.Errorf("unable to delete alias edge from "+
×
3988
                                "graph: %v", err)
×
3989
                }
×
3990

3991
                // We'll need to update the graph with the new ShortChannelID
3992
                // via an addToGraph call. We don't pass in the peer's
3993
                // alias since we'll be using the confirmed SCID from now on
3994
                // regardless if it's public or not.
3995
                err = f.addToGraph(
4✔
3996
                        c, &confChan.shortChanID, nil, ourPolicy,
4✔
3997
                )
4✔
3998
                if err != nil {
4✔
3999
                        return fmt.Errorf("failed adding confirmed zero-conf "+
×
4000
                                "SCID to graph: %v", err)
×
4001
                }
×
4002
        }
4003

4004
        // Update the confirmed transaction's label.
4005
        f.makeLabelForTx(c)
6✔
4006

6✔
4007
        return nil
6✔
4008
}
4009

4010
// genFirstStateMusigNonce generates a nonces for the "first" local state. This
4011
// is the verification nonce for the state created for us after the initial
4012
// commitment transaction signed as part of the funding flow.
4013
func genFirstStateMusigNonce(channel *channeldb.OpenChannel,
4014
) (*musig2.Nonces, error) {
6✔
4015

6✔
4016
        musig2ShaChain, err := channeldb.DeriveMusig2Shachain(
6✔
4017
                channel.RevocationProducer,
6✔
4018
        )
6✔
4019
        if err != nil {
6✔
4020
                return nil, fmt.Errorf("unable to generate musig channel "+
×
4021
                        "nonces: %v", err)
×
4022
        }
×
4023

4024
        // We use the _next_ commitment height here as we need to generate the
4025
        // nonce for the next state the remote party will sign for us.
4026
        verNonce, err := channeldb.NewMusigVerificationNonce(
6✔
4027
                channel.LocalChanCfg.MultiSigKey.PubKey,
6✔
4028
                channel.LocalCommitment.CommitHeight+1,
6✔
4029
                musig2ShaChain,
6✔
4030
        )
6✔
4031
        if err != nil {
6✔
4032
                return nil, fmt.Errorf("unable to generate musig channel "+
×
4033
                        "nonces: %v", err)
×
4034
        }
×
4035

4036
        return verNonce, nil
6✔
4037
}
4038

4039
// handleChannelReady finalizes the channel funding process and enables the
4040
// channel to enter normal operating mode.
4041
func (f *Manager) handleChannelReady(peer lnpeer.Peer, //nolint:funlen
4042
        msg *lnwire.ChannelReady) {
30✔
4043

30✔
4044
        defer f.wg.Done()
30✔
4045

30✔
4046
        // Notify the aux hook that the specified peer just established a
30✔
4047
        // channel with us, identified by the given channel ID.
30✔
4048
        f.cfg.AuxChannelNegotiator.WhenSome(
30✔
4049
                func(acn lnwallet.AuxChannelNegotiator) {
30✔
4050
                        acn.ProcessChannelReady(msg.ChanID, peer.PubKey())
×
4051
                },
×
4052
        )
4053

4054
        // If we are in development mode, we'll wait for specified duration
4055
        // before processing the channel ready message.
4056
        if f.cfg.Dev != nil {
32✔
4057
                duration := f.cfg.Dev.ProcessChannelReadyWait
2✔
4058
                log.Warnf("Channel(%v): sleeping %v before processing "+
2✔
4059
                        "channel_ready", msg.ChanID, duration)
2✔
4060

2✔
4061
                select {
2✔
4062
                case <-time.After(duration):
2✔
4063
                        log.Warnf("Channel(%v): slept %v before processing "+
2✔
4064
                                "channel_ready", msg.ChanID, duration)
2✔
4065
                case <-f.quit:
×
4066
                        log.Warnf("Channel(%v): quit sleeping", msg.ChanID)
×
4067
                        return
×
4068
                }
4069
        }
4070

4071
        log.Debugf("Received ChannelReady for ChannelID(%v) from "+
30✔
4072
                "peer %x", msg.ChanID,
30✔
4073
                peer.IdentityKey().SerializeCompressed())
30✔
4074

30✔
4075
        // We now load or create a new channel barrier for this channel.
30✔
4076
        _, loaded := f.handleChannelReadyBarriers.LoadOrStore(
30✔
4077
                msg.ChanID, struct{}{},
30✔
4078
        )
30✔
4079

30✔
4080
        // If we are currently in the process of handling a channel_ready
30✔
4081
        // message for this channel, ignore.
30✔
4082
        if loaded {
33✔
4083
                log.Infof("Already handling channelReady for "+
3✔
4084
                        "ChannelID(%v), ignoring.", msg.ChanID)
3✔
4085
                return
3✔
4086
        }
3✔
4087

4088
        // If not already handling channelReady for this channel, then the
4089
        // `LoadOrStore` has set up a barrier, and it will be removed once this
4090
        // function exits.
4091
        defer f.handleChannelReadyBarriers.Delete(msg.ChanID)
29✔
4092

29✔
4093
        localDiscoverySignal, ok := f.localDiscoverySignals.Load(msg.ChanID)
29✔
4094
        if ok {
56✔
4095
                // Before we proceed with processing the channel_ready
27✔
4096
                // message, we'll wait for the local waitForFundingConfirmation
27✔
4097
                // goroutine to signal that it has the necessary state in
27✔
4098
                // place. Otherwise, we may be missing critical information
27✔
4099
                // required to handle forwarded HTLC's.
27✔
4100
                select {
27✔
4101
                case <-localDiscoverySignal:
27✔
4102
                        // Fallthrough
4103
                case <-f.quit:
2✔
4104
                        return
2✔
4105
                }
4106

4107
                // With the signal received, we can now safely delete the entry
4108
                // from the map.
4109
                f.localDiscoverySignals.Delete(msg.ChanID)
27✔
4110
        }
4111

4112
        // First, we'll attempt to locate the channel whose funding workflow is
4113
        // being finalized by this message. We go to the database rather than
4114
        // our reservation map as we may have restarted, mid funding flow. Also
4115
        // provide the node's public key to make the search faster.
4116
        chanID := msg.ChanID
29✔
4117
        channel, err := f.cfg.FindChannel(peer.IdentityKey(), chanID)
29✔
4118
        if err != nil {
29✔
4119
                log.Errorf("Unable to locate ChannelID(%v), cannot complete "+
×
4120
                        "funding", chanID)
×
4121
                return
×
4122
        }
×
4123

4124
        // If this is a taproot channel, then we can generate the set of nonces
4125
        // the remote party needs to send the next remote commitment here.
4126
        var firstVerNonce *musig2.Nonces
29✔
4127
        if channel.ChanType.IsTaproot() {
35✔
4128
                firstVerNonce, err = genFirstStateMusigNonce(channel)
6✔
4129
                if err != nil {
6✔
4130
                        log.Error(err)
×
4131
                        return
×
4132
                }
×
4133
        }
4134

4135
        // We'll need to store the received TLV alias if the option_scid_alias
4136
        // feature was negotiated. This will be used to provide route hints
4137
        // during invoice creation. In the zero-conf case, it is also used to
4138
        // provide a ChannelUpdate to the remote peer. This is done before the
4139
        // call to InsertNextRevocation in case the call to PutPeerAlias fails.
4140
        // If it were to fail on the first call to handleChannelReady, we
4141
        // wouldn't want the channel to be usable yet.
4142
        if channel.NegotiatedAliasFeature() {
37✔
4143
                // If the AliasScid field is nil, we must fail out. We will
8✔
4144
                // most likely not be able to route through the peer.
8✔
4145
                if msg.AliasScid == nil {
8✔
4146
                        log.Debugf("Consider closing ChannelID(%v), peer "+
×
4147
                                "does not implement the option-scid-alias "+
×
4148
                                "feature properly", chanID)
×
4149
                        return
×
4150
                }
×
4151

4152
                // We'll store the AliasScid so that invoice creation can use
4153
                // it.
4154
                err = f.cfg.AliasManager.PutPeerAlias(chanID, *msg.AliasScid)
8✔
4155
                if err != nil {
8✔
4156
                        log.Errorf("unable to store peer's alias: %v", err)
×
4157
                        return
×
4158
                }
×
4159

4160
                // If we do not have an alias stored, we'll create one now.
4161
                // This is only used in the upgrade case where a user toggles
4162
                // the option-scid-alias feature-bit to on. We'll also send the
4163
                // channel_ready message here in case the link is created
4164
                // before sendChannelReady is called.
4165
                aliases := f.cfg.AliasManager.GetAliases(
8✔
4166
                        channel.ShortChannelID,
8✔
4167
                )
8✔
4168
                if len(aliases) == 0 {
8✔
4169
                        // No aliases were found so we'll request and store an
×
4170
                        // alias and use it in the channel_ready message.
×
4171
                        alias, err := f.cfg.AliasManager.RequestAlias()
×
4172
                        if err != nil {
×
4173
                                log.Errorf("unable to request alias: %v", err)
×
4174
                                return
×
4175
                        }
×
4176

4177
                        err = f.cfg.AliasManager.AddLocalAlias(
×
4178
                                alias, channel.ShortChannelID, false, false,
×
4179
                        )
×
4180
                        if err != nil {
×
4181
                                log.Errorf("unable to add local alias: %v",
×
4182
                                        err)
×
4183
                                return
×
4184
                        }
×
4185

4186
                        secondPoint, err := channel.SecondCommitmentPoint()
×
4187
                        if err != nil {
×
4188
                                log.Errorf("unable to fetch second "+
×
4189
                                        "commitment point: %v", err)
×
4190
                                return
×
4191
                        }
×
4192

4193
                        channelReadyMsg := lnwire.NewChannelReady(
×
4194
                                chanID, secondPoint,
×
4195
                        )
×
4196
                        channelReadyMsg.AliasScid = &alias
×
4197

×
4198
                        if firstVerNonce != nil {
×
4199
                                channelReadyMsg.NextLocalNonce = lnwire.SomeMusig2Nonce( //nolint:ll
×
4200
                                        firstVerNonce.PubNonce,
×
4201
                                )
×
4202
                        }
×
4203

4204
                        err = peer.SendMessage(true, channelReadyMsg)
×
4205
                        if err != nil {
×
4206
                                log.Errorf("unable to send channel_ready: %v",
×
4207
                                        err)
×
4208
                                return
×
4209
                        }
×
4210
                }
4211
        }
4212

4213
        // If the RemoteNextRevocation is non-nil, it means that we have
4214
        // already processed channelReady for this channel, so ignore. This
4215
        // check is after the alias logic so we store the peer's most recent
4216
        // alias. The spec requires us to validate that subsequent
4217
        // channel_ready messages use the same per commitment point (the
4218
        // second), but it is not actually necessary since we'll just end up
4219
        // ignoring it. We are, however, required to *send* the same per
4220
        // commitment point, since another pedantic implementation might
4221
        // verify it.
4222
        if channel.RemoteNextRevocation != nil {
32✔
4223
                log.Infof("Received duplicate channelReady for "+
3✔
4224
                        "ChannelID(%v), ignoring.", chanID)
3✔
4225
                return
3✔
4226
        }
3✔
4227

4228
        // If this is a taproot channel, then we'll need to map the received
4229
        // nonces to a nonce pair, and also fetch our pending nonces, which are
4230
        // required in order to make the channel whole.
4231
        var chanOpts []lnwallet.ChannelOpt
28✔
4232
        if channel.ChanType.IsTaproot() {
34✔
4233
                f.nonceMtx.Lock()
6✔
4234
                localNonce, ok := f.pendingMusigNonces[chanID]
6✔
4235
                if !ok {
8✔
4236
                        // If there's no pending nonce for this channel ID,
2✔
4237
                        // we'll use the one generated above.
2✔
4238
                        localNonce = firstVerNonce
2✔
4239
                        f.pendingMusigNonces[chanID] = firstVerNonce
2✔
4240
                }
2✔
4241
                f.nonceMtx.Unlock()
6✔
4242

6✔
4243
                log.Infof("ChanID(%v): applying local+remote musig2 nonces",
6✔
4244
                        chanID)
6✔
4245

6✔
4246
                remoteNonce, err := msg.NextLocalNonce.UnwrapOrErrV(
6✔
4247
                        errNoLocalNonce,
6✔
4248
                )
6✔
4249
                if err != nil {
6✔
4250
                        cid := newChanIdentifier(msg.ChanID)
×
4251
                        f.sendWarning(peer, cid, err)
×
4252

×
4253
                        return
×
4254
                }
×
4255

4256
                chanOpts = append(
6✔
4257
                        chanOpts,
6✔
4258
                        lnwallet.WithLocalMusigNonces(localNonce),
6✔
4259
                        lnwallet.WithRemoteMusigNonces(&musig2.Nonces{
6✔
4260
                                PubNonce: remoteNonce,
6✔
4261
                        }),
6✔
4262
                )
6✔
4263

6✔
4264
                // Inform the aux funding controller that the liquidity in the
6✔
4265
                // custom channel is now ready to be advertised. We potentially
6✔
4266
                // haven't sent our own channel ready message yet, but other
6✔
4267
                // than that the channel is ready to count toward available
6✔
4268
                // liquidity.
6✔
4269
                err = fn.MapOptionZ(
6✔
4270
                        f.cfg.AuxFundingController,
6✔
4271
                        func(controller AuxFundingController) error {
6✔
4272
                                return controller.ChannelReady(
×
4273
                                        lnwallet.NewAuxChanState(channel),
×
4274
                                )
×
4275
                        },
×
4276
                )
4277
                if err != nil {
6✔
4278
                        cid := newChanIdentifier(msg.ChanID)
×
4279
                        f.sendWarning(peer, cid, err)
×
4280

×
4281
                        return
×
4282
                }
×
4283
        }
4284

4285
        // The channel_ready message contains the next commitment point we'll
4286
        // need to create the next commitment state for the remote party. So
4287
        // we'll insert that into the channel now before passing it along to
4288
        // other sub-systems.
4289
        err = channel.InsertNextRevocation(msg.NextPerCommitmentPoint)
28✔
4290
        if err != nil {
28✔
4291
                log.Errorf("unable to insert next commitment point: %v", err)
×
4292
                return
×
4293
        }
×
4294

4295
        // Before we can add the channel to the peer, we'll need to ensure that
4296
        // we have an initial forwarding policy set.
4297
        if err := f.ensureInitialForwardingPolicy(chanID, channel); err != nil {
28✔
4298
                log.Errorf("Unable to ensure initial forwarding policy: %v",
×
4299
                        err)
×
4300
        }
×
4301

4302
        err = peer.AddNewChannel(&lnpeer.NewChannel{
28✔
4303
                OpenChannel: channel,
28✔
4304
                ChanOpts:    chanOpts,
28✔
4305
        }, f.quit)
28✔
4306
        if err != nil {
28✔
4307
                log.Errorf("Unable to add new channel %v with peer %x: %v",
×
4308
                        channel.FundingOutpoint,
×
4309
                        peer.IdentityKey().SerializeCompressed(), err,
×
4310
                )
×
4311
        }
×
4312
}
4313

4314
// handleChannelReadyReceived is called once the remote's channelReady message
4315
// is received and processed. At this stage, we must have sent out our
4316
// channelReady message, once the remote's channelReady is processed, the
4317
// channel is now active, thus we change its state to `addedToGraph` to
4318
// let the channel start handling routing.
4319
func (f *Manager) handleChannelReadyReceived(channel *channeldb.OpenChannel,
4320
        scid *lnwire.ShortChannelID, pendingChanID PendingChanID,
4321
        updateChan chan<- *lnrpc.OpenStatusUpdate) error {
26✔
4322

26✔
4323
        chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
26✔
4324

26✔
4325
        // Since we've sent+received funding locked at this point, we
26✔
4326
        // can clean up the pending musig2 nonce state.
26✔
4327
        f.nonceMtx.Lock()
26✔
4328
        delete(f.pendingMusigNonces, chanID)
26✔
4329
        f.nonceMtx.Unlock()
26✔
4330

26✔
4331
        var peerAlias *lnwire.ShortChannelID
26✔
4332
        if channel.IsZeroConf() {
32✔
4333
                // We'll need to wait until channel_ready has been received and
6✔
4334
                // the peer lets us know the alias they want to use for the
6✔
4335
                // channel. With this information, we can then construct a
6✔
4336
                // ChannelUpdate for them.  If an alias does not yet exist,
6✔
4337
                // we'll just return, letting the next iteration of the loop
6✔
4338
                // check again.
6✔
4339
                var defaultAlias lnwire.ShortChannelID
6✔
4340
                chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
6✔
4341
                foundAlias, _ := f.cfg.AliasManager.GetPeerAlias(chanID)
6✔
4342
                if foundAlias == defaultAlias {
6✔
4343
                        return nil
×
4344
                }
×
4345

4346
                peerAlias = &foundAlias
6✔
4347
        }
4348

4349
        err := f.addToGraph(channel, scid, peerAlias, nil)
26✔
4350
        if err != nil {
26✔
4351
                return fmt.Errorf("failed adding to graph: %w", err)
×
4352
        }
×
4353

4354
        // As the channel is now added to the ChannelRouter's topology, the
4355
        // channel is moved to the next state of the state machine. It will be
4356
        // moved to the last state (actually deleted from the database) after
4357
        // the channel is finally announced.
4358
        err = f.saveChannelOpeningState(
26✔
4359
                &channel.FundingOutpoint, addedToGraph, scid,
26✔
4360
        )
26✔
4361
        if err != nil {
26✔
4362
                return fmt.Errorf("error setting channel state to"+
×
4363
                        " addedToGraph: %w", err)
×
4364
        }
×
4365

4366
        log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
26✔
4367
                "added to graph", chanID, scid)
26✔
4368

26✔
4369
        err = fn.MapOptionZ(
26✔
4370
                f.cfg.AuxFundingController,
26✔
4371
                func(controller AuxFundingController) error {
26✔
4372
                        return controller.ChannelReady(
×
4373
                                lnwallet.NewAuxChanState(channel),
×
4374
                        )
×
4375
                },
×
4376
        )
4377
        if err != nil {
26✔
4378
                return fmt.Errorf("failed notifying aux funding controller "+
×
4379
                        "about channel ready: %w", err)
×
4380
        }
×
4381

4382
        // Give the caller a final update notifying them that the channel is
4383
        fundingPoint := channel.FundingOutpoint
26✔
4384
        cp := &lnrpc.ChannelPoint{
26✔
4385
                FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
26✔
4386
                        FundingTxidBytes: fundingPoint.Hash[:],
26✔
4387
                },
26✔
4388
                OutputIndex: fundingPoint.Index,
26✔
4389
        }
26✔
4390

26✔
4391
        if updateChan != nil {
38✔
4392
                upd := &lnrpc.OpenStatusUpdate{
12✔
4393
                        Update: &lnrpc.OpenStatusUpdate_ChanOpen{
12✔
4394
                                ChanOpen: &lnrpc.ChannelOpenUpdate{
12✔
4395
                                        ChannelPoint: cp,
12✔
4396
                                },
12✔
4397
                        },
12✔
4398
                        PendingChanId: pendingChanID[:],
12✔
4399
                }
12✔
4400

12✔
4401
                select {
12✔
4402
                case updateChan <- upd:
12✔
4403
                case <-f.quit:
×
4404
                        return ErrFundingManagerShuttingDown
×
4405
                }
4406
        }
4407

4408
        return nil
26✔
4409
}
4410

4411
// ensureInitialForwardingPolicy ensures that we have an initial forwarding
4412
// policy set for the given channel. If we don't, we'll fall back to the default
4413
// values.
4414
func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID,
4415
        channel *channeldb.OpenChannel) error {
28✔
4416

28✔
4417
        // Before we can add the channel to the peer, we'll need to ensure that
28✔
4418
        // we have an initial forwarding policy set. This should always be the
28✔
4419
        // case except for a channel that was created with lnd <= 0.15.5 and
28✔
4420
        // is still pending while updating to this version.
28✔
4421
        var needDBUpdate bool
28✔
4422
        forwardingPolicy, err := f.getInitialForwardingPolicy(chanID)
28✔
4423
        if err != nil {
28✔
4424
                log.Errorf("Unable to fetch initial forwarding policy, "+
×
4425
                        "falling back to default values: %v", err)
×
4426

×
4427
                forwardingPolicy = f.defaultForwardingPolicy(
×
4428
                        channel.LocalChanCfg.ChannelStateBounds,
×
4429
                )
×
4430
                needDBUpdate = true
×
4431
        }
×
4432

4433
        // We only started storing the actual values for MinHTLCOut and MaxHTLC
4434
        // after 0.16.x, so if a channel was opened with such a version and is
4435
        // still pending while updating to this version, we'll need to set the
4436
        // values to the default values.
4437
        if forwardingPolicy.MinHTLCOut == 0 {
43✔
4438
                forwardingPolicy.MinHTLCOut = channel.LocalChanCfg.MinHTLC
15✔
4439
                needDBUpdate = true
15✔
4440
        }
15✔
4441
        if forwardingPolicy.MaxHTLC == 0 {
43✔
4442
                forwardingPolicy.MaxHTLC = channel.LocalChanCfg.MaxPendingAmount
15✔
4443
                needDBUpdate = true
15✔
4444
        }
15✔
4445

4446
        // And finally, if we found that the values currently stored aren't
4447
        // sufficient for the link, we'll update the database.
4448
        if needDBUpdate {
43✔
4449
                err := f.saveInitialForwardingPolicy(chanID, forwardingPolicy)
15✔
4450
                if err != nil {
15✔
4451
                        return fmt.Errorf("unable to update initial "+
×
4452
                                "forwarding policy: %v", err)
×
4453
                }
×
4454
        }
4455

4456
        return nil
28✔
4457
}
4458

4459
// chanAnnouncement encapsulates the two authenticated announcements that we
4460
// send out to the network after a new channel has been created locally.
4461
type chanAnnouncement struct {
4462
        chanAnn       *lnwire.ChannelAnnouncement1
4463
        chanUpdateAnn *lnwire.ChannelUpdate1
4464
        chanProof     *lnwire.AnnounceSignatures1
4465
}
4466

4467
// newChanAnnouncement creates the authenticated channel announcement messages
4468
// required to broadcast a newly created channel to the network. The
4469
// announcement is two part: the first part authenticates the existence of the
4470
// channel and contains four signatures binding the funding pub keys and
4471
// identity pub keys of both parties to the channel, and the second segment is
4472
// authenticated only by us and contains our directional routing policy for the
4473
// channel. ourPolicy may be set in order to re-use an existing, non-default
4474
// policy.
4475
func (f *Manager) newChanAnnouncement(localPubKey,
4476
        remotePubKey *btcec.PublicKey, localFundingKey *keychain.KeyDescriptor,
4477
        remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
4478
        chanID lnwire.ChannelID, fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi,
4479
        ourPolicy *models.ChannelEdgePolicy,
4480
        chanType channeldb.ChannelType) (*chanAnnouncement, error) {
44✔
4481

44✔
4482
        chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
44✔
4483

44✔
4484
        // The unconditional section of the announcement is the ShortChannelID
44✔
4485
        // itself which compactly encodes the location of the funding output
44✔
4486
        // within the blockchain.
44✔
4487
        chanAnn := &lnwire.ChannelAnnouncement1{
44✔
4488
                ShortChannelID: shortChanID,
44✔
4489
                Features:       lnwire.NewRawFeatureVector(),
44✔
4490
                ChainHash:      chainHash,
44✔
4491
        }
44✔
4492

44✔
4493
        // If this is a taproot channel, then we'll set a special bit in the
44✔
4494
        // feature vector to indicate to the routing layer that this needs a
44✔
4495
        // slightly different type of validation.
44✔
4496
        //
44✔
4497
        // TODO(roasbeef): temp, remove after gossip 1.5
44✔
4498
        if chanType.IsTaproot() {
50✔
4499
                log.Debugf("Applying taproot feature bit to "+
6✔
4500
                        "ChannelAnnouncement for %v", chanID)
6✔
4501

6✔
4502
                chanAnn.Features.Set(
6✔
4503
                        lnwire.SimpleTaprootChannelsRequiredStaging,
6✔
4504
                )
6✔
4505
        }
6✔
4506

4507
        // The chanFlags field indicates which directed edge of the channel is
4508
        // being updated within the ChannelUpdateAnnouncement announcement
4509
        // below. A value of zero means it's the edge of the "first" node and 1
4510
        // being the other node.
4511
        var chanFlags lnwire.ChanUpdateChanFlags
44✔
4512

44✔
4513
        // The lexicographical ordering of the two identity public keys of the
44✔
4514
        // nodes indicates which of the nodes is "first". If our serialized
44✔
4515
        // identity key is lower than theirs then we're the "first" node and
44✔
4516
        // second otherwise.
44✔
4517
        selfBytes := localPubKey.SerializeCompressed()
44✔
4518
        remoteBytes := remotePubKey.SerializeCompressed()
44✔
4519
        if bytes.Compare(selfBytes, remoteBytes) == -1 {
67✔
4520
                copy(chanAnn.NodeID1[:], localPubKey.SerializeCompressed())
23✔
4521
                copy(chanAnn.NodeID2[:], remotePubKey.SerializeCompressed())
23✔
4522
                copy(
23✔
4523
                        chanAnn.BitcoinKey1[:],
23✔
4524
                        localFundingKey.PubKey.SerializeCompressed(),
23✔
4525
                )
23✔
4526
                copy(
23✔
4527
                        chanAnn.BitcoinKey2[:],
23✔
4528
                        remoteFundingKey.SerializeCompressed(),
23✔
4529
                )
23✔
4530

23✔
4531
                // If we're the first node then update the chanFlags to
23✔
4532
                // indicate the "direction" of the update.
23✔
4533
                chanFlags = 0
23✔
4534
        } else {
46✔
4535
                copy(chanAnn.NodeID1[:], remotePubKey.SerializeCompressed())
23✔
4536
                copy(chanAnn.NodeID2[:], localPubKey.SerializeCompressed())
23✔
4537
                copy(
23✔
4538
                        chanAnn.BitcoinKey1[:],
23✔
4539
                        remoteFundingKey.SerializeCompressed(),
23✔
4540
                )
23✔
4541
                copy(
23✔
4542
                        chanAnn.BitcoinKey2[:],
23✔
4543
                        localFundingKey.PubKey.SerializeCompressed(),
23✔
4544
                )
23✔
4545

23✔
4546
                // If we're the second node then update the chanFlags to
23✔
4547
                // indicate the "direction" of the update.
23✔
4548
                chanFlags = 1
23✔
4549
        }
23✔
4550

4551
        // Our channel update message flags will signal that we support the
4552
        // max_htlc field.
4553
        msgFlags := lnwire.ChanUpdateRequiredMaxHtlc
44✔
4554

44✔
4555
        // We announce the channel with the default values. Some of
44✔
4556
        // these values can later be changed by crafting a new ChannelUpdate.
44✔
4557
        chanUpdateAnn := &lnwire.ChannelUpdate1{
44✔
4558
                ShortChannelID: shortChanID,
44✔
4559
                ChainHash:      chainHash,
44✔
4560
                Timestamp:      uint32(time.Now().Unix()),
44✔
4561
                MessageFlags:   msgFlags,
44✔
4562
                ChannelFlags:   chanFlags,
44✔
4563
                TimeLockDelta: uint16(
44✔
4564
                        f.cfg.DefaultRoutingPolicy.TimeLockDelta,
44✔
4565
                ),
44✔
4566
                HtlcMinimumMsat: fwdMinHTLC,
44✔
4567
                HtlcMaximumMsat: fwdMaxHTLC,
44✔
4568
        }
44✔
4569

44✔
4570
        // The caller of newChanAnnouncement is expected to provide the initial
44✔
4571
        // forwarding policy to be announced. If no persisted initial policy
44✔
4572
        // values are found, then we will use the default policy values in the
44✔
4573
        // channel announcement.
44✔
4574
        storedFwdingPolicy, err := f.getInitialForwardingPolicy(chanID)
44✔
4575
        if err != nil && !errors.Is(err, channeldb.ErrChannelNotFound) {
44✔
4576
                return nil, fmt.Errorf("unable to generate channel "+
×
4577
                        "update announcement: %w", err)
×
4578
        }
×
4579

4580
        switch {
44✔
4581
        case ourPolicy != nil:
2✔
4582
                // If ourPolicy is non-nil, modify the default parameters of the
2✔
4583
                // ChannelUpdate.
2✔
4584
                chanUpdateAnn.MessageFlags = ourPolicy.MessageFlags
2✔
4585
                chanUpdateAnn.ChannelFlags = ourPolicy.ChannelFlags
2✔
4586
                chanUpdateAnn.TimeLockDelta = ourPolicy.TimeLockDelta
2✔
4587
                chanUpdateAnn.HtlcMinimumMsat = ourPolicy.MinHTLC
2✔
4588
                chanUpdateAnn.HtlcMaximumMsat = ourPolicy.MaxHTLC
2✔
4589
                chanUpdateAnn.BaseFee = uint32(ourPolicy.FeeBaseMSat)
2✔
4590
                chanUpdateAnn.FeeRate = uint32(
2✔
4591
                        ourPolicy.FeeProportionalMillionths,
2✔
4592
                )
2✔
4593

4594
        case storedFwdingPolicy != nil:
44✔
4595
                chanUpdateAnn.BaseFee = uint32(storedFwdingPolicy.BaseFee)
44✔
4596
                chanUpdateAnn.FeeRate = uint32(storedFwdingPolicy.FeeRate)
44✔
4597

4598
        default:
×
4599
                log.Infof("No channel forwarding policy specified for channel "+
×
4600
                        "announcement of ChannelID(%v). "+
×
4601
                        "Assuming default fee parameters.", chanID)
×
4602
                chanUpdateAnn.BaseFee = uint32(
×
4603
                        f.cfg.DefaultRoutingPolicy.BaseFee,
×
4604
                )
×
4605
                chanUpdateAnn.FeeRate = uint32(
×
4606
                        f.cfg.DefaultRoutingPolicy.FeeRate,
×
4607
                )
×
4608
        }
4609

4610
        // With the channel update announcement constructed, we'll generate a
4611
        // signature that signs a double-sha digest of the announcement.
4612
        // This'll serve to authenticate this announcement and any other future
4613
        // updates we may send.
4614
        chanUpdateMsg, err := chanUpdateAnn.DataToSign()
44✔
4615
        if err != nil {
44✔
4616
                return nil, err
×
4617
        }
×
4618
        sig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanUpdateMsg, true)
44✔
4619
        if err != nil {
44✔
4620
                return nil, fmt.Errorf("unable to generate channel "+
×
4621
                        "update announcement signature: %w", err)
×
4622
        }
×
4623
        chanUpdateAnn.Signature, err = lnwire.NewSigFromSignature(sig)
44✔
4624
        if err != nil {
44✔
4625
                return nil, fmt.Errorf("unable to generate channel "+
×
4626
                        "update announcement signature: %w", err)
×
4627
        }
×
4628

4629
        // The channel existence proofs itself is currently announced in
4630
        // distinct message. In order to properly authenticate this message, we
4631
        // need two signatures: one under the identity public key used which
4632
        // signs the message itself and another signature of the identity
4633
        // public key under the funding key itself.
4634
        //
4635
        // TODO(roasbeef): use SignAnnouncement here instead?
4636
        chanAnnMsg, err := chanAnn.DataToSign()
44✔
4637
        if err != nil {
44✔
4638
                return nil, err
×
4639
        }
×
4640
        nodeSig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanAnnMsg, true)
44✔
4641
        if err != nil {
44✔
4642
                return nil, fmt.Errorf("unable to generate node "+
×
4643
                        "signature for channel announcement: %w", err)
×
4644
        }
×
4645
        bitcoinSig, err := f.cfg.SignMessage(
44✔
4646
                localFundingKey.KeyLocator, chanAnnMsg, true,
44✔
4647
        )
44✔
4648
        if err != nil {
44✔
4649
                return nil, fmt.Errorf("unable to generate bitcoin "+
×
4650
                        "signature for node public key: %w", err)
×
4651
        }
×
4652

4653
        // Finally, we'll generate the announcement proof which we'll use to
4654
        // provide the other side with the necessary signatures required to
4655
        // allow them to reconstruct the full channel announcement.
4656
        proof := &lnwire.AnnounceSignatures1{
44✔
4657
                ChannelID:      chanID,
44✔
4658
                ShortChannelID: shortChanID,
44✔
4659
        }
44✔
4660
        proof.NodeSignature, err = lnwire.NewSigFromSignature(nodeSig)
44✔
4661
        if err != nil {
44✔
4662
                return nil, err
×
4663
        }
×
4664
        proof.BitcoinSignature, err = lnwire.NewSigFromSignature(bitcoinSig)
44✔
4665
        if err != nil {
44✔
4666
                return nil, err
×
4667
        }
×
4668

4669
        return &chanAnnouncement{
44✔
4670
                chanAnn:       chanAnn,
44✔
4671
                chanUpdateAnn: chanUpdateAnn,
44✔
4672
                chanProof:     proof,
44✔
4673
        }, nil
44✔
4674
}
4675

4676
// announceChannel announces a newly created channel to the rest of the network
4677
// by crafting the two authenticated announcements required for the peers on
4678
// the network to recognize the legitimacy of the channel. The crafted
4679
// announcements are then sent to the channel router to handle broadcasting to
4680
// the network during its next trickle.
4681
// This method is synchronous and will return when all the network requests
4682
// finish, either successfully or with an error.
4683
func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
4684
        localFundingKey *keychain.KeyDescriptor,
4685
        remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
4686
        chanID lnwire.ChannelID, chanType channeldb.ChannelType) error {
18✔
4687

18✔
4688
        // First, we'll create the batch of announcements to be sent upon
18✔
4689
        // initial channel creation. This includes the channel announcement
18✔
4690
        // itself, the channel update announcement, and our half of the channel
18✔
4691
        // proof needed to fully authenticate the channel.
18✔
4692
        //
18✔
4693
        // We can pass in zeroes for the min and max htlc policy, because we
18✔
4694
        // only use the channel announcement message from the returned struct.
18✔
4695
        ann, err := f.newChanAnnouncement(
18✔
4696
                localIDKey, remoteIDKey, localFundingKey, remoteFundingKey,
18✔
4697
                shortChanID, chanID, 0, 0, nil, chanType,
18✔
4698
        )
18✔
4699
        if err != nil {
18✔
4700
                log.Errorf("can't generate channel announcement: %v", err)
×
4701
                return err
×
4702
        }
×
4703

4704
        // We only send the channel proof announcement and the node announcement
4705
        // because addToGraph previously sent the ChannelAnnouncement and
4706
        // the ChannelUpdate announcement messages. The channel proof and node
4707
        // announcements are broadcast to the greater network.
4708
        errChan := f.cfg.SendAnnouncement(ann.chanProof)
18✔
4709
        select {
18✔
4710
        case err := <-errChan:
18✔
4711
                if err != nil {
20✔
4712
                        if graph.IsError(err, graph.ErrOutdated,
2✔
4713
                                graph.ErrIgnored) {
2✔
4714

×
4715
                                log.Debugf("Graph rejected "+
×
4716
                                        "AnnounceSignatures: %v", err)
×
4717
                        } else {
2✔
4718
                                log.Errorf("Unable to send channel "+
2✔
4719
                                        "proof: %v", err)
2✔
4720
                                return err
2✔
4721
                        }
2✔
4722
                }
4723

4724
        case <-f.quit:
×
4725
                return ErrFundingManagerShuttingDown
×
4726
        }
4727

4728
        // Now that the channel is announced to the network, we will also
4729
        // obtain and send a node announcement. This is done since a node
4730
        // announcement is only accepted after a channel is known for that
4731
        // particular node, and this might be our first channel.
4732
        nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
18✔
4733
        if err != nil {
18✔
4734
                log.Errorf("can't generate node announcement: %v", err)
×
4735
                return err
×
4736
        }
×
4737

4738
        errChan = f.cfg.SendAnnouncement(&nodeAnn)
18✔
4739
        select {
18✔
4740
        case err := <-errChan:
18✔
4741
                if err != nil {
20✔
4742
                        if graph.IsError(err, graph.ErrOutdated,
2✔
4743
                                graph.ErrIgnored) {
4✔
4744

2✔
4745
                                log.Debugf("Graph rejected "+
2✔
4746
                                        "NodeAnnouncement1: %v", err)
2✔
4747
                        } else {
2✔
4748
                                log.Errorf("Unable to send node "+
×
4749
                                        "announcement: %v", err)
×
4750
                                return err
×
4751
                        }
×
4752
                }
4753

4754
        case <-f.quit:
×
4755
                return ErrFundingManagerShuttingDown
×
4756
        }
4757

4758
        return nil
18✔
4759
}
4760

4761
// InitFundingWorkflow sends a message to the funding manager instructing it
4762
// to initiate a single funder workflow with the source peer.
4763
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
59✔
4764
        f.fundingRequests <- msg
59✔
4765
}
59✔
4766

4767
// getUpfrontShutdownScript takes a user provided script and a getScript
4768
// function which can be used to generate an upfront shutdown script. If our
4769
// peer does not support the feature, this function will error if a non-zero
4770
// script was provided by the user, and return an empty script otherwise. If
4771
// our peer does support the feature, we will return the user provided script
4772
// if non-zero, or a freshly generated script if our node is configured to set
4773
// upfront shutdown scripts automatically.
4774
func getUpfrontShutdownScript(enableUpfrontShutdown bool, peer lnpeer.Peer,
4775
        script lnwire.DeliveryAddress,
4776
        getScript func(bool) (lnwire.DeliveryAddress, error)) (lnwire.DeliveryAddress,
4777
        error) {
112✔
4778

112✔
4779
        // Check whether the remote peer supports upfront shutdown scripts.
112✔
4780
        remoteUpfrontShutdown := peer.RemoteFeatures().HasFeature(
112✔
4781
                lnwire.UpfrontShutdownScriptOptional,
112✔
4782
        )
112✔
4783

112✔
4784
        // If the peer does not support upfront shutdown scripts, and one has been
112✔
4785
        // provided, return an error because the feature is not supported.
112✔
4786
        if !remoteUpfrontShutdown && len(script) != 0 {
113✔
4787
                return nil, errUpfrontShutdownScriptNotSupported
1✔
4788
        }
1✔
4789

4790
        // If the peer does not support upfront shutdown, return an empty address.
4791
        if !remoteUpfrontShutdown {
216✔
4792
                return nil, nil
105✔
4793
        }
105✔
4794

4795
        // If the user has provided an script and the peer supports the feature,
4796
        // return it. Note that user set scripts override the enable upfront
4797
        // shutdown flag.
4798
        if len(script) > 0 {
10✔
4799
                return script, nil
4✔
4800
        }
4✔
4801

4802
        // If we do not have setting of upfront shutdown script enabled, return
4803
        // an empty script.
4804
        if !enableUpfrontShutdown {
7✔
4805
                return nil, nil
3✔
4806
        }
3✔
4807

4808
        // We can safely send a taproot address iff, both sides have negotiated
4809
        // the shutdown-any-segwit feature.
4810
        taprootOK := peer.RemoteFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) &&
1✔
4811
                peer.LocalFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional)
1✔
4812

1✔
4813
        return getScript(taprootOK)
1✔
4814
}
4815

4816
// handleInitFundingMsg creates a channel reservation within the daemon's
4817
// wallet, then sends a funding request to the remote peer kicking off the
4818
// funding workflow.
4819
func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
59✔
4820
        var (
59✔
4821
                peerKey        = msg.Peer.IdentityKey()
59✔
4822
                localAmt       = msg.LocalFundingAmt
59✔
4823
                baseFee        = msg.BaseFee
59✔
4824
                feeRate        = msg.FeeRate
59✔
4825
                minHtlcIn      = msg.MinHtlcIn
59✔
4826
                remoteCsvDelay = msg.RemoteCsvDelay
59✔
4827
                maxValue       = msg.MaxValueInFlight
59✔
4828
                maxHtlcs       = msg.MaxHtlcs
59✔
4829
                maxCSV         = msg.MaxLocalCsv
59✔
4830
                chanReserve    = msg.RemoteChanReserve
59✔
4831
                outpoints      = msg.Outpoints
59✔
4832
        )
59✔
4833

59✔
4834
        // If no maximum CSV delay was set for this channel, we use our default
59✔
4835
        // value.
59✔
4836
        if maxCSV == 0 {
118✔
4837
                maxCSV = f.cfg.MaxLocalCSVDelay
59✔
4838
        }
59✔
4839

4840
        log.Infof("Initiating fundingRequest(local_amt=%v "+
59✔
4841
                "(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
59✔
4842
                "min_confs=%v)", localAmt, msg.SubtractFees, msg.PushAmt,
59✔
4843
                msg.ChainHash, peerKey.SerializeCompressed(), msg.MinConfs)
59✔
4844

59✔
4845
        // We set the channel flags to indicate whether we want this channel to
59✔
4846
        // be announced to the network.
59✔
4847
        var channelFlags lnwire.FundingFlag
59✔
4848
        if !msg.Private {
113✔
4849
                // This channel will be announced.
54✔
4850
                channelFlags = lnwire.FFAnnounceChannel
54✔
4851
        }
54✔
4852

4853
        // If the caller specified their own channel ID, then we'll use that.
4854
        // Otherwise we'll generate a fresh one as normal.  This will be used
4855
        // to track this reservation throughout its lifetime.
4856
        var chanID PendingChanID
59✔
4857
        if msg.PendingChanID == zeroID {
118✔
4858
                chanID = f.nextPendingChanID()
59✔
4859
        } else {
61✔
4860
                // If the user specified their own pending channel ID, then
2✔
4861
                // we'll ensure it doesn't collide with any existing pending
2✔
4862
                // channel ID.
2✔
4863
                chanID = msg.PendingChanID
2✔
4864
                if _, err := f.getReservationCtx(peerKey, chanID); err == nil {
2✔
4865
                        msg.Err <- fmt.Errorf("pendingChannelID(%x) "+
×
4866
                                "already present", chanID[:])
×
4867
                        return
×
4868
                }
×
4869
        }
4870

4871
        // If the funder did not provide an upfront-shutdown address, fall back
4872
        // to the configured shutdown script (if any).
4873
        shutdownScript := msg.ShutdownScript
59✔
4874
        if len(shutdownScript) == 0 {
118✔
4875
                f.cfg.ShutdownScript.WhenSome(
59✔
4876
                        func(script lnwire.DeliveryAddress) {
61✔
4877
                                shutdownScript = script
2✔
4878
                        },
2✔
4879
                )
4880
        }
4881

4882
        // Check whether the peer supports upfront shutdown, and get an address
4883
        // which should be used (either a user specified address or a new
4884
        // address from the wallet if our node is configured to set shutdown
4885
        // address by default).
4886
        shutdown, err := getUpfrontShutdownScript(
59✔
4887
                f.cfg.EnableUpfrontShutdown, msg.Peer, shutdownScript,
59✔
4888
                f.selectShutdownScript,
59✔
4889
        )
59✔
4890
        if err != nil {
59✔
4891
                msg.Err <- err
×
4892
                return
×
4893
        }
×
4894

4895
        // Initialize a funding reservation with the local wallet. If the
4896
        // wallet doesn't have enough funds to commit to this channel, then the
4897
        // request will fail, and be aborted.
4898
        //
4899
        // Before we init the channel, we'll also check to see what commitment
4900
        // format we can use with this peer. This is dependent on *both* us and
4901
        // the remote peer are signaling the proper feature bit.
4902
        chanType, commitType, err := negotiateCommitmentType(
59✔
4903
                msg.ChannelType, msg.Peer.LocalFeatures(),
59✔
4904
                msg.Peer.RemoteFeatures(),
59✔
4905
        )
59✔
4906
        if err != nil {
61✔
4907
                log.Errorf("channel type negotiation failed: %v", err)
2✔
4908
                msg.Err <- err
2✔
4909
                return
2✔
4910
        }
2✔
4911

4912
        var (
59✔
4913
                zeroConf bool
59✔
4914
                scid     bool
59✔
4915
        )
59✔
4916

59✔
4917
        if chanType != nil {
65✔
4918
                // Check if the returned chanType includes either the zero-conf
6✔
4919
                // or scid-alias bits.
6✔
4920
                featureVec := lnwire.RawFeatureVector(*chanType)
6✔
4921
                zeroConf = featureVec.IsSet(lnwire.ZeroConfRequired)
6✔
4922
                scid = featureVec.IsSet(lnwire.ScidAliasRequired)
6✔
4923

6✔
4924
                // The option-scid-alias channel type for a public channel is
6✔
4925
                // disallowed.
6✔
4926
                if scid && !msg.Private {
6✔
4927
                        err = fmt.Errorf("option-scid-alias chantype for " +
×
4928
                                "public channel")
×
4929
                        log.Error(err)
×
4930
                        msg.Err <- err
×
4931

×
4932
                        return
×
4933
                }
×
4934
        }
4935

4936
        // First, we'll query the fee estimator for a fee that should get the
4937
        // commitment transaction confirmed by the next few blocks (conf target
4938
        // of 3). We target the near blocks here to ensure that we'll be able
4939
        // to execute a timely unilateral channel closure if needed.
4940
        commitFeePerKw, err := f.cfg.FeeEstimator.EstimateFeePerKW(3)
59✔
4941
        if err != nil {
59✔
4942
                msg.Err <- err
×
4943
                return
×
4944
        }
×
4945

4946
        // For anchor channels cap the initial commit fee rate at our defined
4947
        // maximum.
4948
        if commitType.HasAnchors() &&
59✔
4949
                commitFeePerKw > f.cfg.MaxAnchorsCommitFeeRate {
65✔
4950

6✔
4951
                commitFeePerKw = f.cfg.MaxAnchorsCommitFeeRate
6✔
4952
        }
6✔
4953

4954
        var scidFeatureVal bool
59✔
4955
        if hasFeatures(
59✔
4956
                msg.Peer.LocalFeatures(), msg.Peer.RemoteFeatures(),
59✔
4957
                lnwire.ScidAliasOptional,
59✔
4958
        ) {
64✔
4959

5✔
4960
                scidFeatureVal = true
5✔
4961
        }
5✔
4962

4963
        // At this point, if we have an AuxFundingController active, we'll check
4964
        // to see if we have a special tapscript root to use in our MuSig2
4965
        // funding output.
4966
        tapscriptRoot, err := fn.MapOptionZ(
59✔
4967
                f.cfg.AuxFundingController,
59✔
4968
                func(c AuxFundingController) AuxTapscriptResult {
59✔
4969
                        return c.DeriveTapscriptRoot(chanID)
×
4970
                },
×
4971
        ).Unpack()
4972
        if err != nil {
59✔
4973
                err = fmt.Errorf("error deriving tapscript root: %w", err)
×
4974
                log.Error(err)
×
4975
                msg.Err <- err
×
4976

×
4977
                return
×
4978
        }
×
4979

4980
        req := &lnwallet.InitFundingReserveMsg{
59✔
4981
                ChainHash:         &msg.ChainHash,
59✔
4982
                PendingChanID:     chanID,
59✔
4983
                NodeID:            peerKey,
59✔
4984
                NodeAddr:          msg.Peer.Address(),
59✔
4985
                SubtractFees:      msg.SubtractFees,
59✔
4986
                LocalFundingAmt:   localAmt,
59✔
4987
                RemoteFundingAmt:  0,
59✔
4988
                FundUpToMaxAmt:    msg.FundUpToMaxAmt,
59✔
4989
                MinFundAmt:        msg.MinFundAmt,
59✔
4990
                RemoteChanReserve: chanReserve,
59✔
4991
                Outpoints:         outpoints,
59✔
4992
                CommitFeePerKw:    commitFeePerKw,
59✔
4993
                FundingFeePerKw:   msg.FundingFeePerKw,
59✔
4994
                PushMSat:          msg.PushAmt,
59✔
4995
                Flags:             channelFlags,
59✔
4996
                MinConfs:          msg.MinConfs,
59✔
4997
                CommitType:        commitType,
59✔
4998
                ChanFunder:        msg.ChanFunder,
59✔
4999
                // Unconfirmed Utxos which are marked by the sweeper subsystem
59✔
5000
                // are excluded from the coin selection because they are not
59✔
5001
                // final and can be RBFed by the sweeper subsystem.
59✔
5002
                AllowUtxoForFunding: func(u lnwallet.Utxo) bool {
119✔
5003
                        // Utxos with at least 1 confirmation are safe to use
60✔
5004
                        // for channel openings because they don't bare the risk
60✔
5005
                        // of being replaced (BIP 125 RBF).
60✔
5006
                        if u.Confirmations > 0 {
62✔
5007
                                return true
2✔
5008
                        }
2✔
5009

5010
                        // Query the sweeper storage to make sure we don't use
5011
                        // an unconfirmed utxo still in use by the sweeper
5012
                        // subsystem.
5013
                        return !f.cfg.IsSweeperOutpoint(u.OutPoint)
60✔
5014
                },
5015
                ZeroConf:         zeroConf,
5016
                OptionScidAlias:  scid,
5017
                ScidAliasFeature: scidFeatureVal,
5018
                Memo:             msg.Memo,
5019
                TapscriptRoot:    tapscriptRoot,
5020
        }
5021

5022
        reservation, err := f.cfg.Wallet.InitChannelReservation(req)
59✔
5023
        if err != nil {
61✔
5024
                msg.Err <- err
2✔
5025
                return
2✔
5026
        }
2✔
5027

5028
        if zeroConf {
63✔
5029
                // Store the alias for zero-conf channels in the underlying
4✔
5030
                // partial channel state.
4✔
5031
                aliasScid, err := f.cfg.AliasManager.RequestAlias()
4✔
5032
                if err != nil {
4✔
5033
                        msg.Err <- err
×
5034
                        return
×
5035
                }
×
5036

5037
                reservation.AddAlias(aliasScid)
4✔
5038
        }
5039

5040
        // Set our upfront shutdown address in the existing reservation.
5041
        reservation.SetOurUpfrontShutdown(shutdown)
59✔
5042

59✔
5043
        // Now that we have successfully reserved funds for this channel in the
59✔
5044
        // wallet, we can fetch the final channel capacity. This is done at
59✔
5045
        // this point since the final capacity might change in case of
59✔
5046
        // SubtractFees=true.
59✔
5047
        capacity := reservation.Capacity()
59✔
5048

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

59✔
5052
        // If the remote CSV delay was not set in the open channel request,
59✔
5053
        // we'll use the RequiredRemoteDelay closure to compute the delay we
59✔
5054
        // require given the total amount of funds within the channel.
59✔
5055
        if remoteCsvDelay == 0 {
117✔
5056
                remoteCsvDelay = f.cfg.RequiredRemoteDelay(capacity)
58✔
5057
        }
58✔
5058

5059
        // If no minimum HTLC value was specified, use the default one.
5060
        if minHtlcIn == 0 {
117✔
5061
                minHtlcIn = f.cfg.DefaultMinHtlcIn
58✔
5062
        }
58✔
5063

5064
        // If no max value was specified, use the default one.
5065
        if maxValue == 0 {
117✔
5066
                maxValue = f.cfg.RequiredRemoteMaxValue(capacity)
58✔
5067
        }
58✔
5068

5069
        if maxHtlcs == 0 {
118✔
5070
                maxHtlcs = f.cfg.RequiredRemoteMaxHTLCs(capacity)
59✔
5071
        }
59✔
5072

5073
        // Once the reservation has been created, and indexed, queue a funding
5074
        // request to the remote peer, kicking off the funding workflow.
5075
        ourContribution := reservation.OurContribution()
59✔
5076

59✔
5077
        // Prepare the optional channel fee values from the initFundingMsg. If
59✔
5078
        // useBaseFee or useFeeRate are false the client did not provide fee
59✔
5079
        // values hence we assume default fee settings from the config.
59✔
5080
        forwardingPolicy := f.defaultForwardingPolicy(
59✔
5081
                ourContribution.ChannelStateBounds,
59✔
5082
        )
59✔
5083
        if baseFee != nil {
62✔
5084
                forwardingPolicy.BaseFee = lnwire.MilliSatoshi(*baseFee)
3✔
5085
        }
3✔
5086

5087
        if feeRate != nil {
62✔
5088
                forwardingPolicy.FeeRate = lnwire.MilliSatoshi(*feeRate)
3✔
5089
        }
3✔
5090

5091
        // Fetch our dust limit which is part of the default channel
5092
        // constraints, and log it.
5093
        ourDustLimit := ourContribution.DustLimit
59✔
5094

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

59✔
5097
        // If the channel reserve is not specified, then we calculate an
59✔
5098
        // appropriate amount here.
59✔
5099
        if chanReserve == 0 {
114✔
5100
                chanReserve = f.cfg.RequiredRemoteChanReserve(
55✔
5101
                        capacity, ourDustLimit,
55✔
5102
                )
55✔
5103
        }
55✔
5104

5105
        // If a pending channel map for this peer isn't already created, then
5106
        // we create one, ultimately allowing us to track this pending
5107
        // reservation within the target peer.
5108
        peerIDKey := newSerializedKey(peerKey)
59✔
5109
        f.resMtx.Lock()
59✔
5110
        if _, ok := f.activeReservations[peerIDKey]; !ok {
111✔
5111
                f.activeReservations[peerIDKey] = make(pendingChannels)
52✔
5112
        }
52✔
5113

5114
        resCtx := &reservationWithCtx{
59✔
5115
                chanAmt:           capacity,
59✔
5116
                forwardingPolicy:  *forwardingPolicy,
59✔
5117
                remoteCsvDelay:    remoteCsvDelay,
59✔
5118
                remoteMinHtlc:     minHtlcIn,
59✔
5119
                remoteMaxValue:    maxValue,
59✔
5120
                remoteMaxHtlcs:    maxHtlcs,
59✔
5121
                remoteChanReserve: chanReserve,
59✔
5122
                maxLocalCsv:       maxCSV,
59✔
5123
                channelType:       chanType,
59✔
5124
                reservation:       reservation,
59✔
5125
                peer:              msg.Peer,
59✔
5126
                updates:           msg.Updates,
59✔
5127
                err:               msg.Err,
59✔
5128
        }
59✔
5129
        f.activeReservations[peerIDKey][chanID] = resCtx
59✔
5130
        f.resMtx.Unlock()
59✔
5131

59✔
5132
        // Update the timestamp once the InitFundingMsg has been handled.
59✔
5133
        defer resCtx.updateTimestamp()
59✔
5134

59✔
5135
        // Check the sanity of the selected channel constraints.
59✔
5136
        bounds := &channeldb.ChannelStateBounds{
59✔
5137
                ChanReserve:      chanReserve,
59✔
5138
                MaxPendingAmount: maxValue,
59✔
5139
                MinHTLC:          minHtlcIn,
59✔
5140
                MaxAcceptedHtlcs: maxHtlcs,
59✔
5141
        }
59✔
5142
        commitParams := &channeldb.CommitmentParams{
59✔
5143
                DustLimit: ourDustLimit,
59✔
5144
                CsvDelay:  remoteCsvDelay,
59✔
5145
        }
59✔
5146
        err = lnwallet.VerifyConstraints(
59✔
5147
                bounds, commitParams, resCtx.maxLocalCsv, capacity,
59✔
5148
        )
59✔
5149
        if err != nil {
61✔
5150
                _, reserveErr := f.cancelReservationCtx(peerKey, chanID, false)
2✔
5151
                if reserveErr != nil {
2✔
5152
                        log.Errorf("unable to cancel reservation: %v",
×
5153
                                reserveErr)
×
5154
                }
×
5155

5156
                msg.Err <- err
2✔
5157
                return
2✔
5158
        }
5159

5160
        // When opening a script enforced channel lease, include the required
5161
        // expiry TLV record in our proposal.
5162
        var leaseExpiry *lnwire.LeaseExpiry
57✔
5163
        if commitType == lnwallet.CommitmentTypeScriptEnforcedLease {
59✔
5164
                leaseExpiry = new(lnwire.LeaseExpiry)
2✔
5165
                *leaseExpiry = lnwire.LeaseExpiry(reservation.LeaseExpiry())
2✔
5166
        }
2✔
5167

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

57✔
5171
        reservation.SetState(lnwallet.SentOpenChannel)
57✔
5172

57✔
5173
        fundingOpen := lnwire.OpenChannel{
57✔
5174
                ChainHash:             *f.cfg.Wallet.Cfg.NetParams.GenesisHash,
57✔
5175
                PendingChannelID:      chanID,
57✔
5176
                FundingAmount:         capacity,
57✔
5177
                PushAmount:            msg.PushAmt,
57✔
5178
                DustLimit:             ourDustLimit,
57✔
5179
                MaxValueInFlight:      maxValue,
57✔
5180
                ChannelReserve:        chanReserve,
57✔
5181
                HtlcMinimum:           minHtlcIn,
57✔
5182
                FeePerKiloWeight:      uint32(commitFeePerKw),
57✔
5183
                CsvDelay:              remoteCsvDelay,
57✔
5184
                MaxAcceptedHTLCs:      maxHtlcs,
57✔
5185
                FundingKey:            ourContribution.MultiSigKey.PubKey,
57✔
5186
                RevocationPoint:       ourContribution.RevocationBasePoint.PubKey,
57✔
5187
                PaymentPoint:          ourContribution.PaymentBasePoint.PubKey,
57✔
5188
                HtlcPoint:             ourContribution.HtlcBasePoint.PubKey,
57✔
5189
                DelayedPaymentPoint:   ourContribution.DelayBasePoint.PubKey,
57✔
5190
                FirstCommitmentPoint:  ourContribution.FirstCommitmentPoint,
57✔
5191
                ChannelFlags:          channelFlags,
57✔
5192
                UpfrontShutdownScript: shutdown,
57✔
5193
                ChannelType:           chanType,
57✔
5194
                LeaseExpiry:           leaseExpiry,
57✔
5195
        }
57✔
5196

57✔
5197
        if commitType.IsTaproot() {
61✔
5198
                fundingOpen.LocalNonce = lnwire.SomeMusig2Nonce(
4✔
5199
                        ourContribution.LocalNonce.PubNonce,
4✔
5200
                )
4✔
5201
        }
4✔
5202

5203
        if err := msg.Peer.SendMessage(true, &fundingOpen); err != nil {
57✔
5204
                e := fmt.Errorf("unable to send funding request message: %w",
×
5205
                        err)
×
5206
                log.Errorf(e.Error())
×
5207

×
5208
                // Since we were unable to send the initial message to the peer
×
5209
                // and start the funding flow, we'll cancel this reservation.
×
5210
                _, err := f.cancelReservationCtx(peerKey, chanID, false)
×
5211
                if err != nil {
×
5212
                        log.Errorf("unable to cancel reservation: %v", err)
×
5213
                }
×
5214

5215
                msg.Err <- e
×
5216
                return
×
5217
        }
5218
}
5219

5220
// handleWarningMsg processes the warning which was received from remote peer.
5221
func (f *Manager) handleWarningMsg(peer lnpeer.Peer, msg *lnwire.Warning) {
44✔
5222
        log.Warnf("received warning message from peer %x: %v",
44✔
5223
                peer.IdentityKey().SerializeCompressed(), msg.Warning())
44✔
5224
}
44✔
5225

5226
// handleErrorMsg processes the error which was received from remote peer,
5227
// depending on the type of error we should do different clean up steps and
5228
// inform the user about it.
5229
func (f *Manager) handleErrorMsg(peer lnpeer.Peer, msg *lnwire.Error) {
2✔
5230
        chanID := msg.ChanID
2✔
5231
        peerKey := peer.IdentityKey()
2✔
5232

2✔
5233
        // First, we'll attempt to retrieve and cancel the funding workflow
2✔
5234
        // that this error was tied to. If we're unable to do so, then we'll
2✔
5235
        // exit early as this was an unwarranted error.
2✔
5236
        resCtx, err := f.cancelReservationCtx(peerKey, chanID, true)
2✔
5237
        if err != nil {
2✔
5238
                log.Warnf("Received error for non-existent funding "+
×
5239
                        "flow: %v (%v)", err, msg.Error())
×
5240
                return
×
5241
        }
×
5242

5243
        // If we did indeed find the funding workflow, then we'll return the
5244
        // error back to the caller (if any), and cancel the workflow itself.
5245
        fundingErr := fmt.Errorf("received funding error from %x: %v",
2✔
5246
                peerKey.SerializeCompressed(), msg.Error(),
2✔
5247
        )
2✔
5248
        log.Errorf(fundingErr.Error())
2✔
5249

2✔
5250
        // If this was a PSBT funding flow, the remote likely timed out because
2✔
5251
        // we waited too long. Return a nice error message to the user in that
2✔
5252
        // case so the user knows what's the problem.
2✔
5253
        if resCtx.reservation.IsPsbt() {
4✔
5254
                fundingErr = fmt.Errorf("%w: %v", chanfunding.ErrRemoteCanceled,
2✔
5255
                        fundingErr)
2✔
5256
        }
2✔
5257

5258
        resCtx.err <- fundingErr
2✔
5259
}
5260

5261
// pruneZombieReservations loops through all pending reservations and fails the
5262
// funding flow for any reservations that have not been updated since the
5263
// ReservationTimeout and are not locked waiting for the funding transaction.
5264
func (f *Manager) pruneZombieReservations() {
5✔
5265
        zombieReservations := make(pendingChannels)
5✔
5266

5✔
5267
        f.resMtx.RLock()
5✔
5268
        for _, pendingReservations := range f.activeReservations {
10✔
5269
                for pendingChanID, resCtx := range pendingReservations {
10✔
5270
                        if resCtx.isLocked() {
5✔
5271
                                continue
×
5272
                        }
5273

5274
                        // We don't want to expire PSBT funding reservations.
5275
                        // These reservations are always initiated by us and the
5276
                        // remote peer is likely going to cancel them after some
5277
                        // idle time anyway. So no need for us to also prune
5278
                        // them.
5279
                        sinceLastUpdate := time.Since(resCtx.lastUpdated)
5✔
5280
                        isExpired := sinceLastUpdate > f.cfg.ReservationTimeout
5✔
5281
                        if !resCtx.reservation.IsPsbt() && isExpired {
10✔
5282
                                zombieReservations[pendingChanID] = resCtx
5✔
5283
                        }
5✔
5284
                }
5285
        }
5286
        f.resMtx.RUnlock()
5✔
5287

5✔
5288
        for pendingChanID, resCtx := range zombieReservations {
10✔
5289
                err := fmt.Errorf("reservation timed out waiting for peer "+
5✔
5290
                        "(peer_id:%x, chan_id:%x)",
5✔
5291
                        resCtx.peer.IdentityKey().SerializeCompressed(),
5✔
5292
                        pendingChanID[:])
5✔
5293
                log.Warnf(err.Error())
5✔
5294

5✔
5295
                chanID := lnwire.NewChanIDFromOutPoint(
5✔
5296
                        *resCtx.reservation.FundingOutpoint(),
5✔
5297
                )
5✔
5298

5✔
5299
                // Create channel identifier and set the channel ID.
5✔
5300
                cid := newChanIdentifier(pendingChanID)
5✔
5301
                cid.setChanID(chanID)
5✔
5302

5✔
5303
                f.failFundingFlow(resCtx.peer, cid, err)
5✔
5304
        }
5✔
5305
}
5306

5307
// cancelReservationCtx does all needed work in order to securely cancel the
5308
// reservation.
5309
func (f *Manager) cancelReservationCtx(peerKey *btcec.PublicKey,
5310
        pendingChanID PendingChanID,
5311
        byRemote bool) (*reservationWithCtx, error) {
25✔
5312

25✔
5313
        log.Infof("Cancelling funding reservation for node_key=%x, "+
25✔
5314
                "chan_id=%x", peerKey.SerializeCompressed(), pendingChanID[:])
25✔
5315

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

25✔
5320
        nodeReservations, ok := f.activeReservations[peerIDKey]
25✔
5321
        if !ok {
34✔
5322
                // No reservations for this node.
9✔
5323
                return nil, fmt.Errorf("no active reservations for peer(%x)",
9✔
5324
                        peerIDKey[:])
9✔
5325
        }
9✔
5326

5327
        ctx, ok := nodeReservations[pendingChanID]
18✔
5328
        if !ok {
20✔
5329
                return nil, fmt.Errorf("unknown channel (id: %x) for "+
2✔
5330
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
2✔
5331
        }
2✔
5332

5333
        // If the reservation was a PSBT funding flow and it was canceled by the
5334
        // remote peer, then we need to thread through a different error message
5335
        // to the subroutine that's waiting for the user input so it can return
5336
        // a nice error message to the user.
5337
        if ctx.reservation.IsPsbt() && byRemote {
18✔
5338
                ctx.reservation.RemoteCanceled()
2✔
5339
        }
2✔
5340

5341
        if err := ctx.reservation.Cancel(); err != nil {
16✔
5342
                return nil, fmt.Errorf("unable to cancel reservation: %w", err)
×
5343
        }
×
5344

5345
        delete(nodeReservations, pendingChanID)
16✔
5346

16✔
5347
        // If this was the last active reservation for this peer, delete the
16✔
5348
        // peer's entry altogether.
16✔
5349
        if len(nodeReservations) == 0 {
32✔
5350
                delete(f.activeReservations, peerIDKey)
16✔
5351
        }
16✔
5352
        return ctx, nil
16✔
5353
}
5354

5355
// deleteReservationCtx deletes the reservation uniquely identified by the
5356
// target public key of the peer, and the specified pending channel ID.
5357
func (f *Manager) deleteReservationCtx(peerKey *btcec.PublicKey,
5358
        pendingChanID PendingChanID) {
58✔
5359

58✔
5360
        peerIDKey := newSerializedKey(peerKey)
58✔
5361
        f.resMtx.Lock()
58✔
5362
        defer f.resMtx.Unlock()
58✔
5363

58✔
5364
        nodeReservations, ok := f.activeReservations[peerIDKey]
58✔
5365
        if !ok {
58✔
5366
                // No reservations for this node.
×
5367
                return
×
5368
        }
×
5369
        delete(nodeReservations, pendingChanID)
58✔
5370

58✔
5371
        // If this was the last active reservation for this peer, delete the
58✔
5372
        // peer's entry altogether.
58✔
5373
        if len(nodeReservations) == 0 {
109✔
5374
                delete(f.activeReservations, peerIDKey)
51✔
5375
        }
51✔
5376
}
5377

5378
// getReservationCtx returns the reservation context for a particular pending
5379
// channel ID for a target peer.
5380
func (f *Manager) getReservationCtx(peerKey *btcec.PublicKey,
5381
        pendingChanID PendingChanID) (*reservationWithCtx, error) {
93✔
5382

93✔
5383
        peerIDKey := newSerializedKey(peerKey)
93✔
5384
        f.resMtx.RLock()
93✔
5385
        resCtx, ok := f.activeReservations[peerIDKey][pendingChanID]
93✔
5386
        f.resMtx.RUnlock()
93✔
5387

93✔
5388
        if !ok {
95✔
5389
                return nil, fmt.Errorf("unknown channel (id: %x) for "+
2✔
5390
                        "peer(%x)", pendingChanID[:], peerIDKey[:])
2✔
5391
        }
2✔
5392

5393
        return resCtx, nil
93✔
5394
}
5395

5396
// IsPendingChannel returns a boolean indicating whether the channel identified
5397
// by the pendingChanID and given peer is pending, meaning it is in the process
5398
// of being funded. After the funding transaction has been confirmed, the
5399
// channel will receive a new, permanent channel ID, and will no longer be
5400
// considered pending.
5401
func (f *Manager) IsPendingChannel(pendingChanID PendingChanID,
5402
        peer lnpeer.Peer) bool {
2✔
5403

2✔
5404
        peerIDKey := newSerializedKey(peer.IdentityKey())
2✔
5405
        f.resMtx.RLock()
2✔
5406
        _, ok := f.activeReservations[peerIDKey][pendingChanID]
2✔
5407
        f.resMtx.RUnlock()
2✔
5408

2✔
5409
        return ok
2✔
5410
}
2✔
5411

5412
func copyPubKey(pub *btcec.PublicKey) *btcec.PublicKey {
387✔
5413
        var tmp btcec.JacobianPoint
387✔
5414
        pub.AsJacobian(&tmp)
387✔
5415
        tmp.ToAffine()
387✔
5416
        return btcec.NewPublicKey(&tmp.X, &tmp.Y)
387✔
5417
}
387✔
5418

5419
// defaultForwardingPolicy returns the default forwarding policy based on the
5420
// default routing policy and our local channel constraints.
5421
func (f *Manager) defaultForwardingPolicy(
5422
        bounds channeldb.ChannelStateBounds) *models.ForwardingPolicy {
106✔
5423

106✔
5424
        return &models.ForwardingPolicy{
106✔
5425
                MinHTLCOut:    bounds.MinHTLC,
106✔
5426
                MaxHTLC:       bounds.MaxPendingAmount,
106✔
5427
                BaseFee:       f.cfg.DefaultRoutingPolicy.BaseFee,
106✔
5428
                FeeRate:       f.cfg.DefaultRoutingPolicy.FeeRate,
106✔
5429
                TimeLockDelta: f.cfg.DefaultRoutingPolicy.TimeLockDelta,
106✔
5430
        }
106✔
5431
}
106✔
5432

5433
// saveInitialForwardingPolicy saves the forwarding policy for the provided
5434
// chanPoint in the channelOpeningStateBucket.
5435
func (f *Manager) saveInitialForwardingPolicy(chanID lnwire.ChannelID,
5436
        forwardingPolicy *models.ForwardingPolicy) error {
71✔
5437

71✔
5438
        return f.cfg.ChannelDB.SaveInitialForwardingPolicy(
71✔
5439
                chanID, forwardingPolicy,
71✔
5440
        )
71✔
5441
}
71✔
5442

5443
// getInitialForwardingPolicy fetches the initial forwarding policy for a given
5444
// channel id from the database which will be applied during the channel
5445
// announcement phase.
5446
func (f *Manager) getInitialForwardingPolicy(
5447
        chanID lnwire.ChannelID) (*models.ForwardingPolicy, error) {
96✔
5448

96✔
5449
        return f.cfg.ChannelDB.GetInitialForwardingPolicy(chanID)
96✔
5450
}
96✔
5451

5452
// deleteInitialForwardingPolicy removes channel fees for this chanID from
5453
// the database.
5454
func (f *Manager) deleteInitialForwardingPolicy(chanID lnwire.ChannelID) error {
26✔
5455
        return f.cfg.ChannelDB.DeleteInitialForwardingPolicy(chanID)
26✔
5456
}
26✔
5457

5458
// saveChannelOpeningState saves the channelOpeningState for the provided
5459
// chanPoint to the channelOpeningStateBucket.
5460
func (f *Manager) saveChannelOpeningState(chanPoint *wire.OutPoint,
5461
        state channelOpeningState, shortChanID *lnwire.ShortChannelID) error {
94✔
5462

94✔
5463
        var outpointBytes bytes.Buffer
94✔
5464
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
94✔
5465
                return err
×
5466
        }
×
5467

5468
        // Save state and the uint64 representation of the shortChanID
5469
        // for later use.
5470
        scratch := make([]byte, 10)
94✔
5471
        byteOrder.PutUint16(scratch[:2], uint16(state))
94✔
5472
        byteOrder.PutUint64(scratch[2:], shortChanID.ToUint64())
94✔
5473

94✔
5474
        return f.cfg.ChannelDB.SaveChannelOpeningState(
94✔
5475
                outpointBytes.Bytes(), scratch,
94✔
5476
        )
94✔
5477
}
5478

5479
// getChannelOpeningState fetches the channelOpeningState for the provided
5480
// chanPoint from the database, or returns ErrChannelNotFound if the channel
5481
// is not found.
5482
func (f *Manager) getChannelOpeningState(chanPoint *wire.OutPoint) (
5483
        channelOpeningState, *lnwire.ShortChannelID, error) {
255✔
5484

255✔
5485
        var outpointBytes bytes.Buffer
255✔
5486
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
255✔
5487
                return 0, nil, err
×
5488
        }
×
5489

5490
        value, err := f.cfg.ChannelDB.GetChannelOpeningState(
255✔
5491
                outpointBytes.Bytes(),
255✔
5492
        )
255✔
5493
        if err != nil {
306✔
5494
                return 0, nil, err
51✔
5495
        }
51✔
5496

5497
        state := channelOpeningState(byteOrder.Uint16(value[:2]))
206✔
5498
        shortChanID := lnwire.NewShortChanIDFromInt(byteOrder.Uint64(value[2:]))
206✔
5499
        return state, &shortChanID, nil
206✔
5500
}
5501

5502
// deleteChannelOpeningState removes any state for chanPoint from the database.
5503
func (f *Manager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error {
26✔
5504
        var outpointBytes bytes.Buffer
26✔
5505
        if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
26✔
5506
                return err
×
5507
        }
×
5508

5509
        return f.cfg.ChannelDB.DeleteChannelOpeningState(
26✔
5510
                outpointBytes.Bytes(),
26✔
5511
        )
26✔
5512
}
5513

5514
// selectShutdownScript selects the shutdown script we should send to the peer.
5515
// If we can use taproot, then we prefer that, otherwise we'll use a p2wkh
5516
// script.
5517
func (f *Manager) selectShutdownScript(taprootOK bool,
5518
) (lnwire.DeliveryAddress, error) {
×
5519

×
5520
        addrType := lnwallet.WitnessPubKey
×
5521
        if taprootOK {
×
5522
                addrType = lnwallet.TaprootPubkey
×
5523
        }
×
5524

5525
        addr, err := f.cfg.Wallet.NewAddress(
×
5526
                addrType, false, lnwallet.DefaultAccountName,
×
5527
        )
×
5528
        if err != nil {
×
5529
                return nil, err
×
5530
        }
×
5531

5532
        return txscript.PayToAddrScript(addr)
×
5533
}
5534

5535
// waitForPeerOnline blocks until the peer specified by peerPubkey comes online
5536
// and then returns the online peer.
5537
func (f *Manager) waitForPeerOnline(peerPubkey *btcec.PublicKey) (lnpeer.Peer,
5538
        error) {
107✔
5539

107✔
5540
        peerChan := make(chan lnpeer.Peer, 1)
107✔
5541

107✔
5542
        var peerKey [33]byte
107✔
5543
        copy(peerKey[:], peerPubkey.SerializeCompressed())
107✔
5544

107✔
5545
        f.cfg.NotifyWhenOnline(peerKey, peerChan)
107✔
5546

107✔
5547
        var peer lnpeer.Peer
107✔
5548
        select {
107✔
5549
        case peer = <-peerChan:
106✔
5550
        case <-f.quit:
1✔
5551
                return peer, ErrFundingManagerShuttingDown
1✔
5552
        }
5553
        return peer, nil
106✔
5554
}
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

© 2026 Coveralls, Inc