mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
24fa35ec80
This commit updates the `fee()` method in `weightEstimator` to make sure when doing CPFP we are not exceeding the max allowed fee rate. In order to use the max fee rate, we need to modify several methods to pass the configured value to the estimator.
152 lines
4.3 KiB
Go
152 lines
4.3 KiB
Go
package sweep
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
|
"github.com/btcsuite/btcd/chaincfg"
|
|
"github.com/btcsuite/btcd/txscript"
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/lightningnetwork/lnd/input"
|
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestWeightEstimator tests weight estimation for inputs with and without
|
|
// unconfirmed parents.
|
|
func TestWeightEstimator(t *testing.T) {
|
|
testFeeRate := chainfee.SatPerKWeight(20000)
|
|
|
|
w := newWeightEstimator(testFeeRate, 0)
|
|
|
|
// Add an input without unconfirmed parent tx.
|
|
input1 := input.MakeBaseInput(
|
|
&wire.OutPoint{}, input.CommitmentAnchor,
|
|
&input.SignDescriptor{}, 0, nil,
|
|
)
|
|
|
|
require.NoError(t, w.add(&input1))
|
|
|
|
// The expectations is that this input is added.
|
|
const expectedWeight1 = 322
|
|
require.Equal(t, expectedWeight1, w.weight())
|
|
require.Equal(t, testFeeRate.FeeForWeight(expectedWeight1), w.fee())
|
|
|
|
// Define a parent transaction that pays a fee of 30000 sat/kw.
|
|
parentTxHighFee := &input.TxInfo{
|
|
Weight: 100,
|
|
Fee: 3000,
|
|
}
|
|
|
|
// Add an output of the parent tx above.
|
|
input2 := input.MakeBaseInput(
|
|
&wire.OutPoint{}, input.CommitmentAnchor,
|
|
&input.SignDescriptor{}, 0,
|
|
parentTxHighFee,
|
|
)
|
|
|
|
require.NoError(t, w.add(&input2))
|
|
|
|
// Pay for parent isn't possible because the parent pays a higher fee
|
|
// rate than the child. We expect no additional fee on the child.
|
|
const expectedWeight2 = expectedWeight1 + 280
|
|
require.Equal(t, expectedWeight2, w.weight())
|
|
require.Equal(t, testFeeRate.FeeForWeight(expectedWeight2), w.fee())
|
|
|
|
// Define a parent transaction that pays a fee of 10000 sat/kw.
|
|
parentTxLowFee := &input.TxInfo{
|
|
Weight: 100,
|
|
Fee: 1000,
|
|
}
|
|
|
|
// Add an output of the low-fee parent tx above.
|
|
input3 := input.MakeBaseInput(
|
|
&wire.OutPoint{}, input.CommitmentAnchor,
|
|
&input.SignDescriptor{}, 0,
|
|
parentTxLowFee,
|
|
)
|
|
require.NoError(t, w.add(&input3))
|
|
|
|
// Expect the weight to increase because of the third input.
|
|
const expectedWeight3 = expectedWeight2 + 280
|
|
require.Equal(t, expectedWeight3, w.weight())
|
|
|
|
// Expect the fee to cover the child and the parent transaction at 20
|
|
// sat/kw after subtraction of the fee that was already paid by the
|
|
// parent.
|
|
expectedFee := testFeeRate.FeeForWeight(
|
|
expectedWeight3+parentTxLowFee.Weight,
|
|
) - parentTxLowFee.Fee
|
|
|
|
require.Equal(t, expectedFee, w.fee())
|
|
}
|
|
|
|
// TestWeightEstimatorMaxFee tests that the weight estimator correctly caps the
|
|
// fee at the maximum allowed fee.
|
|
func TestWeightEstimatorMaxFee(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testFeeRate := chainfee.SatPerKWeight(9_000)
|
|
maxFeeRate := chainfee.SatPerKWeight(10_000)
|
|
|
|
w := newWeightEstimator(testFeeRate, maxFeeRate)
|
|
|
|
// Define a parent transaction that pays a fee of 1000 sat/kw.
|
|
parentTxLowFee := &input.TxInfo{
|
|
Weight: 100,
|
|
Fee: 100,
|
|
}
|
|
|
|
// Add an output of the low-fee parent tx above.
|
|
childInput := input.MakeBaseInput(
|
|
&wire.OutPoint{}, input.CommitmentAnchor,
|
|
&input.SignDescriptor{}, 0, parentTxLowFee,
|
|
)
|
|
require.NoError(t, w.add(&childInput))
|
|
|
|
// The child weight should be 322 weight uints.
|
|
const childWeight = 322
|
|
require.Equal(t, childWeight, w.weight())
|
|
|
|
// Check the fee is capped at the maximum allowed fee. The
|
|
// calculations,
|
|
//
|
|
// totalWeight = childWeight + parentWeight = 422
|
|
// fee = totalWeight * testFeeRate - parentsFee =
|
|
// 422 * 9_000 / 1000 - 100 = 3598
|
|
// maxFee = childWeight * maxFeeRate = 422 * 10_000 / 1000 = 3220
|
|
//
|
|
// Thus we cap at the maxFee.
|
|
expectedFee := maxFeeRate.FeeForWeight(childWeight)
|
|
require.Equal(t, expectedFee, w.fee())
|
|
}
|
|
|
|
// TestWeightEstimatorAddOutput tests that adding the raw P2WKH output to the
|
|
// estimator yield the same result as an estimated add.
|
|
func TestWeightEstimatorAddOutput(t *testing.T) {
|
|
testFeeRate := chainfee.SatPerKWeight(20000)
|
|
|
|
p2wkhAddr, err := btcutil.NewAddressWitnessPubKeyHash(
|
|
make([]byte, 20), &chaincfg.MainNetParams,
|
|
)
|
|
require.NoError(t, err)
|
|
|
|
p2wkhScript, err := txscript.PayToAddrScript(p2wkhAddr)
|
|
require.NoError(t, err)
|
|
|
|
// Create two estimators, add the raw P2WKH out to one.
|
|
txOut := &wire.TxOut{
|
|
PkScript: p2wkhScript,
|
|
Value: 10000,
|
|
}
|
|
|
|
w1 := newWeightEstimator(testFeeRate, 0)
|
|
w1.addOutput(txOut)
|
|
|
|
w2 := newWeightEstimator(testFeeRate, 0)
|
|
w2.addP2WKHOutput()
|
|
|
|
// Estimate hhould be the same.
|
|
require.Equal(t, w1.weight(), w2.weight())
|
|
}
|