mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 01:43:16 +01:00
sweep: ensure we factor in extra change addrs in MaxFeeRateAllowed
This commit is contained in:
parent
f2adabb989
commit
bdaa9f4146
@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/lnutils"
|
"github.com/lightningnetwork/lnd/lnutils"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||||
|
"github.com/lightningnetwork/lnd/tlv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -43,6 +44,19 @@ var (
|
|||||||
ErrThirdPartySpent = errors.New("third party spent the output")
|
ErrThirdPartySpent = errors.New("third party spent the output")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// dummyChangePkScript is a dummy tapscript change script that's used
|
||||||
|
// when we don't need a real address, just something that can be used
|
||||||
|
// for fee estimation.
|
||||||
|
dummyChangePkScript = []byte{
|
||||||
|
0x51, 0x20,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Bumper defines an interface that can be used by other subsystems for fee
|
// Bumper defines an interface that can be used by other subsystems for fee
|
||||||
// bumping.
|
// bumping.
|
||||||
type Bumper interface {
|
type Bumper interface {
|
||||||
@ -129,12 +143,33 @@ type BumpRequest struct {
|
|||||||
// compares it with the specified MaxFeeRate, and returns the smaller of the
|
// compares it with the specified MaxFeeRate, and returns the smaller of the
|
||||||
// two.
|
// two.
|
||||||
func (r *BumpRequest) MaxFeeRateAllowed() (chainfee.SatPerKWeight, error) {
|
func (r *BumpRequest) MaxFeeRateAllowed() (chainfee.SatPerKWeight, error) {
|
||||||
|
// We'll want to know if we have any blobs, as we need to factor this
|
||||||
|
// into the max fee rate for this bump request.
|
||||||
|
hasBlobs := fn.Any(func(i input.Input) bool {
|
||||||
|
return fn.MapOptionZ(
|
||||||
|
i.ResolutionBlob(), func(b tlv.Blob) bool {
|
||||||
|
return len(b) > 0
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}, r.Inputs)
|
||||||
|
|
||||||
|
sweepAddrs := [][]byte{
|
||||||
|
r.DeliveryAddress.DeliveryAddress,
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have blobs, then we'll add an extra sweep addr for the size
|
||||||
|
// estimate below. We know that these blobs will also always be based on
|
||||||
|
// p2tr addrs.
|
||||||
|
if hasBlobs {
|
||||||
|
// We need to pass in a real address, so we'll use a dummy
|
||||||
|
// tapscript change script that's used elsewhere for tests.
|
||||||
|
sweepAddrs = append(sweepAddrs, dummyChangePkScript)
|
||||||
|
}
|
||||||
|
|
||||||
// Get the size of the sweep tx, which will be used to calculate the
|
// Get the size of the sweep tx, which will be used to calculate the
|
||||||
// budget fee rate.
|
// budget fee rate.
|
||||||
//
|
|
||||||
// TODO(roasbeef): also wants the extra change output?
|
|
||||||
size, err := calcSweepTxWeight(
|
size, err := calcSweepTxWeight(
|
||||||
r.Inputs, r.DeliveryAddress.DeliveryAddress,
|
r.Inputs, sweepAddrs,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -163,7 +198,7 @@ func (r *BumpRequest) MaxFeeRateAllowed() (chainfee.SatPerKWeight, error) {
|
|||||||
// calcSweepTxWeight calculates the weight of the sweep tx. It assumes a
|
// calcSweepTxWeight calculates the weight of the sweep tx. It assumes a
|
||||||
// sweeping tx always has a single output(change).
|
// sweeping tx always has a single output(change).
|
||||||
func calcSweepTxWeight(inputs []input.Input,
|
func calcSweepTxWeight(inputs []input.Input,
|
||||||
outputPkScript []byte) (lntypes.WeightUnit, error) {
|
outputPkScript [][]byte) (lntypes.WeightUnit, error) {
|
||||||
|
|
||||||
// Use a const fee rate as we only use the weight estimator to
|
// Use a const fee rate as we only use the weight estimator to
|
||||||
// calculate the size.
|
// calculate the size.
|
||||||
@ -177,7 +212,7 @@ func calcSweepTxWeight(inputs []input.Input,
|
|||||||
// TODO(yy): we should refactor the weight estimator to not require a
|
// TODO(yy): we should refactor the weight estimator to not require a
|
||||||
// fee rate and max fee rate and make it a pure tx weight calculator.
|
// fee rate and max fee rate and make it a pure tx weight calculator.
|
||||||
_, estimator, err := getWeightEstimate(
|
_, estimator, err := getWeightEstimate(
|
||||||
inputs, nil, feeRate, 0, [][]byte{outputPkScript},
|
inputs, nil, feeRate, 0, outputPkScript,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -115,13 +115,15 @@ func TestCalcSweepTxWeight(t *testing.T) {
|
|||||||
inp := createTestInput(100, input.WitnessKeyHash)
|
inp := createTestInput(100, input.WitnessKeyHash)
|
||||||
|
|
||||||
// Use a wrong change script to test the error case.
|
// Use a wrong change script to test the error case.
|
||||||
weight, err := calcSweepTxWeight([]input.Input{&inp}, []byte{0})
|
weight, err := calcSweepTxWeight(
|
||||||
|
[]input.Input{&inp}, [][]byte{{0x00}},
|
||||||
|
)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Zero(t, weight)
|
require.Zero(t, weight)
|
||||||
|
|
||||||
// Use a correct change script to test the success case.
|
// Use a correct change script to test the success case.
|
||||||
weight, err = calcSweepTxWeight(
|
weight, err = calcSweepTxWeight(
|
||||||
[]input.Input{&inp}, changePkScript.DeliveryAddress,
|
[]input.Input{&inp}, [][]byte{changePkScript.DeliveryAddress},
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -143,7 +145,7 @@ func TestBumpRequestMaxFeeRateAllowed(t *testing.T) {
|
|||||||
|
|
||||||
// The weight is 487.
|
// The weight is 487.
|
||||||
weight, err := calcSweepTxWeight(
|
weight, err := calcSweepTxWeight(
|
||||||
[]input.Input{&inp}, changePkScript.DeliveryAddress,
|
[]input.Input{&inp}, [][]byte{changePkScript.DeliveryAddress},
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ func TestNewBudgetInputSet(t *testing.T) {
|
|||||||
rt.ErrorContains(err, "duplicate inputs")
|
rt.ErrorContains(err, "duplicate inputs")
|
||||||
rt.Nil(set)
|
rt.Nil(set)
|
||||||
|
|
||||||
// Pass a slice of inputs that only one input has the deadline height,
|
// Pass a slice of inputs that only one input has the deadline height.
|
||||||
set, err = NewBudgetInputSet(
|
set, err = NewBudgetInputSet(
|
||||||
[]SweeperInput{input0, input3}, testHeight,
|
[]SweeperInput{input0, input3}, testHeight,
|
||||||
fn.None[AuxSweeper](),
|
fn.None[AuxSweeper](),
|
||||||
|
@ -262,7 +262,8 @@ func getWeightEstimate(inputs []input.Input, outputs []*wire.TxOut,
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
// Unknown script type.
|
// Unknown script type.
|
||||||
return nil, nil, errors.New("unknown script type")
|
return nil, nil, fmt.Errorf("unknown script "+
|
||||||
|
"type: %x", outputPkScript)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user