input/size: add txSize test
Similar to what we do for witnesses, check that the HTLC weight constants check out. They actually do not, since the spec is off by one. We ensure we agree with the spec.
This commit is contained in:
parent
2bc37db61a
commit
d30aae43e6
@ -7,12 +7,16 @@ import (
|
|||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/keychain"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -23,6 +27,8 @@ const (
|
|||||||
// maxDERSignatureSize is the largest possible DER-encoded signature
|
// maxDERSignatureSize is the largest possible DER-encoded signature
|
||||||
// without the trailing sighash flag.
|
// without the trailing sighash flag.
|
||||||
maxDERSignatureSize = 72
|
maxDERSignatureSize = 72
|
||||||
|
|
||||||
|
testAmt = btcutil.MaxSatoshi
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -40,6 +46,11 @@ var (
|
|||||||
testPrivkey, _ = btcec.PrivKeyFromBytes(btcec.S256(), make([]byte, 32))
|
testPrivkey, _ = btcec.PrivKeyFromBytes(btcec.S256(), make([]byte, 32))
|
||||||
|
|
||||||
testTx = wire.NewMsgTx(2)
|
testTx = wire.NewMsgTx(2)
|
||||||
|
|
||||||
|
testOutPoint = wire.OutPoint{
|
||||||
|
Hash: chainhash.Hash{},
|
||||||
|
Index: 1,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestTxWeightEstimator tests that transaction weight estimates are calculated
|
// TestTxWeightEstimator tests that transaction weight estimates are calculated
|
||||||
@ -845,3 +856,158 @@ func TestWitnessSizes(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// genTimeoutTx creates a signed HTLC second level timeout tx.
|
||||||
|
func genTimeoutTx(chanType channeldb.ChannelType) (*wire.MsgTx, error) {
|
||||||
|
// Create the unsigned timeout tx.
|
||||||
|
timeoutTx, err := lnwallet.CreateHtlcTimeoutTx(
|
||||||
|
chanType, testOutPoint, testAmt, testCLTVExpiry,
|
||||||
|
testCSVDelay, testPubkey, testPubkey,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// In order to sign the transcation, generate the script for the output
|
||||||
|
// it spends.
|
||||||
|
witScript, err := input.SenderHTLCScript(
|
||||||
|
testPubkey, testPubkey, testPubkey, testHash160,
|
||||||
|
chanType.HasAnchors(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
signDesc := &input.SignDescriptor{
|
||||||
|
WitnessScript: witScript,
|
||||||
|
KeyDesc: keychain.KeyDescriptor{
|
||||||
|
PubKey: testPubkey,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign the timeout tx and add the witness.
|
||||||
|
sigHashType := lnwallet.HtlcSigHashType(chanType)
|
||||||
|
timeoutWitness, err := input.SenderHtlcSpendTimeout(
|
||||||
|
&maxDERSignature{}, sigHashType, &dummySigner{},
|
||||||
|
signDesc, timeoutTx,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
timeoutTx.TxIn[0].Witness = timeoutWitness
|
||||||
|
|
||||||
|
return timeoutTx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// genSuccessTx creates a signed HTLC second level success tx.
|
||||||
|
func genSuccessTx(chanType channeldb.ChannelType) (*wire.MsgTx, error) {
|
||||||
|
// Create the unisgned success tx.
|
||||||
|
successTx, err := lnwallet.CreateHtlcSuccessTx(
|
||||||
|
chanType, testOutPoint, testAmt, testCSVDelay,
|
||||||
|
testPubkey, testPubkey,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// In order to sign the transcation, generate the script for the output
|
||||||
|
// it spends.
|
||||||
|
witScript, err := input.ReceiverHTLCScript(
|
||||||
|
testCLTVExpiry, testPubkey, testPubkey,
|
||||||
|
testPubkey, testHash160, chanType.HasAnchors(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
signDesc := &input.SignDescriptor{
|
||||||
|
WitnessScript: witScript,
|
||||||
|
KeyDesc: keychain.KeyDescriptor{
|
||||||
|
PubKey: testPubkey,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign the success tx and add the witness.
|
||||||
|
sigHashType := lnwallet.HtlcSigHashType(channeldb.SingleFunderBit)
|
||||||
|
successWitness, err := input.ReceiverHtlcSpendRedeem(
|
||||||
|
&maxDERSignature{}, sigHashType, testPreimage,
|
||||||
|
&dummySigner{}, signDesc, successTx,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
successTx.TxIn[0].Witness = successWitness
|
||||||
|
|
||||||
|
return successTx, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type txSizeTest struct {
|
||||||
|
name string
|
||||||
|
expWeight int64
|
||||||
|
genTx func(t *testing.T) *wire.MsgTx
|
||||||
|
}
|
||||||
|
|
||||||
|
var txSizeTests = []txSizeTest{
|
||||||
|
{
|
||||||
|
name: "htlc timeout regular ",
|
||||||
|
expWeight: input.HtlcTimeoutWeight,
|
||||||
|
genTx: func(t *testing.T) *wire.MsgTx {
|
||||||
|
tx, err := genTimeoutTx(channeldb.SingleFunderBit)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "htlc timeout confirmed",
|
||||||
|
expWeight: input.HtlcTimeoutWeightConfirmed,
|
||||||
|
genTx: func(t *testing.T) *wire.MsgTx {
|
||||||
|
tx, err := genTimeoutTx(channeldb.AnchorOutputsBit)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "htlc success regular",
|
||||||
|
// The weight estimate from the spec is off by one, but it's
|
||||||
|
// okay since we overestimate the weight.
|
||||||
|
expWeight: input.HtlcSuccessWeight - 1,
|
||||||
|
genTx: func(t *testing.T) *wire.MsgTx {
|
||||||
|
tx, err := genSuccessTx(channeldb.SingleFunderBit)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "htlc success confirmed",
|
||||||
|
// The weight estimate from the spec is off by one, but it's
|
||||||
|
// okay since we overestimate the weight.
|
||||||
|
expWeight: input.HtlcSuccessWeightConfirmed - 1,
|
||||||
|
genTx: func(t *testing.T) *wire.MsgTx {
|
||||||
|
tx, err := genSuccessTx(channeldb.AnchorOutputsBit)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWitnessSizes asserts the correctness of our magic tx size constants.
|
||||||
|
func TestTxSizes(t *testing.T) {
|
||||||
|
for _, test := range txSizeTests {
|
||||||
|
test := test
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
tx := test.genTx(t)
|
||||||
|
|
||||||
|
weight := blockchain.GetTransactionWeight(btcutil.NewTx(tx))
|
||||||
|
if weight != test.expWeight {
|
||||||
|
t.Fatalf("size mismatch, want: %v, got: %v",
|
||||||
|
test.expWeight, weight)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user