From eb8d22e1943ccec94fa6c060d5ad0ee3cca75d1f Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Wed, 9 Dec 2020 12:24:01 +0100 Subject: [PATCH] lnwallet/channel: properly set SignDesc.Output Only value was populated for some, which would cause code to rely on the PkScript being there to fail. --- lnwallet/channel.go | 63 +++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/lnwallet/channel.go b/lnwallet/channel.go index 4ab00e28..9aa70818 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -3034,16 +3034,15 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing, // Finally, we'll generate a sign descriptor to generate a // signature to give to the remote party for this commitment // transaction. Note we use the raw HTLC amount. + txOut := remoteCommitView.txn.TxOut[htlc.remoteOutputIndex] sigJob.SignDesc = input.SignDescriptor{ KeyDesc: localChanCfg.HtlcBasePoint, SingleTweak: keyRing.LocalHtlcKeyTweak, WitnessScript: htlc.theirWitnessScript, - Output: &wire.TxOut{ - Value: int64(htlc.Amount.ToSatoshis()), - }, - HashType: sigHashType, - SigHashes: txscript.NewTxSigHashes(sigJob.Tx), - InputIndex: 0, + Output: txOut, + HashType: sigHashType, + SigHashes: txscript.NewTxSigHashes(sigJob.Tx), + InputIndex: 0, } sigJob.OutputIndex = htlc.remoteOutputIndex @@ -3087,16 +3086,15 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing, // Finally, we'll generate a sign descriptor to generate a // signature to give to the remote party for this commitment // transaction. Note we use the raw HTLC amount. + txOut := remoteCommitView.txn.TxOut[htlc.remoteOutputIndex] sigJob.SignDesc = input.SignDescriptor{ KeyDesc: localChanCfg.HtlcBasePoint, SingleTweak: keyRing.LocalHtlcKeyTweak, WitnessScript: htlc.theirWitnessScript, - Output: &wire.TxOut{ - Value: int64(htlc.Amount.ToSatoshis()), - }, - HashType: sigHashType, - SigHashes: txscript.NewTxSigHashes(sigJob.Tx), - InputIndex: 0, + Output: txOut, + HashType: sigHashType, + SigHashes: txscript.NewTxSigHashes(sigJob.Tx), + InputIndex: 0, } sigJob.OutputIndex = htlc.remoteOutputIndex @@ -5396,7 +5394,7 @@ func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer input.Si htlcResolutions, err := extractHtlcResolutions( chainfee.SatPerKWeight(remoteCommit.FeePerKw), false, signer, remoteCommit.Htlcs, keyRing, &chanState.LocalChanCfg, - &chanState.RemoteChanCfg, *commitSpend.SpenderTxHash, + &chanState.RemoteChanCfg, commitSpend.SpendingTx, chanState.ChanType, ) if err != nil { @@ -5599,13 +5597,13 @@ type HtlcResolutions struct { // allowing the caller to sweep an outgoing HTLC present on either their, or // the remote party's commitment transaction. func newOutgoingHtlcResolution(signer input.Signer, - localChanCfg *channeldb.ChannelConfig, commitHash chainhash.Hash, + localChanCfg *channeldb.ChannelConfig, commitTx *wire.MsgTx, htlc *channeldb.HTLC, keyRing *CommitmentKeyRing, feePerKw chainfee.SatPerKWeight, csvDelay uint32, localCommit bool, chanType channeldb.ChannelType) (*OutgoingHtlcResolution, error) { op := wire.OutPoint{ - Hash: commitHash, + Hash: commitTx.TxHash(), Index: uint32(htlc.OutputIndex), } @@ -5664,16 +5662,15 @@ func newOutgoingHtlcResolution(signer input.Signer, // With the transaction created, we can generate a sign descriptor // that's capable of generating the signature required to spend the // HTLC output using the timeout transaction. + txOut := commitTx.TxOut[htlc.OutputIndex] timeoutSignDesc := input.SignDescriptor{ KeyDesc: localChanCfg.HtlcBasePoint, SingleTweak: keyRing.LocalHtlcKeyTweak, WitnessScript: htlcScript, - Output: &wire.TxOut{ - Value: int64(htlc.Amt.ToSatoshis()), - }, - HashType: txscript.SigHashAll, - SigHashes: txscript.NewTxSigHashes(timeoutTx), - InputIndex: 0, + Output: txOut, + HashType: txscript.SigHashAll, + SigHashes: txscript.NewTxSigHashes(timeoutTx), + InputIndex: 0, } htlcSig, err := btcec.ParseDERSignature(htlc.Signature, btcec.S256()) @@ -5738,13 +5735,13 @@ func newOutgoingHtlcResolution(signer input.Signer, // // TODO(roasbeef) consolidate code with above func func newIncomingHtlcResolution(signer input.Signer, - localChanCfg *channeldb.ChannelConfig, commitHash chainhash.Hash, + localChanCfg *channeldb.ChannelConfig, commitTx *wire.MsgTx, htlc *channeldb.HTLC, keyRing *CommitmentKeyRing, feePerKw chainfee.SatPerKWeight, csvDelay uint32, localCommit bool, chanType channeldb.ChannelType) (*IncomingHtlcResolution, error) { op := wire.OutPoint{ - Hash: commitHash, + Hash: commitTx.TxHash(), Index: uint32(htlc.OutputIndex), } @@ -5795,16 +5792,15 @@ func newIncomingHtlcResolution(signer input.Signer, // Once we've created the second-level transaction, we'll generate the // SignDesc needed spend the HTLC output using the success transaction. + txOut := commitTx.TxOut[htlc.OutputIndex] successSignDesc := input.SignDescriptor{ KeyDesc: localChanCfg.HtlcBasePoint, SingleTweak: keyRing.LocalHtlcKeyTweak, WitnessScript: htlcScript, - Output: &wire.TxOut{ - Value: int64(htlc.Amt.ToSatoshis()), - }, - HashType: txscript.SigHashAll, - SigHashes: txscript.NewTxSigHashes(successTx), - InputIndex: 0, + Output: txOut, + HashType: txscript.SigHashAll, + SigHashes: txscript.NewTxSigHashes(successTx), + InputIndex: 0, } htlcSig, err := btcec.ParseDERSignature(htlc.Signature, btcec.S256()) @@ -5892,7 +5888,7 @@ func (r *OutgoingHtlcResolution) HtlcPoint() wire.OutPoint { func extractHtlcResolutions(feePerKw chainfee.SatPerKWeight, ourCommit bool, signer input.Signer, htlcs []channeldb.HTLC, keyRing *CommitmentKeyRing, localChanCfg, remoteChanCfg *channeldb.ChannelConfig, - commitHash chainhash.Hash, chanType channeldb.ChannelType) ( + commitTx *wire.MsgTx, chanType channeldb.ChannelType) ( *HtlcResolutions, error) { // TODO(roasbeef): don't need to swap csv delay? @@ -5924,7 +5920,7 @@ func extractHtlcResolutions(feePerKw chainfee.SatPerKWeight, ourCommit bool, // Otherwise, we'll create an incoming HTLC resolution // as we can satisfy the contract. ihr, err := newIncomingHtlcResolution( - signer, localChanCfg, commitHash, &htlc, + signer, localChanCfg, commitTx, &htlc, keyRing, feePerKw, uint32(csvDelay), ourCommit, chanType, ) @@ -5937,7 +5933,7 @@ func extractHtlcResolutions(feePerKw chainfee.SatPerKWeight, ourCommit bool, } ohr, err := newOutgoingHtlcResolution( - signer, localChanCfg, commitHash, &htlc, keyRing, + signer, localChanCfg, commitTx, &htlc, keyRing, feePerKw, uint32(csvDelay), ourCommit, chanType, ) if err != nil { @@ -6138,12 +6134,11 @@ func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel, // outgoing HTLC's that we'll need to claim as well. If this is after // recovery there is not much we can do with HTLCs, so we'll always // use what we have in our latest state when extracting resolutions. - txHash := commitTx.TxHash() localCommit := chanState.LocalCommitment htlcResolutions, err := extractHtlcResolutions( chainfee.SatPerKWeight(localCommit.FeePerKw), true, signer, localCommit.Htlcs, keyRing, &chanState.LocalChanCfg, - &chanState.RemoteChanCfg, txHash, chanState.ChanType, + &chanState.RemoteChanCfg, commitTx, chanState.ChanType, ) if err != nil { return nil, err