diff --git a/cmd/chantools/closepoolaccount.go b/cmd/chantools/closepoolaccount.go index 3817822..6a1c865 100644 --- a/cmd/chantools/closepoolaccount.go +++ b/cmd/chantools/closepoolaccount.go @@ -241,8 +241,11 @@ func closePoolAccount(extendedKey *hdkeychain.ExtendedKey, apiURL string, // Calculate the fee based on the given fee rate and our weight // estimation. var ( - estimator input.TxWeightEstimator - signDesc = &input.SignDescriptor{ + estimator input.TxWeightEstimator + prevOutFetcher = txscript.NewCannedPrevOutputFetcher( + pkScript, sweepValue, + ) + signDesc = &input.SignDescriptor{ KeyDesc: keychain.KeyDescriptor{ KeyLocator: keychain.KeyLocator{ Family: poolscript.AccountKeyFamily, @@ -255,10 +258,8 @@ func closePoolAccount(extendedKey *hdkeychain.ExtendedKey, apiURL string, PkScript: pkScript, Value: sweepValue, }, - InputIndex: 0, - PrevOutputFetcher: txscript.NewCannedPrevOutputFetcher( - pkScript, sweepValue, - ), + InputIndex: 0, + PrevOutputFetcher: prevOutFetcher, } ) @@ -267,7 +268,9 @@ func closePoolAccount(extendedKey *hdkeychain.ExtendedKey, apiURL string, estimator.AddWitnessInput(poolscript.ExpiryWitnessSize) signDesc.HashType = txscript.SigHashAll signDesc.SignMethod = input.WitnessV0SignMethod - signDesc.SigHashes = input.NewTxSigHashesV0Only(sweepTx) + signDesc.SigHashes = txscript.NewTxSigHashes( + sweepTx, prevOutFetcher, + ) case account.VersionTaprootEnabled: estimator.AddWitnessInput(poolscript.TaprootExpiryWitnessSize) diff --git a/cmd/chantools/recoverloopin.go b/cmd/chantools/recoverloopin.go index beebb27..289e588 100644 --- a/cmd/chantools/recoverloopin.go +++ b/cmd/chantools/recoverloopin.go @@ -258,8 +258,12 @@ func getSignedTx(signer *lnd.Signer, loopIn *loopdb.LoopIn, sweepTx *wire.MsgTx, keyIndex uint32) ([]byte, error) { // Create the sign descriptor. - prevoutFetcher := txscript.NewCannedPrevOutputFetcher( - htlc.PkScript, int64(loopIn.Contract.AmountRequested), + prevTxOut := &wire.TxOut{ + PkScript: htlc.PkScript, + Value: int64(loopIn.Contract.AmountRequested), + } + prevOutputFetcher := txscript.NewCannedPrevOutputFetcher( + prevTxOut.PkScript, prevTxOut.Value, ) signDesc := &input.SignDescriptor{ @@ -272,11 +276,8 @@ func getSignedTx(signer *lnd.Signer, loopIn *loopdb.LoopIn, sweepTx *wire.MsgTx, WitnessScript: htlc.TimeoutScript(), HashType: htlc.SigHash(), InputIndex: 0, - PrevOutputFetcher: prevoutFetcher, - Output: &wire.TxOut{ - PkScript: htlc.PkScript, - Value: int64(loopIn.Contract.AmountRequested), - }, + PrevOutputFetcher: prevOutputFetcher, + Output: prevTxOut, } switch htlc.Version { case swap.HtlcV2: @@ -303,13 +304,13 @@ func getSignedTx(signer *lnd.Signer, loopIn *loopdb.LoopIn, sweepTx *wire.MsgTx, return nil, err } - sighashes := txscript.NewTxSigHashes(sweepTx, prevoutFetcher) + sigHashes := txscript.NewTxSigHashes(sweepTx, prevOutputFetcher) // Verify the signature. This will throw an error if the signature is // invalid and allows us to bruteforce the key index. vm, err := txscript.NewEngine( - htlc.PkScript, sweepTx, 0, txscript.StandardVerifyFlags, nil, - sighashes, int64(loopIn.Contract.AmountRequested), prevoutFetcher, + prevTxOut.PkScript, sweepTx, 0, txscript.StandardVerifyFlags, + nil, sigHashes, prevTxOut.Value, prevOutputFetcher, ) if err != nil { return nil, err diff --git a/cmd/chantools/sweepremoteclosed.go b/cmd/chantools/sweepremoteclosed.go index 83bc7c3..5605236 100644 --- a/cmd/chantools/sweepremoteclosed.go +++ b/cmd/chantools/sweepremoteclosed.go @@ -173,6 +173,7 @@ func sweepRemoteClosed(extendedKey *hdkeychain.ExtendedKey, apiURL, signDescs []*input.SignDescriptor sweepTx = wire.NewMsgTx(2) totalOutputValue = uint64(0) + prevOutFetcher = txscript.NewMultiPrevOutFetcher(nil) ) // Add all found target outputs. @@ -207,22 +208,25 @@ func sweepRemoteClosed(extendedKey *hdkeychain.ExtendedKey, apiURL, sequence = 1 } + prevOutPoint := wire.OutPoint{ + Hash: *txHash, + Index: uint32(vout.Outspend.Vin), + } + prevTxOut := &wire.TxOut{ + PkScript: pkScript, + Value: int64(vout.Value), + } + prevOutFetcher.AddPrevOut(prevOutPoint, prevTxOut) sweepTx.TxIn = append(sweepTx.TxIn, &wire.TxIn{ - PreviousOutPoint: wire.OutPoint{ - Hash: *txHash, - Index: uint32(vout.Outspend.Vin), - }, - Sequence: sequence, + PreviousOutPoint: prevOutPoint, + Sequence: sequence, }) signDescs = append(signDescs, &input.SignDescriptor{ KeyDesc: *target.keyDesc, WitnessScript: target.script, - Output: &wire.TxOut{ - PkScript: pkScript, - Value: int64(vout.Value), - }, - HashType: txscript.SigHashAll, + Output: prevTxOut, + HashType: txscript.SigHashAll, }) } } @@ -259,7 +263,7 @@ func sweepRemoteClosed(extendedKey *hdkeychain.ExtendedKey, apiURL, ExtendedKey: extendedKey, ChainParams: chainParams, } - sigHashes = input.NewTxSigHashesV0Only(sweepTx) + sigHashes = txscript.NewTxSigHashes(sweepTx, prevOutFetcher) ) for idx, desc := range signDescs { desc.SigHashes = sigHashes diff --git a/cmd/chantools/sweeptimelock.go b/cmd/chantools/sweeptimelock.go index 61f038f..3821511 100644 --- a/cmd/chantools/sweeptimelock.go +++ b/cmd/chantools/sweeptimelock.go @@ -222,11 +222,13 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiURL string, } api := &btc.ExplorerAPI{BaseURL: apiURL} - sweepTx := wire.NewMsgTx(2) - totalOutputValue := int64(0) - signDescs := make([]*input.SignDescriptor, 0) - var estimator input.TxWeightEstimator - + var ( + sweepTx = wire.NewMsgTx(2) + totalOutputValue = int64(0) + signDescs = make([]*input.SignDescriptor, 0) + prevOutFetcher = txscript.NewMultiPrevOutFetcher(nil) + estimator input.TxWeightEstimator + ) for _, target := range targets { // We can't rely on the CSV delay of the channel DB to be // correct. But it doesn't cost us a lot to just brute force it. @@ -246,11 +248,17 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiURL string, } // Create the transaction input. + prevOutPoint := wire.OutPoint{ + Hash: target.txid, + Index: target.index, + } + prevTxOut := &wire.TxOut{ + PkScript: scriptHash, + Value: target.value, + } + prevOutFetcher.AddPrevOut(prevOutPoint, prevTxOut) sweepTx.TxIn = append(sweepTx.TxIn, &wire.TxIn{ - PreviousOutPoint: wire.OutPoint{ - Hash: target.txid, - Index: target.index, - }, + PreviousOutPoint: prevOutPoint, Sequence: input.LockTimeToSequence( false, uint32(csvTimeout), ), @@ -264,11 +272,8 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiURL string, target.delayBasePointDesc.PubKey, ), WitnessScript: script, - Output: &wire.TxOut{ - PkScript: scriptHash, - Value: target.value, - }, - HashType: txscript.SigHashAll, + Output: prevTxOut, + HashType: txscript.SigHashAll, } totalOutputValue += target.value signDescs = append(signDescs, signDesc) @@ -298,7 +303,7 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiURL string, }} // Sign the transaction now. - sigHashes := input.NewTxSigHashesV0Only(sweepTx) + sigHashes := txscript.NewTxSigHashes(sweepTx, prevOutFetcher) for idx, desc := range signDescs { desc.SigHashes = sigHashes desc.InputIndex = idx diff --git a/cmd/chantools/sweeptimelockmanual.go b/cmd/chantools/sweeptimelockmanual.go index 5d0eece..6b21630 100644 --- a/cmd/chantools/sweeptimelockmanual.go +++ b/cmd/chantools/sweeptimelockmanual.go @@ -257,7 +257,10 @@ func sweepTimeLockManual(extendedKey *hdkeychain.ExtendedKey, apiURL string, totalFee, sweepValue, estimator.Weight()) // Create the sign descriptor for the input then sign the transaction. - sigHashes := input.NewTxSigHashesV0Only(sweepTx) + prevOutFetcher := txscript.NewCannedPrevOutputFetcher( + scriptHash, sweepValue, + ) + sigHashes := txscript.NewTxSigHashes(sweepTx, prevOutFetcher) signDesc := &input.SignDescriptor{ KeyDesc: *delayDesc, SingleTweak: input.SingleTweakBytes( diff --git a/lnd/channel.go b/lnd/channel.go index 01f538a..160bb4f 100644 --- a/lnd/channel.go +++ b/lnd/channel.go @@ -67,7 +67,6 @@ func (lc *LightningChannel) SignedCommitTx() (*wire.MsgTx, error) { // With this, we then generate the full witness so the caller can // broadcast a fully signed transaction. - lc.SignDesc.SigHashes = input.NewTxSigHashesV0Only(commitTx) ourSig, err := lc.TXSigner.SignOutputRaw(commitTx, lc.SignDesc) if err != nil { return nil, err diff --git a/lnd/signer.go b/lnd/signer.go index 6385918..420fba7 100644 --- a/lnd/signer.go +++ b/lnd/signer.go @@ -12,6 +12,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcwallet/wallet" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" ) @@ -132,13 +133,16 @@ func (s *Signer) AddPartialSignature(packet *psbt.Packet, inputIndex int) error { // Now we add our partial signature. + prevOutFetcher := wallet.PsbtPrevOutputFetcher(packet) signDesc := &input.SignDescriptor{ KeyDesc: keyDesc, WitnessScript: witnessScript, Output: utxo, InputIndex: inputIndex, HashType: txscript.SigHashAll, - SigHashes: input.NewTxSigHashesV0Only(packet.UnsignedTx), + SigHashes: txscript.NewTxSigHashes( + packet.UnsignedTx, prevOutFetcher, + ), } ourSigRaw, err := s.SignOutputRaw(packet.UnsignedTx, signDesc) if err != nil {