lnwallet: update all witness gen funcs for receiver's HTLC scripts

This commit is contained in:
Olaoluwa Osuntokun 2017-07-29 18:08:40 -07:00
parent 4b1a7091e6
commit f70697bf71
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
1 changed files with 59 additions and 45 deletions

View File

@ -469,38 +469,34 @@ func receiverHTLCScript(cltvExipiry uint32, senderKey,
// receiverHtlcSpendRedeem constructs a valid witness allowing the receiver of // receiverHtlcSpendRedeem constructs a valid witness allowing the receiver of
// an HTLC to redeem the conditional payment in the event that their commitment // an HTLC to redeem the conditional payment in the event that their commitment
// transaction is broadcast. Since this is a pay out to the receiving party as // transaction is broadcast. This clause transitions the state of the HLTC
// an output on their commitment transaction, a relative time delay is required // output into the delay+claim state by activating the off-chain covenant bound
// before the output can be spent. // by the 2-of-2 multi-sig output. The HTLC success timeout transaction being
func receiverHtlcSpendRedeem(commitScript []byte, outputAmt btcutil.Amount, // signed has a relative timelock delay enforced by its sequence number. This
reciverKey *btcec.PrivateKey, sweepTx *wire.MsgTx, // delay give the sender of the HTLC enough time to revoke the output if this
paymentPreimage []byte, relativeTimeout uint32) (wire.TxWitness, error) { // is a breach commitment transaction.
func receiverHtlcSpendRedeem(senderSig, paymentPreimage []byte,
signer Signer, signDesc *SignDescriptor,
htlcSuccessTx *wire.MsgTx) (wire.TxWitness, error) {
// In order to properly spend the transaction, we need to set the // First, we'll generate a signature for the HTLC success transaction.
// sequence number. We do this by converting the relative block delay // The signDesc should be signing with the public key used as the
// into a sequence number value able to be interpreted by // receiver's public key and also the correct single tweak.
// OP_CHECKSEQUENCEVERIFY. sweepSig, err := signer.SignOutputRaw(htlcSuccessTx, signDesc)
sweepTx.TxIn[0].Sequence = lockTimeToSequence(false, relativeTimeout)
// Additionally, OP_CSV requires that the version of the transaction
// spending a pkscript with OP_CSV within it *must* be >= 2.
sweepTx.Version = 2
hashCache := txscript.NewTxSigHashes(sweepTx)
sweepSig, err := txscript.RawTxInWitnessSignature(
sweepTx, hashCache, 0, int64(outputAmt), commitScript,
txscript.SigHashAll, reciverKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Place a one as the first item in the evaluated witness stack to // The final witness stack is used the provide the script with the
// force script execution to the HTLC redemption clause. // payment pre-image, and also execute the multi-sig clause after the
witnessStack := wire.TxWitness(make([][]byte, 4)) // pre-images matches. We add a nil item at the bottom of the stack in
witnessStack[0] = sweepSig // order to consume the extra pop within OP_CHECKMULTISIG.
witnessStack[1] = paymentPreimage witnessStack := wire.TxWitness(make([][]byte, 5))
witnessStack[2] = []byte{1} witnessStack[0] = nil
witnessStack[3] = commitScript witnessStack[1] = append(senderSig, byte(txscript.SigHashAll))
witnessStack[2] = append(sweepSig, byte(txscript.SigHashAll))
witnessStack[3] = paymentPreimage
witnessStack[4] = signDesc.WitnessScript
return witnessStack, nil return witnessStack, nil
} }
@ -509,15 +505,14 @@ func receiverHtlcSpendRedeem(commitScript []byte, outputAmt btcutil.Amount,
// HTLC within a previously revoked commitment transaction to re-claim the // HTLC within a previously revoked commitment transaction to re-claim the
// pending funds in the case that the receiver broadcasts this revoked // pending funds in the case that the receiver broadcasts this revoked
// commitment transaction. // commitment transaction.
func receiverHtlcSpendRevoke(commitScript []byte, outputAmt btcutil.Amount, func receiverHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
senderKey *btcec.PrivateKey, sweepTx *wire.MsgTx, revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) {
revokePreimage []byte) (wire.TxWitness, error) {
// TODO(roasbeef): move sig generate outside func, or just factor out? // First, we'll generate a signature for the sweep transaction. The
hashCache := txscript.NewTxSigHashes(sweepTx) // signDesc should be signing with the public key used as the fully
sweepSig, err := txscript.RawTxInWitnessSignature( // derived revocation public key and also the correct double tweak
sweepTx, hashCache, 0, int64(outputAmt), commitScript, // value.
txscript.SigHashAll, senderKey) sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -525,12 +520,10 @@ func receiverHtlcSpendRevoke(commitScript []byte, outputAmt btcutil.Amount,
// We place a zero, then one as the first items in the evaluated // We place a zero, then one as the first items in the evaluated
// witness stack in order to force script execution to the HTLC // witness stack in order to force script execution to the HTLC
// revocation clause. // revocation clause.
witnessStack := wire.TxWitness(make([][]byte, 5)) witnessStack := wire.TxWitness(make([][]byte, 3))
witnessStack[0] = sweepSig witnessStack[0] = append(sweepSig, byte(txscript.SigHashAll))
witnessStack[1] = revokePreimage witnessStack[1] = revokeKey.SerializeCompressed()
witnessStack[2] = []byte{1} witnessStack[2] = signDesc.WitnessScript
witnessStack[3] = nil
witnessStack[4] = commitScript
return witnessStack, nil return witnessStack, nil
} }
@ -539,14 +532,35 @@ func receiverHtlcSpendRevoke(commitScript []byte, outputAmt btcutil.Amount,
// an HTLC to recover the pending funds after an absolute timeout in the // an HTLC to recover the pending funds after an absolute timeout in the
// scenario that the receiver of the HTLC broadcasts their version of the // scenario that the receiver of the HTLC broadcasts their version of the
// commitment transaction. // commitment transaction.
func receiverHtlcSpendTimeout(commitScript []byte, outputAmt btcutil.Amount, //
senderKey *btcec.PrivateKey, sweepTx *wire.MsgTx, // NOTE: The target input of the passed transaction MUST NOT have a final
absoluteTimeout uint32) (wire.TxWitness, error) { // sequence number. Otherwise, the OP_CHECKLOCKTIMEVERIFY check will fail.
func receiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor,
sweepTx *wire.MsgTx, cltvExpiry uint32) (wire.TxWitness, error) {
// The HTLC output has an absolute time period before we are permitted // The HTLC output has an absolute time period before we are permitted
// to recover the pending funds. Therefore we need to set the locktime // to recover the pending funds. Therefore we need to set the locktime
// on this sweeping transaction in order to pass Script verification. // on this sweeping transaction in order to pass Script verification.
sweepTx.LockTime = absoluteTimeout sweepTx.LockTime = cltvExpiry
// With the lock time on the transaction set, we'll not generate a
// signature for the sweep transaction. The passed sign descriptor
// should be created using the raw public key of the sender (w/o the
// single tweak applied), and the single tweak set to the proper value
// taking into account the current state's point.
sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
if err != nil {
return nil, err
}
witnessStack := wire.TxWitness(make([][]byte, 3))
witnessStack[0] = append(sweepSig, byte(txscript.SigHashAll))
witnessStack[1] = nil
witnessStack[2] = signDesc.WitnessScript
return witnessStack, nil
}
hashCache := txscript.NewTxSigHashes(sweepTx) hashCache := txscript.NewTxSigHashes(sweepTx)
sweepSig, err := txscript.RawTxInWitnessSignature( sweepSig, err := txscript.RawTxInWitnessSignature(