cmd: update bumpfee, bumpclosefee and bumpforceclosefee

This commit is contained in:
yyforyongyu 2024-04-03 02:23:40 +08:00
parent 6f55a7af05
commit 7abefa7760
No known key found for this signature in database
GPG key ID: 9BCD95C4FF296868

View file

@ -177,56 +177,78 @@ var bumpFeeCommand = cli.Command{
Usage: "Bumps the fee of an arbitrary input/transaction.",
ArgsUsage: "outpoint",
Description: `
This command takes a different approach than bitcoind's bumpfee command.
lnd has a central batching engine in which inputs with similar fee rates
are batched together to save on transaction fees. Due to this, we cannot
rely on bumping the fee on a specific transaction, since transactions
can change at any point with the addition of new inputs. The list of
inputs that currently exist within lnd's central batching engine can be
retrieved through lncli wallet pendingsweeps.
BumpFee is an endpoint that allows users to interact with lnd's sweeper
directly. It takes an outpoint from an unconfirmed transaction and
sends it to the sweeper for potential fee bumping. Depending on whether
the outpoint has been registered in the sweeper (an existing input,
e.g., an anchor output) or not (a new input, e.g., an unconfirmed
wallet utxo), this will either be an RBF or CPFP attempt.
When bumping the fee of an input that currently exists within lnd's
central batching engine, a higher fee transaction will be created that
replaces the lower fee transaction through the Replace-By-Fee (RBF)
policy.
When receiving an input, lnds sweeper needs to understand its time
sensitivity to make economical fee bumps - internally a fee function is
created using the deadline and budget to guide the process. When the
deadline is approaching, the fee function will increase the fee rate
and perform an RBF.
This command also serves useful when wanting to perform a
When a force close happens, all the outputs from the force closing
transaction will be registered in the sweeper. The sweeper will then
handle the creation, publish, and fee bumping of the sweeping
transactions. Everytime a new block comes in, unless the sweeping
transaction is confirmed, an RBF is attempted. To interfere with this
automatic process, users can use BumpFee to specify customized fee
rate, budget, deadline, and whether the sweep should happen
immediately. It's recommended to call listsweeps to understand the
shape of the existing sweeping transaction first - depending on the
number of inputs in this transaction, the RBF requirements can be quite
different.
This RPC also serves useful when wanting to perform a
Child-Pays-For-Parent (CPFP), where the child transaction pays for its
parent's fee. This can be done by specifying an outpoint within the low
fee transaction that is under the control of the wallet.
A fee preference must be provided, either through the conf_target or
sat_per_vbyte parameters.
Note that this command currently doesn't perform any validation checks
on the fee preference being provided. For now, the responsibility of
ensuring that the new fee preference is sufficient is delegated to the
user.
The force flag enables sweeping of inputs that are negatively yielding.
Normally it does not make sense to lose money on sweeping, unless a
parent transaction needs to get confirmed and there is only a small
output available to attach the child transaction to.
`,
Flags: []cli.Flag{
cli.Uint64Flag{
Name: "conf_target",
Usage: "the number of blocks that the output should " +
"be swept on-chain within",
Usage: `
The deadline in number of blocks that the input should be spent within.
When not set, for new inputs, the default value (1008) is used; for
exiting inputs, their current values will be retained.`,
},
cli.Uint64Flag{
Name: "sat_per_byte",
Usage: "Deprecated, use sat_per_vbyte instead.",
Hidden: true,
},
cli.BoolFlag{
Name: "force",
Usage: "Deprecated, use immediate instead.",
Hidden: true,
},
cli.Uint64Flag{
Name: "sat_per_vbyte",
Usage: "a manual fee expressed in sat/vbyte that " +
"should be used when sweeping the output",
Usage: `
The starting fee rate, expressed in sat/vbyte, that will be used to
spend the input with initially. This value will be used by the
sweeper's fee function as its starting fee rate. When not set, the
sweeper will use the estimated fee rate using the target_conf as the
starting fee rate.`,
},
cli.BoolFlag{
Name: "force",
Usage: "sweep even if the yield is negative",
Name: "immediate",
Usage: `
Whether this input will be swept immediately. When set to true, the
sweeper will sweep this input without waiting for the next batch.`,
},
cli.Uint64Flag{
Name: "budget",
Usage: `
The max amount in sats that can be used as the fees. Setting this value
greater than the input's value may result in CPFP - one or more wallet
utxos will be used to pay the fees specified by the budget. If not set,
for new inputs, by default 50% of the input's value will be treated as
the budget for fee bumping; for existing inputs, their current budgets
will be retained.`,
},
},
Action: actionDecorator(bumpFee),
@ -241,15 +263,6 @@ func bumpFee(ctx *cli.Context) error {
return cli.ShowCommandHelp(ctx, "bumpfee")
}
// Check that only the field sat_per_vbyte or the deprecated field
// sat_per_byte is used.
feeRateFlag, err := checkNotBothSet(
ctx, "sat_per_vbyte", "sat_per_byte",
)
if err != nil {
return err
}
// Validate and parse the relevant arguments/flags.
protoOutPoint, err := NewProtoOutPoint(ctx.Args().Get(0))
if err != nil {
@ -260,10 +273,10 @@ func bumpFee(ctx *cli.Context) error {
defer cleanUp()
resp, err := client.BumpFee(ctxc, &walletrpc.BumpFeeRequest{
Outpoint: protoOutPoint,
TargetConf: uint32(ctx.Uint64("conf_target")),
SatPerVbyte: ctx.Uint64(feeRateFlag),
Force: ctx.Bool("force"),
Outpoint: protoOutPoint,
TargetConf: uint32(ctx.Uint64("conf_target")),
Immediate: ctx.Bool("force"),
Budget: ctx.Uint64("budget"),
})
if err != nil {
return err
@ -291,18 +304,45 @@ var bumpCloseFeeCommand = cli.Command{
Flags: []cli.Flag{
cli.Uint64Flag{
Name: "conf_target",
Usage: "the number of blocks that the output should " +
"be swept on-chain within",
Usage: `
The deadline in number of blocks that the input should be spent within.
When not set, for new inputs, the default value (1008) is used; for
exiting inputs, their current values will be retained.`,
},
cli.Uint64Flag{
Name: "sat_per_byte",
Usage: "Deprecated, use sat_per_vbyte instead.",
Hidden: true,
},
cli.BoolFlag{
Name: "force",
Usage: "Deprecated, use immediate instead.",
Hidden: true,
},
cli.Uint64Flag{
Name: "sat_per_vbyte",
Usage: "a manual fee expressed in sat/vbyte that " +
"should be used when sweeping the output",
Usage: `
The starting fee rate, expressed in sat/vbyte, that will be used to
spend the input with initially. This value will be used by the
sweeper's fee function as its starting fee rate. When not set, the
sweeper will use the estimated fee rate using the target_conf as the
starting fee rate.`,
},
cli.BoolFlag{
Name: "immediate",
Usage: `
Whether this input will be swept immediately. When set to true, the
sweeper will sweep this input without waiting for the next batch.`,
},
cli.Uint64Flag{
Name: "budget",
Usage: `
The max amount in sats that can be used as the fees. Setting this value
greater than the input's value may result in CPFP - one or more wallet
utxos will be used to pay the fees specified by the budget. If not set,
for new inputs, by default 50% of the input's value will be treated as
the budget for fee bumping; for existing inputs, their current budgets
will be retained.`,
},
},
Action: actionDecorator(bumpForceCloseFee),
@ -323,18 +363,45 @@ var bumpForceCloseFeeCommand = cli.Command{
Flags: []cli.Flag{
cli.Uint64Flag{
Name: "conf_target",
Usage: "the number of blocks that the output should " +
"be swept on-chain within",
Usage: `
The deadline in number of blocks that the input should be spent within.
When not set, for new inputs, the default value (1008) is used; for
exiting inputs, their current values will be retained.`,
},
cli.Uint64Flag{
Name: "sat_per_byte",
Usage: "Deprecated, use sat_per_vbyte instead.",
Hidden: true,
},
cli.BoolFlag{
Name: "force",
Usage: "Deprecated, use immediate instead.",
Hidden: true,
},
cli.Uint64Flag{
Name: "sat_per_vbyte",
Usage: "a manual fee expressed in sat/vbyte that " +
"should be used when sweeping the output",
Usage: `
The starting fee rate, expressed in sat/vbyte, that will be used to
spend the input with initially. This value will be used by the
sweeper's fee function as its starting fee rate. When not set, the
sweeper will use the estimated fee rate using the target_conf as the
starting fee rate.`,
},
cli.BoolFlag{
Name: "immediate",
Usage: `
Whether this input will be swept immediately. When set to true, the
sweeper will sweep this input without waiting for the next batch.`,
},
cli.Uint64Flag{
Name: "budget",
Usage: `
The max amount in sats that can be used as the fees. Setting this value
greater than the input's value may result in CPFP - one or more wallet
utxos will be used to pay the fees specified by the budget. If not set,
for new inputs, by default 50% of the input's value will be treated as
the budget for fee bumping; for existing inputs, their current budgets
will be retained.`,
},
},
Action: actionDecorator(bumpForceCloseFee),
@ -349,18 +416,9 @@ func bumpForceCloseFee(ctx *cli.Context) error {
return cli.ShowCommandHelp(ctx, "bumpclosefee")
}
// Check that only the field sat_per_vbyte or the deprecated field
// sat_per_byte is used.
feeRateFlag, err := checkNotBothSet(
ctx, "sat_per_vbyte", "sat_per_byte",
)
if err != nil {
return err
}
// Validate the channel point.
channelPoint := ctx.Args().Get(0)
_, err = NewProtoOutPoint(channelPoint)
_, err := NewProtoOutPoint(channelPoint)
if err != nil {
return err
}
@ -415,10 +473,10 @@ func bumpForceCloseFee(ctx *cli.Context) error {
resp, err := walletClient.BumpFee(
ctxc, &walletrpc.BumpFeeRequest{
Outpoint: sweep.Outpoint,
TargetConf: uint32(ctx.Uint64("conf_target")),
SatPerVbyte: ctx.Uint64(feeRateFlag),
Force: true,
Outpoint: sweep.Outpoint,
TargetConf: uint32(ctx.Uint64("conf_target")),
Budget: ctx.Uint64("budget"),
Immediate: ctx.Bool("immediate"),
})
if err != nil {
return err