diff --git a/lnwallet/script_utils.go b/lnwallet/script_utils.go index 65622d31..081a5448 100644 --- a/lnwallet/script_utils.go +++ b/lnwallet/script_utils.go @@ -817,6 +817,31 @@ func htlcSpendSuccess(signer Signer, signDesc *SignDescriptor, return witnessStack, nil } +// htlcSpendRevoke spends a second-level HTLC output. This function is to be +// used by the sender or receiver of an HTLC to claim the HTLC after a revoked +// commitment transaction was broadcast. +func htlcSpendRevoke(signer Signer, signDesc *SignDescriptor, + revokeTx *wire.MsgTx) (wire.TxWitness, error) { + + // We don't need any spacial modifications to the transaction as this + // is just sweeping a revoked HTLC output. So we'll generate a regular + // witness signature. + sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc) + if err != nil { + return nil, err + } + + // We set a one as the first element the witness stack (ignoring the + // witness script), in order to force execution to the revocation + // clause in the second level HTLC script. + witnessStack := wire.TxWitness(make([][]byte, 3)) + witnessStack[0] = append(sweepSig, byte(signDesc.HashType)) + witnessStack[1] = []byte{1} + witnessStack[2] = signDesc.WitnessScript + + return witnessStack, nil +} + // HtlcSecondLevelSpend exposes the public witness generation function for // spending an HTLC success transaction, either due to an expiring time lock or // having had the payment preimage. This method is able to spend any @@ -848,31 +873,6 @@ func HtlcSecondLevelSpend(signer Signer, signDesc *SignDescriptor, return witnessStack, nil } -// htlcTimeoutRevoke spends a second-level HTLC output. This function is to be -// used by the sender or receiver of an HTLC to claim the HTLC after a revoked -// commitment transaction was broadcast. -func htlcSpendRevoke(signer Signer, signDesc *SignDescriptor, - revokeTx *wire.MsgTx) (wire.TxWitness, error) { - - // We don't need any spacial modifications to the transaction as this - // is just sweeping a revoked HTLC output. So we'll generate a regular - // witness signature. - sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc) - if err != nil { - return nil, err - } - - // We set a one as the first element the witness stack (ignoring the - // witness script), in order to force execution to the revocation - // clause in the second level HTLC script. - witnessStack := wire.TxWitness(make([][]byte, 3)) - witnessStack[0] = append(sweepSig, byte(signDesc.HashType)) - witnessStack[1] = []byte{1} - witnessStack[2] = signDesc.WitnessScript - - return witnessStack, nil -} - // lockTimeToSequence converts the passed relative locktime to a sequence // number in accordance to BIP-68. // See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki diff --git a/lnwallet/witnessgen.go b/lnwallet/witnessgen.go index 59a7a534..aca3bacc 100644 --- a/lnwallet/witnessgen.go +++ b/lnwallet/witnessgen.go @@ -63,6 +63,12 @@ const ( // pre-image to the HTLC. We can sweep this without any additional // timeout. HtlcAcceptedRemoteSuccess WitnessType = 8 + + // HtlcSecondLevelRevoke is a witness that allows us to sweep an HTLC + // from the remote party's commitment transaction in the case that the + // broadcast a revoked commitment, but then also immediately attempt to + // go to the second level to claim the HTLC. + HtlcSecondLevelRevoke WitnessType = 9 ) // WitnessGenerator represents a function which is able to generate the final @@ -111,6 +117,9 @@ func (wt WitnessType) GenWitnessFunc(signer Signer, // value. return receiverHtlcSpendTimeout(signer, desc, tx, -1) + case HtlcSecondLevelRevoke: + return htlcSpendRevoke(signer, desc, tx) + default: return nil, fmt.Errorf("unknown witness type: %v", wt) }