walletrpc: add new deadline-delta param to bumpfee rpc

Add new parameter deadline-delta to the bumpfee request and only
allow it to be used when the budget value is used as well.
This commit is contained in:
ziggie committed 2025-02-07 11:28:41 +01:00
1 parent e40324358a
commit 34c4d12c71
7 files changed
+623 -465

No files matched your search

+74 -21
View File
@@ -955,7 +955,7 @@ func UnmarshallOutPoint(op *lnrpc.OutPoint) (*wire.OutPoint, error) {
// validateBumpFeeRequest makes sure the deprecated fields are not used when
// the new fields are set.
func validateBumpFeeRequest(in *BumpFeeRequest) (
func validateBumpFeeRequest(in *BumpFeeRequest, estimator chainfee.Estimator) (
fn.Option[chainfee.SatPerKWeight], bool, error) {
// Get the specified fee rate if set.
@@ -980,6 +980,31 @@ func validateBumpFeeRequest(in *BumpFeeRequest) (
satPerKwOpt = fn.Some(satPerKw)
}
// We make sure either the conf target or the exact fee rate is
// specified for the starting fee of the fee function.
if in.TargetConf != 0 && !satPerKwOpt.IsNone() {
return satPerKwOpt, false,
fmt.Errorf("either TargetConf or SatPerVbyte should " +
"be set, to specify the starting fee rate of " +
"the fee function")
}
// In case the user specified a conf target, we estimate the fee rate
// for the given target using the provided estimator.
if in.TargetConf != 0 {
startingFeeRate, err := estimator.EstimateFeePerKW(
in.TargetConf,
)
if err != nil {
return satPerKwOpt, false, fmt.Errorf("unable to "+
"estimate fee rate for target conf %d: %w",
in.TargetConf, err)
}
// Set the starting fee rate to the estimated fee rate.
satPerKwOpt = fn.Some(startingFeeRate)
}
var immediate bool
switch {
case in.Force && in.Immediate:
@@ -993,6 +1018,11 @@ func validateBumpFeeRequest(in *BumpFeeRequest) (
immediate = in.Immediate
}
if in.DeadlineDelta != 0 && in.Budget == 0 {
return satPerKwOpt, immediate, fmt.Errorf("budget must be " +
"set if deadline-delta is set")
}
return satPerKwOpt, immediate, nil
}
@@ -1002,8 +1032,10 @@ func validateBumpFeeRequest(in *BumpFeeRequest) (
func (w *WalletKit) prepareSweepParams(in *BumpFeeRequest,
op wire.OutPoint, currentHeight int32) (sweep.Params, bool, error) {
// Return an error if both deprecated and new fields are used.
feerate, immediate, err := validateBumpFeeRequest(in)
// Return an error if the bump fee request is invalid.
feeRate, immediate, err := validateBumpFeeRequest(
in, w.cfg.FeeEstimator,
)
if err != nil {
return sweep.Params{}, false, err
}
@@ -1025,12 +1057,13 @@ func (w *WalletKit) prepareSweepParams(in *BumpFeeRequest,
// specified, the params would have a zero budget.
params := sweep.Params{
Immediate: immediate,
StartingFeeRate: feerate,
StartingFeeRate: feeRate,
Budget: btcutil.Amount(in.Budget),
}
if in.TargetConf != 0 {
if in.DeadlineDelta != 0 {
params.DeadlineHeight = fn.Some(
int32(in.TargetConf) + currentHeight,
int32(in.DeadlineDelta) + currentHeight,
)
}
@@ -1041,7 +1074,9 @@ func (w *WalletKit) prepareSweepParams(in *BumpFeeRequest,
// must be greater than zero.
budget := inp.Params.Budget
// Set the new budget if specified.
// Set the new budget if specified. If a new deadline delta is
// specified we also require the budget value which is checked in the
// validateBumpFeeRequest function.
if in.Budget != 0 {
budget = btcutil.Amount(in.Budget)
}
@@ -1050,13 +1085,21 @@ func (w *WalletKit) prepareSweepParams(in *BumpFeeRequest,
// a deadline is requested.
deadline := inp.Params.DeadlineHeight
// Set the deadline if target conf is specified.
// Set the deadline if it was specified.
//
// TODO(yy): upgrade `falafel` so we can make this field optional. Atm
// we cannot distinguish between user's not setting the field and
// setting it to 0.
if in.TargetConf != 0 {
deadline = fn.Some(int32(in.TargetConf) + currentHeight)
if in.DeadlineDelta != 0 {
deadline = fn.Some(int32(in.DeadlineDelta) + currentHeight)
}
startingFeeRate := inp.Params.StartingFeeRate
// We only set the starting fee rate if it was specified else we keep
// the existing one.
if feeRate.IsSome() {
startingFeeRate = feeRate
}
// Prepare the new sweep params.
@@ -1065,15 +1108,13 @@ func (w *WalletKit) prepareSweepParams(in *BumpFeeRequest,
// specified, the params would have a zero budget.
params := sweep.Params{
Immediate: immediate,
StartingFeeRate: feerate,
DeadlineHeight: deadline,
StartingFeeRate: startingFeeRate,
Budget: budget,
}
if ok {
log.Infof("[BumpFee]: bumping fee for existing input=%v, old "+
"params=%v, new params=%v", op, inp.Params, params)
}
log.Infof("[BumpFee]: bumping fee for existing input=%v, old "+
"params=%v, new params=%v", op, inp.Params, params)
return params, ok, nil
}
@@ -1263,11 +1304,12 @@ func (w *WalletKit) BumpForceCloseFee(_ context.Context,
// by the mempool rules.
params, existing, err := w.prepareSweepParams(
&BumpFeeRequest{
Outpoint: lnrpcOutpoint,
TargetConf: in.DeadlineDelta,
SatPerVbyte: in.StartingFeerate,
Immediate: in.Immediate,
Budget: in.Budget,
Outpoint: lnrpcOutpoint,
TargetConf: in.TargetConf,
SatPerVbyte: in.StartingFeerate,
Immediate: in.Immediate,
Budget: in.Budget,
DeadlineDelta: in.DeadlineDelta,
}, anchor.OutPoint, currentHeight,
)
if err != nil {
@@ -1323,11 +1365,22 @@ func (w *WalletKit) sweepNewInput(op *wire.OutPoint, currentHeight uint32,
"transaction")
}
// If there's no budget set, use the default value.
// TODO(ziggie): The budget value should ideally only be set for CPFP
// requests because for RBF requests we should have already registered
// the input including the budget value in the first place. However it
// might not be set and then depending on the deadline delta fee
// estimations might become too aggressive. So need to evaluate whether
// we set a default value here, make it configurable or fail request
// in that case.
if params.Budget == 0 {
params.Budget = utxo.Value.MulF64(
contractcourt.DefaultBudgetRatio,
)
log.Warnf("[BumpFee]: setting default budget value of %v for "+
"input=%v, which will be used for the maximum fee "+
"rate estimation (budget was not specified)",
params.Budget, op)
}
signDesc := &input.SignDescriptor{