lnwallet: update the witness generation funcs for sender's HTLC output
This commit updates all the spendHtlcSpend* functions which are used to spend each of the possible clauses within the HTLC contract placed on the sender’s commitment transaction.
This commit is contained in:
parent
8f5129e08f
commit
d697c6ca9a
@ -270,32 +270,29 @@ func senderHTLCScript(senderKey, receiverKey, revocationKey *btcec.PublicKey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// senderHtlcSpendRevoke constructs a valid witness allowing the receiver of an
|
// senderHtlcSpendRevoke constructs a valid witness allowing the receiver of an
|
||||||
// HTLC to claim the output with knowledge of the revocation preimage in the
|
// HTLC to claim the output with knowledge of the revocation private key in the
|
||||||
// scenario that the sender of the HTLC broadcasts a previously revoked
|
// scenario that the sender of the HTLC broadcasts a previously revoked
|
||||||
// commitment transaction. A valid spend requires knowledge of the preimage to
|
// commitment transaction. A valid spend requires knowledge of the private key
|
||||||
// the commitment transaction's revocation hash, and a valid signature under
|
// that corresponds to their revocation base point and also the private key fro
|
||||||
// the receiver's public key.
|
// the per commitment point, and a valid signature under the combined public
|
||||||
func senderHtlcSpendRevoke(commitScript []byte, outputAmt btcutil.Amount,
|
// key.
|
||||||
reciverKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
func senderHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
|
||||||
revokePreimage []byte) (wire.TxWitness, error) {
|
revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) {
|
||||||
|
|
||||||
hashCache := txscript.NewTxSigHashes(sweepTx)
|
sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
// In order to force script execution to enter the revocation clause,
|
// The stack required to sweep a revoke HTLC output consists simply of
|
||||||
// we place two one's as the first items in the final evaluated witness
|
// the exact witness stack as one of a regular p2wkh spend. The only
|
||||||
// stack.
|
// difference is that the keys used were derived in an adversarial
|
||||||
witnessStack := wire.TxWitness(make([][]byte, 5))
|
// manner in order to encode the revocation contract into a sig+key
|
||||||
witnessStack[0] = sweepSig
|
// pair.
|
||||||
witnessStack[1] = revokePreimage
|
witnessStack := wire.TxWitness(make([][]byte, 3))
|
||||||
witnessStack[2] = []byte{1}
|
witnessStack[0] = append(sweepSig, byte(txscript.SigHashAll))
|
||||||
witnessStack[3] = []byte{1}
|
witnessStack[1] = revokeKey.SerializeCompressed()
|
||||||
witnessStack[4] = commitScript
|
witnessStack[2] = signDesc.WitnessScript
|
||||||
|
|
||||||
return witnessStack, nil
|
return witnessStack, nil
|
||||||
}
|
}
|
||||||
@ -303,70 +300,49 @@ func senderHtlcSpendRevoke(commitScript []byte, outputAmt btcutil.Amount,
|
|||||||
// senderHtlcSpendRedeem constructs a valid witness allowing the receiver of an
|
// senderHtlcSpendRedeem constructs a valid witness allowing the receiver of an
|
||||||
// HTLC to redeem the pending output in the scenario that the sender broadcasts
|
// HTLC to redeem the pending output in the scenario that the sender broadcasts
|
||||||
// their version of the commitment transaction. A valid spend requires
|
// their version of the commitment transaction. A valid spend requires
|
||||||
// knowledge of the payment preimage, and a valid signature under the
|
// knowledge of the payment preimage, and a valid signature under the receivers
|
||||||
// receivers public key.
|
// public key.
|
||||||
func senderHtlcSpendRedeem(commitScript []byte, outputAmt btcutil.Amount,
|
func senderHtlcSpendRedeem(signer Signer, signDesc *SignDescriptor,
|
||||||
reciverKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
sweepTx *wire.MsgTx, paymentPreimage []byte) (wire.TxWitness, error) {
|
||||||
paymentPreimage []byte) (wire.TxWitness, error) {
|
|
||||||
|
|
||||||
hashCache := txscript.NewTxSigHashes(sweepTx)
|
sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
// We force script execution into the HTLC redemption clause by placing
|
// The stack require to spend this output is simply the signature
|
||||||
// a one, then a zero as the first items in the final evaluated
|
// generated above under the receiver's public key, and the payment
|
||||||
// witness stack.
|
// pre-image.
|
||||||
witnessStack := wire.TxWitness(make([][]byte, 5))
|
witnessStack := wire.TxWitness(make([][]byte, 3))
|
||||||
witnessStack[0] = sweepSig
|
witnessStack[0] = append(sweepSig, byte(txscript.SigHashAll))
|
||||||
witnessStack[1] = paymentPreimage
|
witnessStack[1] = paymentPreimage
|
||||||
witnessStack[2] = nil
|
witnessStack[2] = signDesc.WitnessScript
|
||||||
witnessStack[3] = []byte{1}
|
|
||||||
witnessStack[4] = commitScript
|
|
||||||
|
|
||||||
return witnessStack, nil
|
return witnessStack, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// htlcSpendTimeout constructs a valid witness allowing the sender of an HTLC
|
// senderHtlcSpendTimeout constructs a valid witness allowing the sender of an
|
||||||
// to recover the pending funds after an absolute, then relative locktime
|
// HTLC to activate the time locked covenant clause of a soon to be expired
|
||||||
// period.
|
// HTLC. This script simply spends the multi-sig output using the
|
||||||
func senderHtlcSpendTimeout(commitScript []byte, outputAmt btcutil.Amount,
|
// pre-generated HTLC timeout transaction.
|
||||||
senderKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
func senderHtlcSpendTimeout(reciverSig []byte, signer Signer,
|
||||||
absoluteTimeout, relativeTimeout uint32) (wire.TxWitness, error) {
|
signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx) (wire.TxWitness, error) {
|
||||||
|
|
||||||
// Since the HTLC output has an absolute timeout before we're permitted
|
sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc)
|
||||||
// to sweep the output, we need to set the locktime of this sweeping
|
|
||||||
// transaction to that absolute value in order to pass Script
|
|
||||||
// verification.
|
|
||||||
sweepTx.LockTime = absoluteTimeout
|
|
||||||
|
|
||||||
// Additionally, we're required to wait a relative period of time
|
|
||||||
// before we can sweep the output in order to allow the other party to
|
|
||||||
// contest our claim of validity to this version of the commitment
|
|
||||||
// transaction.
|
|
||||||
sweepTx.TxIn[0].Sequence = lockTimeToSequence(false, relativeTimeout)
|
|
||||||
|
|
||||||
// Finally, 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, senderKey)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// We place a zero as the first item of the evaluated witness stack in
|
// We place a zero as the first item of the evaluated witness stack in
|
||||||
// order to force Script execution to the HTLC timeout clause.
|
// order to force Script execution to the HTLC timeout clause. The
|
||||||
witnessStack := wire.TxWitness(make([][]byte, 3))
|
// second zero is require to consume the extra pop due to a bug in the
|
||||||
witnessStack[0] = sweepSig
|
// original OP_CHECKMULTISIG.
|
||||||
witnessStack[1] = nil
|
witnessStack := wire.TxWitness(make([][]byte, 5))
|
||||||
witnessStack[2] = commitScript
|
witnessStack[0] = nil
|
||||||
|
witnessStack[1] = append(reciverSig, byte(txscript.SigHashAll))
|
||||||
|
witnessStack[2] = append(sweepSig, byte(txscript.SigHashAll))
|
||||||
|
witnessStack[3] = nil
|
||||||
|
witnessStack[4] = signDesc.WitnessScript
|
||||||
|
|
||||||
return witnessStack, nil
|
return witnessStack, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user