diff --git a/lnwallet/btcwallet/btcwallet.go b/lnwallet/btcwallet/btcwallet.go index a4569e52..e1176933 100644 --- a/lnwallet/btcwallet/btcwallet.go +++ b/lnwallet/btcwallet/btcwallet.go @@ -19,6 +19,7 @@ import ( "github.com/btcsuite/btcwallet/wallet/txauthor" "github.com/btcsuite/btcwallet/wallet/txrules" "github.com/btcsuite/btcwallet/walletdb" + "github.com/btcsuite/btcwallet/wtxmgr" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet/chainfee" @@ -367,6 +368,27 @@ func (b *BtcWallet) UnlockOutpoint(o wire.OutPoint) { b.wallet.UnlockOutpoint(o) } +// LeaseOutput locks an output to the given ID, preventing it from being +// available for any future coin selection attempts. The absolute time of the +// lock's expiration is returned. The expiration of the lock can be extended by +// successive invocations of this call. Outputs can be unlocked before their +// expiration through `ReleaseOutput`. +// +// If the output is not known, wtxmgr.ErrUnknownOutput is returned. If the +// output has already been locked to a different ID, then +// wtxmgr.ErrOutputAlreadyLocked is returned. +func (b *BtcWallet) LeaseOutput(id wtxmgr.LockID, op wire.OutPoint) (time.Time, + error) { + return b.wallet.LeaseOutput(id, op) +} + +// ReleaseOutput unlocks an output, allowing it to be available for coin +// selection if it remains unspent. The ID should match the one used to +// originally lock the output. +func (b *BtcWallet) ReleaseOutput(id wtxmgr.LockID, op wire.OutPoint) error { + return b.wallet.ReleaseOutput(id, op) +} + // ListUnspentWitness returns a slice of all the unspent outputs the wallet // controls which pay to witness programs either directly or indirectly. // diff --git a/lnwallet/interface.go b/lnwallet/interface.go index bff571e1..951cf17a 100644 --- a/lnwallet/interface.go +++ b/lnwallet/interface.go @@ -4,12 +4,14 @@ import ( "errors" "fmt" "sync" + "time" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwallet/wallet/txauthor" + "github.com/btcsuite/btcwallet/wtxmgr" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet/chainfee" ) @@ -221,6 +223,22 @@ type WalletController interface { // eligible for coin selection. UnlockOutpoint(o wire.OutPoint) + // LeaseOutput locks an output to the given ID, preventing it from being + // available for any future coin selection attempts. The absolute time + // of the lock's expiration is returned. The expiration of the lock can + // be extended by successive invocations of this call. Outputs can be + // unlocked before their expiration through `ReleaseOutput`. + // + // If the output is not known, wtxmgr.ErrUnknownOutput is returned. If + // the output has already been locked to a different ID, then + // wtxmgr.ErrOutputAlreadyLocked is returned. + LeaseOutput(id wtxmgr.LockID, op wire.OutPoint) (time.Time, error) + + // ReleaseOutput unlocks an output, allowing it to be available for coin + // selection if it remains unspent. The ID should match the one used to + // originally lock the output. + ReleaseOutput(id wtxmgr.LockID, op wire.OutPoint) error + // PublishTransaction performs cursory validation (dust checks, etc), // then finally broadcasts the passed transaction to the Bitcoin network. // If the transaction is rejected because it is conflicting with an diff --git a/mock.go b/mock.go index 6d40402b..fc86d1b0 100644 --- a/mock.go +++ b/mock.go @@ -5,6 +5,7 @@ import ( "fmt" "sync" "sync/atomic" + "time" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/chaincfg" @@ -13,6 +14,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwallet/wallet/txauthor" + "github.com/btcsuite/btcwallet/wtxmgr" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/input" @@ -322,6 +324,14 @@ func (*mockWalletController) ListTransactionDetails(_, _ int32) ([]*lnwallet.Tra } func (*mockWalletController) LockOutpoint(o wire.OutPoint) {} func (*mockWalletController) UnlockOutpoint(o wire.OutPoint) {} + +func (*mockWalletController) LeaseOutput(wtxmgr.LockID, wire.OutPoint) (time.Time, error) { + return time.Now(), nil +} +func (*mockWalletController) ReleaseOutput(wtxmgr.LockID, wire.OutPoint) error { + return nil +} + func (m *mockWalletController) PublishTransaction(tx *wire.MsgTx, _ string) error { m.publishedTransactions <- tx return nil