From 9e8a1707cca78dd8a35d55a923574ccb2126e007 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Mon, 19 Aug 2019 14:26:36 -0700 Subject: [PATCH] lnwallet: modify FetchInputInfo to return additional information for utxos --- lnrpc/walletrpc/walletkit_server.go | 13 +++++---- lnwallet/btcwallet/signer.go | 41 +++++++++++++++++++++++------ lnwallet/interface.go | 2 +- lnwallet/wallet.go | 5 +++- mock.go | 13 +++++---- 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/lnrpc/walletrpc/walletkit_server.go b/lnrpc/walletrpc/walletkit_server.go index 4b3a26c6..374983f4 100644 --- a/lnrpc/walletrpc/walletkit_server.go +++ b/lnrpc/walletrpc/walletkit_server.go @@ -496,23 +496,26 @@ func (w *WalletKit) BumpFee(ctx context.Context, // // We'll gather all of the information required by the UtxoSweeper in // order to sweep the output. - txOut, err := w.cfg.Wallet.FetchInputInfo(op) + utxo, err := w.cfg.Wallet.FetchInputInfo(op) if err != nil { return nil, err } var witnessType input.WitnessType - switch { - case txscript.IsPayToWitnessPubKeyHash(txOut.PkScript): + switch utxo.AddressType { + case lnwallet.WitnessPubKey: witnessType = input.WitnessKeyHash - case txscript.IsPayToScriptHash(txOut.PkScript): + case lnwallet.NestedWitnessPubKey: witnessType = input.NestedWitnessKeyHash default: return nil, fmt.Errorf("unknown input witness %v", op) } signDesc := &input.SignDescriptor{ - Output: txOut, + Output: &wire.TxOut{ + PkScript: utxo.PkScript, + Value: int64(utxo.Value), + }, HashType: txscript.SigHashAll, } diff --git a/lnwallet/btcwallet/signer.go b/lnwallet/btcwallet/signer.go index c32c64e3..35e158c0 100644 --- a/lnwallet/btcwallet/signer.go +++ b/lnwallet/btcwallet/signer.go @@ -1,6 +1,8 @@ package btcwallet import ( + "fmt" + "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" @@ -21,11 +23,7 @@ import ( // of ErrNotMine should be returned instead. // // This is a part of the WalletController interface. -func (b *BtcWallet) FetchInputInfo(prevOut *wire.OutPoint) (*wire.TxOut, error) { - var ( - err error - output *wire.TxOut - ) +func (b *BtcWallet) FetchInputInfo(prevOut *wire.OutPoint) (*lnwallet.Utxo, error) { // We manually look up the output within the tx store. txid := &prevOut.Hash txDetail, err := base.UnstableAPI(b.wallet).TxDetails(txid) @@ -39,13 +37,40 @@ func (b *BtcWallet) FetchInputInfo(prevOut *wire.OutPoint) (*wire.TxOut, error) // we actually have control of this output. We do this because the check // above only guarantees that the transaction is somehow relevant to us, // like in the event of us being the sender of the transaction. - output = txDetail.TxRecord.MsgTx.TxOut[prevOut.Index] - if _, err := b.fetchOutputAddr(output.PkScript); err != nil { + pkScript := txDetail.TxRecord.MsgTx.TxOut[prevOut.Index].PkScript + if _, err := b.fetchOutputAddr(pkScript); err != nil { return nil, err } + // Then, we'll populate all of the information required by the struct. + addressType := lnwallet.UnknownAddressType + switch { + case txscript.IsPayToWitnessPubKeyHash(pkScript): + addressType = lnwallet.WitnessPubKey + case txscript.IsPayToScriptHash(pkScript): + addressType = lnwallet.NestedWitnessPubKey + } - return output, nil + // Determine the number of confirmations the output currently has. + _, currentHeight, err := b.GetBestBlock() + if err != nil { + return nil, fmt.Errorf("unable to retrieve current height: %v", + err) + } + confs := int64(0) + if txDetail.Block.Height != -1 { + confs = int64(currentHeight - txDetail.Block.Height) + } + + return &lnwallet.Utxo{ + AddressType: addressType, + Value: btcutil.Amount( + txDetail.TxRecord.MsgTx.TxOut[prevOut.Index].Value, + ), + PkScript: pkScript, + Confirmations: confs, + OutPoint: *prevOut, + }, nil } // fetchOutputAddr attempts to fetch the managed address corresponding to the diff --git a/lnwallet/interface.go b/lnwallet/interface.go index e09fc271..bf6c255d 100644 --- a/lnwallet/interface.go +++ b/lnwallet/interface.go @@ -135,7 +135,7 @@ type WalletController interface { // passed outpoint. If the base wallet determines this output is under // its control, then the original txout should be returned. Otherwise, // a non-nil error value of ErrNotMine should be returned instead. - FetchInputInfo(prevOut *wire.OutPoint) (*wire.TxOut, error) + FetchInputInfo(prevOut *wire.OutPoint) (*Utxo, error) // ConfirmedBalance returns the sum of all the wallet's unspent outputs // that have at least confs confirmations. If confs is set to zero, diff --git a/lnwallet/wallet.go b/lnwallet/wallet.go index 3a2a0160..13c73851 100644 --- a/lnwallet/wallet.go +++ b/lnwallet/wallet.go @@ -774,7 +774,10 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) { return } - signDesc.Output = info + signDesc.Output = &wire.TxOut{ + PkScript: info.PkScript, + Value: int64(info.Value), + } signDesc.InputIndex = i inputScript, err := l.Cfg.Signer.ComputeInputScript( diff --git a/mock.go b/mock.go index cb4892ed..0b41bf83 100644 --- a/mock.go +++ b/mock.go @@ -242,12 +242,15 @@ func (*mockWalletController) BackEnd() string { // FetchInputInfo will be called to get info about the inputs to the funding // transaction. func (*mockWalletController) FetchInputInfo( - prevOut *wire.OutPoint) (*wire.TxOut, error) { - txOut := &wire.TxOut{ - Value: int64(10 * btcutil.SatoshiPerBitcoin), - PkScript: []byte("dummy"), + prevOut *wire.OutPoint) (*lnwallet.Utxo, error) { + utxo := &lnwallet.Utxo{ + AddressType: lnwallet.WitnessPubKey, + Value: 10 * btcutil.SatoshiPerBitcoin, + PkScript: []byte("dummy"), + Confirmations: 1, + OutPoint: *prevOut, } - return txOut, nil + return utxo, nil } func (*mockWalletController) ConfirmedBalance(confs int32) (btcutil.Amount, error) { return 0, nil