From 70103a183813854f92a5d8de5d9cc9aa7c69c9e8 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Thu, 12 May 2022 10:24:40 +0200 Subject: [PATCH] multi: return more information in list of leased outputs With this commit we return the additional information the wallet now provides about locked/leased outputs. --- lnrpc/walletrpc/psbt.go | 21 ++++++++++----- lnrpc/walletrpc/walletkit_server.go | 11 +++++--- lntest/mock/walletcontroller.go | 9 ++++--- lnwallet/btcwallet/btcwallet.go | 41 +++++++++++++++++++---------- lnwallet/interface.go | 6 +++-- 5 files changed, 59 insertions(+), 29 deletions(-) diff --git a/lnrpc/walletrpc/psbt.go b/lnrpc/walletrpc/psbt.go index 2031c3e56..e3d02b4a8 100644 --- a/lnrpc/walletrpc/psbt.go +++ b/lnrpc/walletrpc/psbt.go @@ -10,6 +10,7 @@ import ( "github.com/btcsuite/btcd/btcutil/psbt" "github.com/btcsuite/btcd/wire" + base "github.com/btcsuite/btcwallet/wallet" "github.com/btcsuite/btcwallet/wtxmgr" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -47,17 +48,21 @@ func verifyInputsUnspent(inputs []*wire.TxIn, utxos []*lnwallet.Utxo) error { // lockInputs requests a lock lease for all inputs specified in a PSBT packet // by using the internal, static lock ID of lnd's wallet. -func lockInputs(w lnwallet.WalletController, packet *psbt.Packet) ( - []*wtxmgr.LockedOutput, error) { +func lockInputs(w lnwallet.WalletController, + packet *psbt.Packet) ([]*base.ListLeasedOutputResult, error) { - locks := make([]*wtxmgr.LockedOutput, len(packet.UnsignedTx.TxIn)) + locks := make( + []*base.ListLeasedOutputResult, len(packet.UnsignedTx.TxIn), + ) for idx, rawInput := range packet.UnsignedTx.TxIn { - lock := &wtxmgr.LockedOutput{ - LockID: LndInternalLockID, - Outpoint: rawInput.PreviousOutPoint, + lock := &base.ListLeasedOutputResult{ + LockedOutput: &wtxmgr.LockedOutput{ + LockID: LndInternalLockID, + Outpoint: rawInput.PreviousOutPoint, + }, } - expiration, err := w.LeaseOutput( + expiration, pkScript, value, err := w.LeaseOutput( lock.LockID, lock.Outpoint, DefaultLockDuration, ) if err != nil { @@ -80,6 +85,8 @@ func lockInputs(w lnwallet.WalletController, packet *psbt.Packet) ( } lock.Expiration = expiration + lock.PkScript = pkScript + lock.Value = int64(value) locks[idx] = lock } diff --git a/lnrpc/walletrpc/walletkit_server.go b/lnrpc/walletrpc/walletkit_server.go index 946f1298f..1f6425878 100644 --- a/lnrpc/walletrpc/walletkit_server.go +++ b/lnrpc/walletrpc/walletkit_server.go @@ -23,6 +23,7 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcwallet/waddrmgr" + base "github.com/btcsuite/btcwallet/wallet" "github.com/btcsuite/btcwallet/wtxmgr" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/lightningnetwork/lnd/input" @@ -423,7 +424,7 @@ func (w *WalletKit) LeaseOutput(ctx context.Context, // other concurrent processes attempting to lease the same UTXO. var expiration time.Time err = w.cfg.CoinSelectionLocker.WithCoinSelectLock(func() error { - expiration, err = w.cfg.Wallet.LeaseOutput( + expiration, _, _, err = w.cfg.Wallet.LeaseOutput( lockID, *op, duration, ) return err @@ -1003,7 +1004,7 @@ func (w *WalletKit) FundPsbt(_ context.Context, err error packet *psbt.Packet feeSatPerKW chainfee.SatPerKWeight - locks []*wtxmgr.LockedOutput + locks []*base.ListLeasedOutputResult rawPsbt bytes.Buffer ) @@ -1189,9 +1190,11 @@ func (w *WalletKit) FundPsbt(_ context.Context, } // marshallLeases converts the lock leases to the RPC format. -func marshallLeases(locks []*wtxmgr.LockedOutput) []*UtxoLease { +func marshallLeases(locks []*base.ListLeasedOutputResult) []*UtxoLease { rpcLocks := make([]*UtxoLease, len(locks)) for idx, lock := range locks { + lock := lock + rpcLocks[idx] = &UtxoLease{ Id: lock.LockID[:], Outpoint: &lnrpc.OutPoint{ @@ -1200,6 +1203,8 @@ func marshallLeases(locks []*wtxmgr.LockedOutput) []*UtxoLease { OutputIndex: lock.Outpoint.Index, }, Expiration: uint64(lock.Expiration.Unix()), + PkScript: lock.PkScript, + Value: uint64(lock.Value), } } diff --git a/lntest/mock/walletcontroller.go b/lntest/mock/walletcontroller.go index 7dc79e2cc..0256a3164 100644 --- a/lntest/mock/walletcontroller.go +++ b/lntest/mock/walletcontroller.go @@ -13,6 +13,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcwallet/waddrmgr" + base "github.com/btcsuite/btcwallet/wallet" "github.com/btcsuite/btcwallet/wallet/txauthor" "github.com/btcsuite/btcwallet/wtxmgr" "github.com/lightningnetwork/lnd/lnwallet" @@ -174,9 +175,9 @@ func (w *WalletController) UnlockOutpoint(o wire.OutPoint) {} // LeaseOutput returns the current time and a nil error. func (w *WalletController) LeaseOutput(wtxmgr.LockID, wire.OutPoint, - time.Duration) (time.Time, error) { + time.Duration) (time.Time, []byte, btcutil.Amount, error) { - return time.Now(), nil + return time.Now(), nil, 0, nil } // ReleaseOutput currently does nothing. @@ -184,7 +185,9 @@ func (w *WalletController) ReleaseOutput(wtxmgr.LockID, wire.OutPoint) error { return nil } -func (w *WalletController) ListLeasedOutputs() ([]*wtxmgr.LockedOutput, error) { +func (w *WalletController) ListLeasedOutputs() ([]*base.ListLeasedOutputResult, + error) { + return nil, nil } diff --git a/lnwallet/btcwallet/btcwallet.go b/lnwallet/btcwallet/btcwallet.go index f972ab616..1b0464d88 100644 --- a/lnwallet/btcwallet/btcwallet.go +++ b/lnwallet/btcwallet/btcwallet.go @@ -919,30 +919,43 @@ func (b *BtcWallet) UnlockOutpoint(o wire.OutPoint) { // // NOTE: This method requires the global coin selection lock to be held. func (b *BtcWallet) LeaseOutput(id wtxmgr.LockID, op wire.OutPoint, - duration time.Duration) (time.Time, error) { + duration time.Duration) (time.Time, []byte, btcutil.Amount, error) { // Make sure we don't attempt to double lock an output that's been // locked by the in-memory implementation. if b.wallet.LockedOutpoint(op) { - return time.Time{}, wtxmgr.ErrOutputAlreadyLocked + return time.Time{}, nil, 0, wtxmgr.ErrOutputAlreadyLocked } - return b.wallet.LeaseOutput(id, op, duration) + lockedUntil, err := b.wallet.LeaseOutput(id, op, duration) + if err != nil { + return time.Time{}, nil, 0, err + } + + // Get the pkScript and value for this lock from the list of all leased + // outputs. + allLeases, err := b.wallet.ListLeasedOutputs() + if err != nil { + return time.Time{}, nil, 0, err + } + + for _, lease := range allLeases { + if lease.Outpoint == op { + return lockedUntil, lease.PkScript, + btcutil.Amount(lease.Value), nil + } + } + + // We MUST find the leased output in the loop above, otherwise something + // is seriously wrong. + return time.Time{}, nil, 0, wtxmgr.ErrUnknownOutput } // ListLeasedOutputs returns a list of all currently locked outputs. -func (b *BtcWallet) ListLeasedOutputs() ([]*wtxmgr.LockedOutput, error) { - leasedOutputs, err := b.wallet.ListLeasedOutputs() - if err != nil { - return nil, err - } +func (b *BtcWallet) ListLeasedOutputs() ([]*base.ListLeasedOutputResult, + error) { - lockedOutputs := make([]*wtxmgr.LockedOutput, len(leasedOutputs)) - for i, output := range leasedOutputs { - lockedOutputs[i] = output.LockedOutput - } - - return lockedOutputs, nil + return b.wallet.ListLeasedOutputs() } // ReleaseOutput unlocks an output, allowing it to be available for coin diff --git a/lnwallet/interface.go b/lnwallet/interface.go index e9c06b5e2..309e0a4b8 100644 --- a/lnwallet/interface.go +++ b/lnwallet/interface.go @@ -15,6 +15,7 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcwallet/waddrmgr" + base "github.com/btcsuite/btcwallet/wallet" "github.com/btcsuite/btcwallet/wallet/txauthor" "github.com/btcsuite/btcwallet/wtxmgr" "github.com/lightningnetwork/lnd/keychain" @@ -338,7 +339,8 @@ type WalletController interface { // // NOTE: This method requires the global coin selection lock to be held. LeaseOutput(id wtxmgr.LockID, op wire.OutPoint, - duration time.Duration) (time.Time, error) + duration time.Duration) (time.Time, []byte, btcutil.Amount, + 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 @@ -348,7 +350,7 @@ type WalletController interface { ReleaseOutput(id wtxmgr.LockID, op wire.OutPoint) error // ListLeasedOutputs returns a list of all currently locked outputs. - ListLeasedOutputs() ([]*wtxmgr.LockedOutput, error) + ListLeasedOutputs() ([]*base.ListLeasedOutputResult, error) // PublishTransaction performs cursory validation (dust checks, etc), // then finally broadcasts the passed transaction to the Bitcoin network.