diff --git a/lnwallet/chanfunding/assembler.go b/lnwallet/chanfunding/assembler.go index 08fe31e43..a694d2a2c 100644 --- a/lnwallet/chanfunding/assembler.go +++ b/lnwallet/chanfunding/assembler.go @@ -1,9 +1,12 @@ package chanfunding import ( + "time" + "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcwallet/wallet" + "github.com/btcsuite/btcwallet/wtxmgr" "github.com/lightningnetwork/lnd/lnwallet/chainfee" ) @@ -34,18 +37,18 @@ type CoinSelectionLocker interface { WithCoinSelectLock(func() error) error } -// OutpointLocker allows a caller to lock/unlock an outpoint. When locked, the -// outpoints shouldn't be used for any sort of channel funding of coin -// selection. Locked outpoints are not expected to be persisted between -// restarts. -type OutpointLocker interface { - // LockOutpoint locks a target outpoint, rendering it unusable for coin +// OutputLeaser allows a caller to lease/release an output. When leased, the +// outputs shouldn't be used for any sort of channel funding or coin selection. +// Leased outputs are expected to be persisted between restarts. +type OutputLeaser interface { + // LeaseOutput leases a target output, rendering it unusable for coin // selection. - LockOutpoint(o wire.OutPoint) + LeaseOutput(i wtxmgr.LockID, o wire.OutPoint, d time.Duration) ( + time.Time, []byte, btcutil.Amount, error) - // UnlockOutpoint unlocks a target outpoint, allowing it to be used for + // ReleaseOutput releases a target output, allowing it to be used for // coin selection once again. - UnlockOutpoint(o wire.OutPoint) + ReleaseOutput(i wtxmgr.LockID, o wire.OutPoint) error } // Request is a new request for funding a channel. The items in the struct diff --git a/lnwallet/chanfunding/wallet_assembler.go b/lnwallet/chanfunding/wallet_assembler.go index 062fd2328..d4ee080bc 100644 --- a/lnwallet/chanfunding/wallet_assembler.go +++ b/lnwallet/chanfunding/wallet_assembler.go @@ -62,9 +62,9 @@ type FullIntent struct { // change from the main funding transaction. ChangeOutputs []*wire.TxOut - // coinLocker is the Assembler's instance of the OutpointLocker + // coinLeaser is the Assembler's instance of the OutputLeaser // interface. - coinLocker OutpointLocker + coinLeaser OutputLeaser // coinSource is the Assembler's instance of the CoinSource interface. coinSource CoinSource @@ -219,7 +219,13 @@ func (f *FullIntent) Outputs() []*wire.TxOut { // NOTE: Part of the chanfunding.Intent interface. func (f *FullIntent) Cancel() { for _, coin := range f.InputCoins { - f.coinLocker.UnlockOutpoint(coin.OutPoint) + err := f.coinLeaser.ReleaseOutput( + LndInternalLockID, coin.OutPoint, + ) + if err != nil { + log.Warnf("Failed to release UTXO %s (%v))", + coin.OutPoint, err) + } } f.ShimIntent.Cancel() @@ -241,9 +247,9 @@ type WalletConfig struct { // access to the current set of coins returned by the CoinSource. CoinSelectLocker CoinSelectionLocker - // CoinLocker is what the WalletAssembler uses to lock coins that may + // CoinLeaser is what the WalletAssembler uses to lease coins that may // be used as inputs for a new funding transaction. - CoinLocker OutpointLocker + CoinLeaser OutputLeaser // Signer allows the WalletAssembler to sign inputs on any potential // funding transactions. @@ -518,7 +524,13 @@ func (w *WalletAssembler) ProvisionChannel(r *Request) (Intent, error) { for _, coin := range selectedCoins { outpoint := coin.OutPoint - w.cfg.CoinLocker.LockOutpoint(outpoint) + _, _, _, err = w.cfg.CoinLeaser.LeaseOutput( + LndInternalLockID, outpoint, + DefaultReservationTimeout, + ) + if err != nil { + return err + } } newIntent := &FullIntent{ @@ -528,7 +540,7 @@ func (w *WalletAssembler) ProvisionChannel(r *Request) (Intent, error) { musig2: r.Musig2, }, InputCoins: selectedCoins, - coinLocker: w.cfg.CoinLocker, + coinLeaser: w.cfg.CoinLeaser, coinSource: w.cfg.CoinSource, signer: w.cfg.Signer, } diff --git a/lnwallet/test/test_interface.go b/lnwallet/test/test_interface.go index f97b6500c..caa222cf4 100644 --- a/lnwallet/test/test_interface.go +++ b/lnwallet/test/test_interface.go @@ -2990,7 +2990,7 @@ func testSingleFunderExternalFundingTx(miner *rpctest.Harness, chanfunding.WalletConfig{ CoinSource: lnwallet.NewCoinSource(alice), CoinSelectLocker: alice, - CoinLocker: alice, + CoinLeaser: alice, Signer: alice.Cfg.Signer, DustLimit: 600, CoinSelectionStrategy: wallet.CoinSelectionLargest, diff --git a/lnwallet/wallet.go b/lnwallet/wallet.go index 6a8ced33b..99a2f380b 100644 --- a/lnwallet/wallet.go +++ b/lnwallet/wallet.go @@ -851,7 +851,7 @@ func (l *LightningWallet) handleFundingReserveRequest(req *InitFundingReserveMsg cfg := chanfunding.WalletConfig{ CoinSource: &CoinSource{l}, CoinSelectLocker: l, - CoinLocker: l, + CoinLeaser: l, Signer: l.Cfg.Signer, DustLimit: DustLimitForSize( input.P2WSHSize,