mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
lnwallet: Add TxWeightEstimator support for nested pay-to-witness.
This commit is contained in:
parent
c94130328a
commit
3232fd71c2
@ -19,6 +19,12 @@ const (
|
||||
// WitnessSize - witness size (bytes).
|
||||
// Weight - the metric for determining the weight of the transaction.
|
||||
|
||||
// P2WPKHSize 22 bytes
|
||||
// - OP_0: 1 byte
|
||||
// - OP_DATA: 1 byte (PublicKeyHASH160 length)
|
||||
// - PublicKeyHASH160: 20 bytes
|
||||
P2WPKHSize = 1 + 1 + 20
|
||||
|
||||
// P2WSHSize 34 bytes
|
||||
// - OP_0: 1 byte
|
||||
// - OP_DATA: 1 byte (WitnessScriptSHA256 length)
|
||||
@ -35,19 +41,19 @@ const (
|
||||
// - value: 8 bytes
|
||||
// - var_int: 1 byte (pkscript_length)
|
||||
// - pkscript (p2wpkh): 22 bytes
|
||||
P2WKHOutputSize = 8 + 1 + 22
|
||||
P2WKHOutputSize = 8 + 1 + P2WPKHSize
|
||||
|
||||
// P2WSHOutputSize 43 bytes
|
||||
// - value: 8 bytes
|
||||
// - var_int: 1 byte (pkscript_length)
|
||||
// - pkscript (p2wsh): 34 bytes
|
||||
P2WSHOutputSize = 8 + 1 + 34
|
||||
P2WSHOutputSize = 8 + 1 + P2WSHSize
|
||||
|
||||
// P2WPKHSize 22 bytes
|
||||
// - OP_0: 1 byte
|
||||
// - OP_DATA: 1 byte (PublicKeyHASH160 length)
|
||||
// - PublicKeyHASH160: 20 bytes
|
||||
P2WPKHSize = 1 + 1 + 20
|
||||
// P2SHOutputSize 32 bytes
|
||||
// - value: 8 bytes
|
||||
// - var_int: 1 byte (pkscript_length)
|
||||
// - pkscript (p2sh): 23 bytes
|
||||
P2SHOutputSize = 8 + 1 + 23
|
||||
|
||||
// P2PKHScriptSigSize 108 bytes
|
||||
// - OP_DATA: 1 byte (signature length)
|
||||
@ -337,14 +343,14 @@ func (twe *TxWeightEstimator) AddP2PKHInput() {
|
||||
}
|
||||
|
||||
// AddP2WKHInput updates the weight estimate to account for an additional input
|
||||
// spending a P2PWKH output.
|
||||
// spending a native P2PWKH output.
|
||||
func (twe *TxWeightEstimator) AddP2WKHInput() {
|
||||
twe.AddWitnessInput(P2WKHWitnessSize)
|
||||
}
|
||||
|
||||
// AddWitnessInput updates the weight estimate to account for an additional
|
||||
// input spending a pay-to-witness output. This accepts the total size of the
|
||||
// witness as a parameter.
|
||||
// input spending a native pay-to-witness output. This accepts the total size
|
||||
// of the witness as a parameter.
|
||||
func (twe *TxWeightEstimator) AddWitnessInput(witnessSize int) {
|
||||
twe.inputSize += InputSize
|
||||
twe.inputWitnessSize += witnessSize
|
||||
@ -352,6 +358,24 @@ func (twe *TxWeightEstimator) AddWitnessInput(witnessSize int) {
|
||||
twe.hasWitness = true
|
||||
}
|
||||
|
||||
// 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() {
|
||||
twe.inputSize += InputSize + P2WPKHSize
|
||||
twe.inputWitnessSize += P2WKHWitnessSize
|
||||
twe.inputSize++
|
||||
twe.hasWitness = true
|
||||
}
|
||||
|
||||
// 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) {
|
||||
twe.inputSize += InputSize + P2WSHSize
|
||||
twe.inputWitnessSize += witnessSize
|
||||
twe.inputSize++
|
||||
twe.hasWitness = true
|
||||
}
|
||||
|
||||
// AddP2PKHOutput updates the weight estimate to account for an additional P2PKH
|
||||
// output.
|
||||
func (twe *TxWeightEstimator) AddP2PKHOutput() {
|
||||
@ -359,20 +383,27 @@ func (twe *TxWeightEstimator) AddP2PKHOutput() {
|
||||
twe.outputCount++
|
||||
}
|
||||
|
||||
// AddP2WKHOutput updates the weight estimate to account for an additional P2WKH
|
||||
// output.
|
||||
// AddP2WKHOutput updates the weight estimate to account for an additional
|
||||
// native P2WKH output.
|
||||
func (twe *TxWeightEstimator) AddP2WKHOutput() {
|
||||
twe.outputSize += P2WKHOutputSize
|
||||
twe.outputCount++
|
||||
}
|
||||
|
||||
// AddP2WSHOutput updates the weight estimate to account for an additional P2WSH
|
||||
// output.
|
||||
// AddP2WSHOutput updates the weight estimate to account for an additional
|
||||
// native P2WSH output.
|
||||
func (twe *TxWeightEstimator) AddP2WSHOutput() {
|
||||
twe.outputSize += P2WSHOutputSize
|
||||
twe.outputCount++
|
||||
}
|
||||
|
||||
// AddP2SHOutput updates the weight estimate to account for an additional P2SH
|
||||
// output.
|
||||
func (twe *TxWeightEstimator) AddP2SHOutput() {
|
||||
twe.outputSize += P2SHOutputSize
|
||||
twe.outputCount++
|
||||
}
|
||||
|
||||
// Weight gets the estimated weight of the transaction.
|
||||
func (twe *TxWeightEstimator) Weight() int {
|
||||
txSizeStripped := BaseTxSize +
|
||||
|
@ -47,12 +47,25 @@ func TestTxWeightEstimator(t *testing.T) {
|
||||
t.Fatalf("Failed to generate scriptPubKey: %v", err)
|
||||
}
|
||||
|
||||
p2shAddr, err := btcutil.NewAddressScriptHash([]byte{0}, netParams)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate address: %v", err)
|
||||
}
|
||||
p2shScript, err := txscript.PayToAddrScript(p2shAddr)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate scriptPubKey: %v", err)
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
numP2PKHInputs int
|
||||
numP2WKHInputs int
|
||||
numP2WSHInputs int
|
||||
numNestedP2WKHInputs int
|
||||
numNestedP2WSHInputs int
|
||||
numP2PKHOutputs int
|
||||
numP2WKHOutputs int
|
||||
numP2WSHOutputs int
|
||||
numP2SHOutputs int
|
||||
}{
|
||||
{
|
||||
numP2PKHInputs: 1,
|
||||
@ -74,6 +87,22 @@ func TestTxWeightEstimator(t *testing.T) {
|
||||
numP2WKHOutputs: 1,
|
||||
numP2WSHOutputs: 1,
|
||||
},
|
||||
{
|
||||
numP2WSHInputs: 1,
|
||||
numP2WKHOutputs: 1,
|
||||
},
|
||||
{
|
||||
numP2PKHInputs: 1,
|
||||
numP2SHOutputs: 1,
|
||||
},
|
||||
{
|
||||
numNestedP2WKHInputs: 1,
|
||||
numP2WKHOutputs: 1,
|
||||
},
|
||||
{
|
||||
numNestedP2WSHInputs: 1,
|
||||
numP2WKHOutputs: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
@ -101,6 +130,40 @@ func TestTxWeightEstimator(t *testing.T) {
|
||||
witness := wire.TxWitness{signature, compressedPubKey}
|
||||
tx.AddTxIn(&wire.TxIn{Witness: witness})
|
||||
}
|
||||
for j := 0; j < test.numP2WSHInputs; j++ {
|
||||
weightEstimate.AddWitnessInput(42)
|
||||
|
||||
witnessScript := make([]byte, 40)
|
||||
witness := wire.TxWitness{witnessScript}
|
||||
tx.AddTxIn(&wire.TxIn{Witness: witness})
|
||||
}
|
||||
for j := 0; j < test.numNestedP2WKHInputs; j++ {
|
||||
weightEstimate.AddNestedP2WKHInput()
|
||||
|
||||
signature := make([]byte, 73)
|
||||
compressedPubKey := make([]byte, 33)
|
||||
witness := wire.TxWitness{signature, compressedPubKey}
|
||||
scriptSig, err := txscript.NewScriptBuilder().AddData(p2wkhScript).
|
||||
Script()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate scriptSig: %v", err)
|
||||
}
|
||||
|
||||
tx.AddTxIn(&wire.TxIn{SignatureScript: scriptSig, Witness: witness})
|
||||
}
|
||||
for j := 0; j < test.numNestedP2WSHInputs; j++ {
|
||||
weightEstimate.AddNestedP2WSHInput(42)
|
||||
|
||||
witnessScript := make([]byte, 40)
|
||||
witness := wire.TxWitness{witnessScript}
|
||||
scriptSig, err := txscript.NewScriptBuilder().AddData(p2wshScript).
|
||||
Script()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate scriptSig: %v", err)
|
||||
}
|
||||
|
||||
tx.AddTxIn(&wire.TxIn{SignatureScript: scriptSig, Witness: witness})
|
||||
}
|
||||
for j := 0; j < test.numP2PKHOutputs; j++ {
|
||||
weightEstimate.AddP2PKHOutput()
|
||||
tx.AddTxOut(&wire.TxOut{PkScript: p2pkhScript})
|
||||
@ -113,6 +176,10 @@ func TestTxWeightEstimator(t *testing.T) {
|
||||
weightEstimate.AddP2WSHOutput()
|
||||
tx.AddTxOut(&wire.TxOut{PkScript: p2wshScript})
|
||||
}
|
||||
for j := 0; j < test.numP2SHOutputs; j++ {
|
||||
weightEstimate.AddP2SHOutput()
|
||||
tx.AddTxOut(&wire.TxOut{PkScript: p2shScript})
|
||||
}
|
||||
|
||||
expectedWeight := blockchain.GetTransactionWeight(btcutil.NewTx(tx))
|
||||
if weightEstimate.Weight() != int(expectedWeight) {
|
||||
|
Loading…
Reference in New Issue
Block a user