From be74d94c48498459814cd690be58efb06f5bd285 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 4 Mar 2020 08:00:09 -0800 Subject: [PATCH 1/4] lnwallet/size_test: add test exercising nested input count bug This commit modifies the NP2WKH and NP2WSH input tests to ensure the input count is properly incremented and accounted for in the size estimate. 253 is chosen because it is the lowest value that, when serialized, occupies more than one byte on the wire. --- lnwallet/size_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lnwallet/size_test.go b/lnwallet/size_test.go index 36dac258d..cf8cbb68e 100644 --- a/lnwallet/size_test.go +++ b/lnwallet/size_test.go @@ -97,11 +97,11 @@ func TestTxWeightEstimator(t *testing.T) { numP2SHOutputs: 1, }, { - numNestedP2WKHInputs: 1, + numNestedP2WKHInputs: 253, numP2WKHOutputs: 1, }, { - numNestedP2WSHInputs: 1, + numNestedP2WSHInputs: 253, numP2WKHOutputs: 1, }, } From 6eb7f2800dc251c388e6ef5210f408ac5bffea78 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 4 Mar 2020 08:00:33 -0800 Subject: [PATCH 2/4] input/size: correct NP2WKH and NP2SH input count This commit corrects a bug in TxWeightEstimator that could result in underestimations for transactions involving NestedP2WPKH and NestedP2WSH inputs. The scriptSig data push is now accounted for in a proper size constant, and the input count is now incremented in both. This would only be detectable in the event that the number of non-nested inputs and the total number of inputs straddle the discontinuities in the CompactSize encoding, e.g. 253, 2^16-1, or 2^32-1. --- input/size.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/input/size.go b/input/size.go index 68fa85e4e..a9406f8a9 100644 --- a/input/size.go +++ b/input/size.go @@ -25,12 +25,22 @@ const ( // - PublicKeyHASH160: 20 bytes P2WPKHSize = 1 + 1 + 20 + // NestedP2WPKHSize 23 bytes + // - OP_DATA: 1 byte (P2WPKHSize) + // - P2WPKHWitnessProgram: 22 bytes + NestedP2WPKHSize = 1 + P2WPKHSize + // P2WSHSize 34 bytes // - OP_0: 1 byte // - OP_DATA: 1 byte (WitnessScriptSHA256 length) // - WitnessScriptSHA256: 32 bytes P2WSHSize = 1 + 1 + 32 + // NestedP2WSHSize 35 bytes + // - OP_DATA: 1 byte (P2WSHSize) + // - P2WSHWitnessProgram: 35 bytes + NestedP2WSHSize = 1 + P2WSHSize + // P2PKHOutputSize 34 bytes // - value: 8 bytes // - var_int: 1 byte (pkscript_length) @@ -417,9 +427,9 @@ func (twe *TxWeightEstimator) AddWitnessInput(witnessSize int) *TxWeightEstimato // AddNestedP2WKHInput updates the weight estimate to account for an additional // input spending a P2SH output with a nested P2WKH redeem script. func (twe *TxWeightEstimator) AddNestedP2WKHInput() *TxWeightEstimator { - twe.inputSize += InputSize + P2WPKHSize + twe.inputSize += InputSize + NestedP2WPKHSize twe.inputWitnessSize += P2WKHWitnessSize - twe.inputSize++ + twe.inputCount++ twe.hasWitness = true return twe @@ -428,9 +438,9 @@ func (twe *TxWeightEstimator) AddNestedP2WKHInput() *TxWeightEstimator { // AddNestedP2WSHInput updates the weight estimate to account for an additional // input spending a P2SH output with a nested P2WSH redeem script. func (twe *TxWeightEstimator) AddNestedP2WSHInput(witnessSize int) *TxWeightEstimator { - twe.inputSize += InputSize + P2WSHSize + twe.inputSize += InputSize + NestedP2WSHSize twe.inputWitnessSize += witnessSize - twe.inputSize++ + twe.inputCount++ twe.hasWitness = true return twe From 4c402ab9d470aba23321b2ac75dcf307be2c0ad4 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 4 Mar 2020 08:00:48 -0800 Subject: [PATCH 3/4] lnwallet/size_test: refactor and expand unit tests --- lnwallet/size_test.go | 95 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/lnwallet/size_test.go b/lnwallet/size_test.go index cf8cbb68e..acc83b965 100644 --- a/lnwallet/size_test.go +++ b/lnwallet/size_test.go @@ -68,6 +68,68 @@ func TestTxWeightEstimator(t *testing.T) { numP2WSHOutputs int numP2SHOutputs int }{ + // Assert base txn size. + {}, + + // Assert single input/output sizes. + { + numP2PKHInputs: 1, + }, + { + numP2WKHInputs: 1, + }, + { + numP2WSHInputs: 1, + }, + { + numNestedP2WKHInputs: 1, + }, + { + numNestedP2WSHInputs: 1, + }, + { + numP2WKHOutputs: 1, + }, + { + numP2PKHOutputs: 1, + }, + { + numP2WSHOutputs: 1, + }, + { + numP2SHOutputs: 1, + }, + + // Assert each input/output increments input/output counts. + { + numP2PKHInputs: 253, + }, + { + numP2WKHInputs: 253, + }, + { + numP2WSHInputs: 253, + }, + { + numNestedP2WKHInputs: 253, + }, + { + numNestedP2WSHInputs: 253, + }, + { + numP2WKHOutputs: 253, + }, + { + numP2PKHOutputs: 253, + }, + { + numP2WSHOutputs: 253, + }, + { + numP2SHOutputs: 253, + }, + + // Assert basic combinations of inputs and outputs. { numP2PKHInputs: 1, numP2PKHOutputs: 2, @@ -97,13 +159,42 @@ func TestTxWeightEstimator(t *testing.T) { numP2SHOutputs: 1, }, { - numNestedP2WKHInputs: 253, + numNestedP2WKHInputs: 1, numP2WKHOutputs: 1, }, { - numNestedP2WSHInputs: 253, + numNestedP2WSHInputs: 1, numP2WKHOutputs: 1, }, + + // Assert disparate input/output types increment total + // input/output counts. + { + numP2PKHInputs: 50, + numP2WKHInputs: 50, + numP2WSHInputs: 51, + numNestedP2WKHInputs: 51, + numNestedP2WSHInputs: 51, + numP2WKHOutputs: 1, + }, + { + numP2WKHInputs: 1, + numP2WKHOutputs: 63, + numP2PKHOutputs: 63, + numP2WSHOutputs: 63, + numP2SHOutputs: 64, + }, + { + numP2PKHInputs: 50, + numP2WKHInputs: 50, + numP2WSHInputs: 51, + numNestedP2WKHInputs: 51, + numNestedP2WSHInputs: 51, + numP2WKHOutputs: 63, + numP2PKHOutputs: 63, + numP2WSHOutputs: 63, + numP2SHOutputs: 64, + }, } for i, test := range testCases { From 4c2bc7bc79c25b47cc7037b1fea684d102a4bce6 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 4 Mar 2020 08:01:37 -0800 Subject: [PATCH 4/4] lnwallet+input: move size_test.go to input pkg --- {lnwallet => input}/size_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename {lnwallet => input}/size_test.go (99%) diff --git a/lnwallet/size_test.go b/input/size_test.go similarity index 99% rename from lnwallet/size_test.go rename to input/size_test.go index acc83b965..916434022 100644 --- a/lnwallet/size_test.go +++ b/input/size_test.go @@ -1,4 +1,4 @@ -package lnwallet_test +package input_test import ( "testing"