input: introduce Signature iface

This commit introduces the Signature interface which will be used by our
witness construction methods instead of passing in raw byte slices. This
will be used later to inject various kinds of mock signatures, e.g.
73-byte signatures for simulating worst-case witness weight.
This commit is contained in:
Conner Fromknecht 2020-04-05 17:06:14 -07:00
parent 2b2c8b5a10
commit 37dffb225a
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7
3 changed files with 37 additions and 11 deletions

View File

@ -23,6 +23,13 @@ var (
SequenceLockTimeSeconds = uint32(1 << 22) SequenceLockTimeSeconds = uint32(1 << 22)
) )
// Signature is an interface for objects that can populate signatures during
// witness construction.
type Signature interface {
// Serialize returns a DER-encoded ECDSA signature.
Serialize() []byte
}
// WitnessScriptHash generates a pay-to-witness-script-hash public key script // WitnessScriptHash generates a pay-to-witness-script-hash public key script
// paying to a version 0 witness program paying to the passed redeem script. // paying to a version 0 witness program paying to the passed redeem script.
func WitnessScriptHash(witnessScript []byte) ([]byte, error) { func WitnessScriptHash(witnessScript []byte) ([]byte, error) {
@ -343,7 +350,7 @@ func SenderHtlcSpendRedeem(signer Signer, signDesc *SignDescriptor,
// HTLC to activate the time locked covenant clause of a soon to be expired // 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 // HTLC. This script simply spends the multi-sig output using the
// pre-generated HTLC timeout transaction. // pre-generated HTLC timeout transaction.
func SenderHtlcSpendTimeout(receiverSig []byte, func SenderHtlcSpendTimeout(receiverSig Signature,
receiverSigHash txscript.SigHashType, signer Signer, receiverSigHash txscript.SigHashType, signer Signer,
signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx) ( signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx) (
wire.TxWitness, error) { wire.TxWitness, error) {
@ -359,7 +366,7 @@ func SenderHtlcSpendTimeout(receiverSig []byte,
// original OP_CHECKMULTISIG. // original OP_CHECKMULTISIG.
witnessStack := wire.TxWitness(make([][]byte, 5)) witnessStack := wire.TxWitness(make([][]byte, 5))
witnessStack[0] = nil witnessStack[0] = nil
witnessStack[1] = append(receiverSig, byte(receiverSigHash)) witnessStack[1] = append(receiverSig.Serialize(), byte(receiverSigHash))
witnessStack[2] = append(sweepSig, byte(signDesc.HashType)) witnessStack[2] = append(sweepSig, byte(signDesc.HashType))
witnessStack[3] = nil witnessStack[3] = nil
witnessStack[4] = signDesc.WitnessScript witnessStack[4] = signDesc.WitnessScript
@ -508,7 +515,7 @@ func ReceiverHTLCScript(cltvExpiry uint32, senderHtlcKey,
// signed has a relative timelock delay enforced by its sequence number. This // 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 // delay give the sender of the HTLC enough time to revoke the output if this
// is a breach commitment transaction. // is a breach commitment transaction.
func ReceiverHtlcSpendRedeem(senderSig []byte, func ReceiverHtlcSpendRedeem(senderSig Signature,
senderSigHash txscript.SigHashType, paymentPreimage []byte, senderSigHash txscript.SigHashType, paymentPreimage []byte,
signer Signer, signDesc *SignDescriptor, htlcSuccessTx *wire.MsgTx) ( signer Signer, signDesc *SignDescriptor, htlcSuccessTx *wire.MsgTx) (
wire.TxWitness, error) { wire.TxWitness, error) {
@ -527,7 +534,7 @@ func ReceiverHtlcSpendRedeem(senderSig []byte,
// order to consume the extra pop within OP_CHECKMULTISIG. // order to consume the extra pop within OP_CHECKMULTISIG.
witnessStack := wire.TxWitness(make([][]byte, 5)) witnessStack := wire.TxWitness(make([][]byte, 5))
witnessStack[0] = nil witnessStack[0] = nil
witnessStack[1] = append(senderSig, byte(senderSigHash)) witnessStack[1] = append(senderSig.Serialize(), byte(senderSigHash))
witnessStack[2] = append(sweepSig, byte(signDesc.HashType)) witnessStack[2] = append(sweepSig, byte(signDesc.HashType))
witnessStack[3] = paymentPreimage witnessStack[3] = paymentPreimage
witnessStack[4] = signDesc.WitnessScript witnessStack[4] = signDesc.WitnessScript

View File

@ -226,7 +226,7 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
htlcOutput *wire.TxOut htlcOutput *wire.TxOut
sweepTxSigHashes *txscript.TxSigHashes sweepTxSigHashes *txscript.TxSigHashes
senderCommitTx, sweepTx *wire.MsgTx senderCommitTx, sweepTx *wire.MsgTx
bobRecvrSig []byte bobRecvrSig *btcec.Signature
bobSigHash txscript.SigHashType bobSigHash txscript.SigHashType
) )
@ -303,10 +303,15 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
SigHashes: sweepTxSigHashes, SigHashes: sweepTxSigHashes,
InputIndex: 0, InputIndex: 0,
} }
bobRecvrSig, err = bobSigner.SignOutputRaw(sweepTx, &bobSignDesc) bobSigBytes, err := bobSigner.SignOutputRaw(sweepTx, &bobSignDesc)
if err != nil { if err != nil {
t.Fatalf("unable to generate alice signature: %v", err) t.Fatalf("unable to generate alice signature: %v", err)
} }
bobRecvrSig, err = btcec.ParseDERSignature(bobSigBytes, btcec.S256())
if err != nil {
t.Fatalf("unable to parse signature: %v", err)
}
} }
testCases := []struct { testCases := []struct {
@ -622,7 +627,7 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
htlcOutput *wire.TxOut htlcOutput *wire.TxOut
receiverCommitTx, sweepTx *wire.MsgTx receiverCommitTx, sweepTx *wire.MsgTx
sweepTxSigHashes *txscript.TxSigHashes sweepTxSigHashes *txscript.TxSigHashes
aliceSenderSig []byte aliceSenderSig *btcec.Signature
aliceSigHash txscript.SigHashType aliceSigHash txscript.SigHashType
) )
@ -695,10 +700,15 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
SigHashes: sweepTxSigHashes, SigHashes: sweepTxSigHashes,
InputIndex: 0, InputIndex: 0,
} }
aliceSenderSig, err = aliceSigner.SignOutputRaw(sweepTx, &aliceSignDesc) aliceSigBytes, err := aliceSigner.SignOutputRaw(sweepTx, &aliceSignDesc)
if err != nil { if err != nil {
t.Fatalf("unable to generate alice signature: %v", err) t.Fatalf("unable to generate alice signature: %v", err)
} }
aliceSenderSig, err = btcec.ParseDERSignature(aliceSigBytes, btcec.S256())
if err != nil {
t.Fatalf("unable to parse signature: %v", err)
}
} }
// TODO(roasbeef): modify valid to check precise script errors? // TODO(roasbeef): modify valid to check precise script errors?

View File

@ -5459,11 +5459,16 @@ func newOutgoingHtlcResolution(signer input.Signer,
InputIndex: 0, InputIndex: 0,
} }
htlcSig, err := btcec.ParseDERSignature(htlc.Signature, btcec.S256())
if err != nil {
return nil, err
}
// With the sign desc created, we can now construct the full witness // With the sign desc created, we can now construct the full witness
// for the timeout transaction, and populate it as well. // for the timeout transaction, and populate it as well.
sigHashType := HtlcSigHashType(chanType) sigHashType := HtlcSigHashType(chanType)
timeoutWitness, err := input.SenderHtlcSpendTimeout( timeoutWitness, err := input.SenderHtlcSpendTimeout(
htlc.Signature, sigHashType, signer, &timeoutSignDesc, timeoutTx, htlcSig, sigHashType, signer, &timeoutSignDesc, timeoutTx,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -5585,14 +5590,18 @@ func newIncomingHtlcResolution(signer input.Signer,
InputIndex: 0, InputIndex: 0,
} }
htlcSig, err := btcec.ParseDERSignature(htlc.Signature, btcec.S256())
if err != nil {
return nil, err
}
// Next, we'll construct the full witness needed to satisfy the input of // Next, we'll construct the full witness needed to satisfy the input of
// the success transaction. Don't specify the preimage yet. The preimage // the success transaction. Don't specify the preimage yet. The preimage
// will be supplied by the contract resolver, either directly or when it // will be supplied by the contract resolver, either directly or when it
// becomes known. // becomes known.
sigHashType := HtlcSigHashType(chanType) sigHashType := HtlcSigHashType(chanType)
successWitness, err := input.ReceiverHtlcSpendRedeem( successWitness, err := input.ReceiverHtlcSpendRedeem(
htlc.Signature, sigHashType, nil, signer, &successSignDesc, htlcSig, sigHashType, nil, signer, &successSignDesc, successTx,
successTx,
) )
if err != nil { if err != nil {
return nil, err return nil, err