lnwallet: make second level sigs using sighash single|anyonecanpay
This commit is contained in:
parent
d1089fb449
commit
bddd3e128c
@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
@ -144,7 +145,8 @@ func TestHtlcTimeoutResolver(t *testing.T) {
|
||||
timeout: true,
|
||||
txToBroadcast: func() (*wire.MsgTx, error) {
|
||||
witness, err := input.SenderHtlcSpendTimeout(
|
||||
nil, signer, fakeSignDesc, sweepTx,
|
||||
nil, txscript.SigHashAll, signer,
|
||||
fakeSignDesc, sweepTx,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -163,7 +165,8 @@ func TestHtlcTimeoutResolver(t *testing.T) {
|
||||
timeout: false,
|
||||
txToBroadcast: func() (*wire.MsgTx, error) {
|
||||
witness, err := input.ReceiverHtlcSpendRedeem(
|
||||
nil, fakePreimageBytes, signer,
|
||||
nil, txscript.SigHashAll,
|
||||
fakePreimageBytes, signer,
|
||||
fakeSignDesc, sweepTx,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -343,8 +343,10 @@ func SenderHtlcSpendRedeem(signer Signer, signDesc *SignDescriptor,
|
||||
// HTLC to activate the time locked covenant clause of a soon to be expired
|
||||
// HTLC. This script simply spends the multi-sig output using the
|
||||
// pre-generated HTLC timeout transaction.
|
||||
func SenderHtlcSpendTimeout(receiverSig []byte, signer Signer,
|
||||
signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx) (wire.TxWitness, error) {
|
||||
func SenderHtlcSpendTimeout(receiverSig []byte,
|
||||
receiverSigHash txscript.SigHashType, signer Signer,
|
||||
signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx) (
|
||||
wire.TxWitness, error) {
|
||||
|
||||
sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc)
|
||||
if err != nil {
|
||||
@ -357,7 +359,7 @@ func SenderHtlcSpendTimeout(receiverSig []byte, signer Signer,
|
||||
// original OP_CHECKMULTISIG.
|
||||
witnessStack := wire.TxWitness(make([][]byte, 5))
|
||||
witnessStack[0] = nil
|
||||
witnessStack[1] = append(receiverSig, byte(txscript.SigHashAll))
|
||||
witnessStack[1] = append(receiverSig, byte(receiverSigHash))
|
||||
witnessStack[2] = append(sweepSig, byte(signDesc.HashType))
|
||||
witnessStack[3] = nil
|
||||
witnessStack[4] = signDesc.WitnessScript
|
||||
@ -506,9 +508,10 @@ func ReceiverHTLCScript(cltvExpiry uint32, senderHtlcKey,
|
||||
// signed has a relative timelock delay enforced by its sequence number. This
|
||||
// delay give the sender of the HTLC enough time to revoke the output if this
|
||||
// is a breach commitment transaction.
|
||||
func ReceiverHtlcSpendRedeem(senderSig, paymentPreimage []byte,
|
||||
signer Signer, signDesc *SignDescriptor,
|
||||
htlcSuccessTx *wire.MsgTx) (wire.TxWitness, error) {
|
||||
func ReceiverHtlcSpendRedeem(senderSig []byte,
|
||||
senderSigHash txscript.SigHashType, paymentPreimage []byte,
|
||||
signer Signer, signDesc *SignDescriptor, htlcSuccessTx *wire.MsgTx) (
|
||||
wire.TxWitness, error) {
|
||||
|
||||
// First, we'll generate a signature for the HTLC success transaction.
|
||||
// The signDesc should be signing with the public key used as the
|
||||
@ -524,7 +527,7 @@ func ReceiverHtlcSpendRedeem(senderSig, paymentPreimage []byte,
|
||||
// order to consume the extra pop within OP_CHECKMULTISIG.
|
||||
witnessStack := wire.TxWitness(make([][]byte, 5))
|
||||
witnessStack[0] = nil
|
||||
witnessStack[1] = append(senderSig, byte(txscript.SigHashAll))
|
||||
witnessStack[1] = append(senderSig, byte(senderSigHash))
|
||||
witnessStack[2] = append(sweepSig, byte(signDesc.HashType))
|
||||
witnessStack[3] = paymentPreimage
|
||||
witnessStack[4] = signDesc.WitnessScript
|
||||
|
@ -227,6 +227,7 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
|
||||
sweepTxSigHashes *txscript.TxSigHashes
|
||||
senderCommitTx, sweepTx *wire.MsgTx
|
||||
bobRecvrSig []byte
|
||||
bobSigHash txscript.SigHashType
|
||||
)
|
||||
|
||||
// genCommitTx generates a commitment tx where the htlc output requires
|
||||
@ -260,7 +261,7 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
|
||||
}
|
||||
|
||||
// genSweepTx generates a sweep of the senderCommitTx, and sets the
|
||||
// sequence if confirmed is true.
|
||||
// sequence and sighash single|anyonecanspend if confirmed is true.
|
||||
genSweepTx := func(confirmed bool) {
|
||||
prevOut := &wire.OutPoint{
|
||||
Hash: senderCommitTx.TxHash(),
|
||||
@ -283,6 +284,11 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
|
||||
|
||||
sweepTxSigHashes = txscript.NewTxSigHashes(sweepTx)
|
||||
|
||||
bobSigHash = txscript.SigHashAll
|
||||
if confirmed {
|
||||
bobSigHash = txscript.SigHashSingle | txscript.SigHashAnyOneCanPay
|
||||
}
|
||||
|
||||
// We'll also generate a signature on the sweep transaction above
|
||||
// that will act as Bob's signature to Alice for the second level HTLC
|
||||
// transaction.
|
||||
@ -293,7 +299,7 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
|
||||
SingleTweak: bobCommitTweak,
|
||||
WitnessScript: htlcWitnessScript,
|
||||
Output: htlcOutput,
|
||||
HashType: txscript.SigHashAll,
|
||||
HashType: bobSigHash,
|
||||
SigHashes: sweepTxSigHashes,
|
||||
InputIndex: 0,
|
||||
}
|
||||
@ -458,8 +464,10 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
|
||||
InputIndex: 0,
|
||||
}
|
||||
|
||||
return SenderHtlcSpendTimeout(bobRecvrSig, aliceSigner,
|
||||
signDesc, sweepTx)
|
||||
return SenderHtlcSpendTimeout(
|
||||
bobRecvrSig, bobSigHash, aliceSigner,
|
||||
signDesc, sweepTx,
|
||||
)
|
||||
}),
|
||||
true,
|
||||
},
|
||||
@ -487,8 +495,10 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
|
||||
InputIndex: 0,
|
||||
}
|
||||
|
||||
return SenderHtlcSpendTimeout(bobRecvrSig, aliceSigner,
|
||||
signDesc, sweepTx)
|
||||
return SenderHtlcSpendTimeout(
|
||||
bobRecvrSig, bobSigHash, aliceSigner,
|
||||
signDesc, sweepTx,
|
||||
)
|
||||
}),
|
||||
true,
|
||||
},
|
||||
@ -517,8 +527,10 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
|
||||
InputIndex: 0,
|
||||
}
|
||||
|
||||
return SenderHtlcSpendTimeout(bobRecvrSig, aliceSigner,
|
||||
signDesc, sweepTx)
|
||||
return SenderHtlcSpendTimeout(
|
||||
bobRecvrSig, bobSigHash, aliceSigner,
|
||||
signDesc, sweepTx,
|
||||
)
|
||||
}),
|
||||
false,
|
||||
},
|
||||
@ -611,6 +623,7 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
|
||||
receiverCommitTx, sweepTx *wire.MsgTx
|
||||
sweepTxSigHashes *txscript.TxSigHashes
|
||||
aliceSenderSig []byte
|
||||
aliceSigHash txscript.SigHashType
|
||||
)
|
||||
|
||||
genCommitTx := func(confirmed bool) {
|
||||
@ -663,6 +676,11 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
|
||||
)
|
||||
sweepTxSigHashes = txscript.NewTxSigHashes(sweepTx)
|
||||
|
||||
aliceSigHash = txscript.SigHashAll
|
||||
if confirmed {
|
||||
aliceSigHash = txscript.SigHashSingle | txscript.SigHashAnyOneCanPay
|
||||
}
|
||||
|
||||
// We'll also generate a signature on the sweep transaction above
|
||||
// that will act as Alice's signature to Bob for the second level HTLC
|
||||
// transaction.
|
||||
@ -673,7 +691,7 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
|
||||
SingleTweak: aliceCommitTweak,
|
||||
WitnessScript: htlcWitnessScript,
|
||||
Output: htlcOutput,
|
||||
HashType: txscript.SigHashAll,
|
||||
HashType: aliceSigHash,
|
||||
SigHashes: sweepTxSigHashes,
|
||||
InputIndex: 0,
|
||||
}
|
||||
@ -706,9 +724,11 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
|
||||
InputIndex: 0,
|
||||
}
|
||||
|
||||
return ReceiverHtlcSpendRedeem(aliceSenderSig,
|
||||
return ReceiverHtlcSpendRedeem(
|
||||
aliceSenderSig, aliceSigHash,
|
||||
bytes.Repeat([]byte{1}, 45), bobSigner,
|
||||
signDesc, sweepTx)
|
||||
signDesc, sweepTx,
|
||||
)
|
||||
|
||||
}),
|
||||
false,
|
||||
@ -731,9 +751,11 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
|
||||
InputIndex: 0,
|
||||
}
|
||||
|
||||
return ReceiverHtlcSpendRedeem(aliceSenderSig,
|
||||
paymentPreimage[:], bobSigner,
|
||||
signDesc, sweepTx)
|
||||
return ReceiverHtlcSpendRedeem(
|
||||
aliceSenderSig, aliceSigHash,
|
||||
paymentPreimage, bobSigner,
|
||||
signDesc, sweepTx,
|
||||
)
|
||||
}),
|
||||
true,
|
||||
},
|
||||
@ -783,9 +805,11 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
|
||||
InputIndex: 0,
|
||||
}
|
||||
|
||||
return ReceiverHtlcSpendRedeem(aliceSenderSig,
|
||||
return ReceiverHtlcSpendRedeem(
|
||||
aliceSenderSig, aliceSigHash,
|
||||
paymentPreimage, bobSigner,
|
||||
signDesc, sweepTx)
|
||||
signDesc, sweepTx,
|
||||
)
|
||||
}),
|
||||
true,
|
||||
},
|
||||
@ -813,9 +837,11 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
|
||||
InputIndex: 0,
|
||||
}
|
||||
|
||||
return ReceiverHtlcSpendRedeem(aliceSenderSig,
|
||||
paymentPreimage, bobSigner,
|
||||
signDesc, sweepTx)
|
||||
return ReceiverHtlcSpendRedeem(
|
||||
aliceSenderSig, aliceSigHash,
|
||||
paymentPreimage, bobSigner, signDesc,
|
||||
sweepTx,
|
||||
)
|
||||
}),
|
||||
false,
|
||||
},
|
||||
|
@ -2748,6 +2748,7 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
||||
txHash := remoteCommitView.txn.TxHash()
|
||||
dustLimit := remoteChanCfg.DustLimit
|
||||
feePerKw := remoteCommitView.feePerKw
|
||||
sigHashType := HtlcSigHashType(chanType)
|
||||
|
||||
// With the keys generated, we'll make a slice with enough capacity to
|
||||
// hold potentially all the HTLCs. The actual slice may be a bit
|
||||
@ -2807,7 +2808,7 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
||||
Output: &wire.TxOut{
|
||||
Value: int64(htlc.Amount.ToSatoshis()),
|
||||
},
|
||||
HashType: txscript.SigHashAll,
|
||||
HashType: sigHashType,
|
||||
SigHashes: txscript.NewTxSigHashes(sigJob.Tx),
|
||||
InputIndex: 0,
|
||||
}
|
||||
@ -2858,7 +2859,7 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
||||
Output: &wire.TxOut{
|
||||
Value: int64(htlc.Amount.ToSatoshis()),
|
||||
},
|
||||
HashType: txscript.SigHashAll,
|
||||
HashType: sigHashType,
|
||||
SigHashes: txscript.NewTxSigHashes(sigJob.Tx),
|
||||
InputIndex: 0,
|
||||
}
|
||||
@ -3811,6 +3812,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment,
|
||||
|
||||
txHash := localCommitmentView.txn.TxHash()
|
||||
feePerKw := localCommitmentView.feePerKw
|
||||
sigHashType := HtlcSigHashType(chanType)
|
||||
|
||||
// With the required state generated, we'll create a slice with large
|
||||
// enough capacity to hold verification jobs for all HTLC's in this
|
||||
@ -3865,7 +3867,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment,
|
||||
hashCache := txscript.NewTxSigHashes(successTx)
|
||||
sigHash, err := txscript.CalcWitnessSigHash(
|
||||
htlc.ourWitnessScript, hashCache,
|
||||
txscript.SigHashAll, successTx, 0,
|
||||
sigHashType, successTx, 0,
|
||||
int64(htlc.Amount.ToSatoshis()),
|
||||
)
|
||||
if err != nil {
|
||||
@ -3919,7 +3921,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment,
|
||||
hashCache := txscript.NewTxSigHashes(timeoutTx)
|
||||
sigHash, err := txscript.CalcWitnessSigHash(
|
||||
htlc.ourWitnessScript, hashCache,
|
||||
txscript.SigHashAll, timeoutTx, 0,
|
||||
sigHashType, timeoutTx, 0,
|
||||
int64(htlc.Amount.ToSatoshis()),
|
||||
)
|
||||
if err != nil {
|
||||
@ -5403,8 +5405,9 @@ func newOutgoingHtlcResolution(signer input.Signer,
|
||||
|
||||
// With the sign desc created, we can now construct the full witness
|
||||
// for the timeout transaction, and populate it as well.
|
||||
sigHashType := HtlcSigHashType(chanType)
|
||||
timeoutWitness, err := input.SenderHtlcSpendTimeout(
|
||||
htlc.Signature, signer, &timeoutSignDesc, timeoutTx,
|
||||
htlc.Signature, sigHashType, signer, &timeoutSignDesc, timeoutTx,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -5530,8 +5533,10 @@ func newIncomingHtlcResolution(signer input.Signer,
|
||||
// the success transaction. Don't specify the preimage yet. The preimage
|
||||
// will be supplied by the contract resolver, either directly or when it
|
||||
// becomes known.
|
||||
sigHashType := HtlcSigHashType(chanType)
|
||||
successWitness, err := input.ReceiverHtlcSpendRedeem(
|
||||
htlc.Signature, nil, signer, &successSignDesc, successTx,
|
||||
htlc.Signature, sigHashType, nil, signer, &successSignDesc,
|
||||
successTx,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
@ -224,6 +225,16 @@ func CommitScriptToRemote(chanType channeldb.ChannelType,
|
||||
}, 0, nil
|
||||
}
|
||||
|
||||
// HtlcSigHashType returns the sighash type to use for HTLC success and timeout
|
||||
// transactions given the channel type.
|
||||
func HtlcSigHashType(chanType channeldb.ChannelType) txscript.SigHashType {
|
||||
if chanType.HasAnchors() {
|
||||
return txscript.SigHashSingle | txscript.SigHashAnyOneCanPay
|
||||
}
|
||||
|
||||
return txscript.SigHashAll
|
||||
}
|
||||
|
||||
// CommitWeight returns the base commitment weight before adding HTLCs.
|
||||
func CommitWeight(chanType channeldb.ChannelType) int64 {
|
||||
// If this commitment has anchors, it will be slightly heavier.
|
||||
|
Loading…
Reference in New Issue
Block a user