Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

coin select: add coin selection strategy option to all on-chain RPCs #8515

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions cmd/lncli/cmd_open_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,7 @@ var batchOpenChannelCommand = cli.Command{
"transaction when storing it to the local " +
"wallet after publishing it",
},
coinSelectionStrategyFlag,
},
Action: actionDecorator(batchOpenChannel),
}
Expand Down Expand Up @@ -845,13 +846,19 @@ func batchOpenChannel(ctx *cli.Context) error {
return nil
}

coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
if err != nil {
return err
}

minConfs := int32(ctx.Uint64("min_confs"))
req := &lnrpc.BatchOpenChannelRequest{
TargetConf: int32(ctx.Int64("conf_target")),
SatPerVbyte: int64(ctx.Uint64("sat_per_vbyte")),
MinConfs: minConfs,
SpendUnconfirmed: minConfs == 0,
Label: ctx.String("label"),
TargetConf: int32(ctx.Int64("conf_target")),
SatPerVbyte: int64(ctx.Uint64("sat_per_vbyte")),
MinConfs: minConfs,
SpendUnconfirmed: minConfs == 0,
Label: ctx.String("label"),
CoinSelectionStrategy: coinSelectionStrategy,
}

// Let's try and parse the JSON part of the CLI now. Fortunately we can
Expand Down
67 changes: 49 additions & 18 deletions cmd/lncli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,16 @@ func newAddress(ctx *cli.Context) error {
return nil
}

var coinSelectionStrategyFlag = cli.StringFlag{
Name: "coin_selection_strategy",
Usage: "(optional) the strategy to use for selecting " +
"coins. Possible values are 'largest', 'random', or " +
"'global-config'. If either 'largest' or 'random' is " +
"specified, it will override the globally configured " +
"strategy in lnd.conf",
Value: "global-config",
}

var estimateFeeCommand = cli.Command{
Name: "estimatefee",
Category: "On-chain",
Expand All @@ -215,9 +225,10 @@ var estimateFeeCommand = cli.Command{
Flags: []cli.Flag{
cli.Int64Flag{
Name: "conf_target",
Usage: "(optional) the number of blocks that the transaction *should* " +
"confirm in",
Usage: "(optional) the number of blocks that the " +
"transaction *should* confirm in",
},
coinSelectionStrategyFlag,
},
Action: actionDecorator(estimateFees),
}
Expand All @@ -231,12 +242,18 @@ func estimateFees(ctx *cli.Context) error {
return err
}

coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
if err != nil {
return err
}

client, cleanUp := getClient(ctx)
defer cleanUp()

resp, err := client.EstimateFee(ctxc, &lnrpc.EstimateFeeRequest{
AddrToAmount: amountToAddr,
TargetConf: int32(ctx.Int64("conf_target")),
AddrToAmount: amountToAddr,
TargetConf: int32(ctx.Int64("conf_target")),
CoinSelectionStrategy: coinSelectionStrategy,
})
if err != nil {
return err
Expand Down Expand Up @@ -313,6 +330,7 @@ var sendCoinsCommand = cli.Command{
"terminal avoid breaking existing shell " +
"scripts",
},
coinSelectionStrategyFlag,
txLabelFlag,
},
Action: actionDecorator(sendCoins),
Expand Down Expand Up @@ -375,6 +393,11 @@ func sendCoins(ctx *cli.Context) error {
"sweep all coins out of the wallet")
}

coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
if err != nil {
return err
}

client, cleanUp := getClient(ctx)
defer cleanUp()
minConfs := int32(ctx.Uint64("min_confs"))
Expand Down Expand Up @@ -409,14 +432,15 @@ func sendCoins(ctx *cli.Context) error {
}

req := &lnrpc.SendCoinsRequest{
Addr: addr,
Amount: amt,
TargetConf: int32(ctx.Int64("conf_target")),
SatPerVbyte: ctx.Uint64(feeRateFlag),
SendAll: ctx.Bool("sweepall"),
Label: ctx.String(txLabelFlag.Name),
MinConfs: minConfs,
SpendUnconfirmed: minConfs == 0,
Addr: addr,
Amount: amt,
TargetConf: int32(ctx.Int64("conf_target")),
SatPerVbyte: ctx.Uint64(feeRateFlag),
SendAll: ctx.Bool("sweepall"),
Label: ctx.String(txLabelFlag.Name),
MinConfs: minConfs,
SpendUnconfirmed: minConfs == 0,
CoinSelectionStrategy: coinSelectionStrategy,
}
txid, err := client.SendCoins(ctxc, req)
if err != nil {
Expand Down Expand Up @@ -585,6 +609,7 @@ var sendManyCommand = cli.Command{
"must satisfy",
Value: defaultUtxoMinConf,
},
coinSelectionStrategyFlag,
txLabelFlag,
},
Action: actionDecorator(sendMany),
Expand Down Expand Up @@ -615,17 +640,23 @@ func sendMany(ctx *cli.Context) error {
return err
}

coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
if err != nil {
return err
}

client, cleanUp := getClient(ctx)
defer cleanUp()

minConfs := int32(ctx.Uint64("min_confs"))
txid, err := client.SendMany(ctxc, &lnrpc.SendManyRequest{
AddrToAmount: amountToAddr,
TargetConf: int32(ctx.Int64("conf_target")),
SatPerVbyte: ctx.Uint64(feeRateFlag),
Label: ctx.String(txLabelFlag.Name),
MinConfs: minConfs,
SpendUnconfirmed: minConfs == 0,
AddrToAmount: amountToAddr,
TargetConf: int32(ctx.Int64("conf_target")),
SatPerVbyte: ctx.Uint64(feeRateFlag),
Label: ctx.String(txLabelFlag.Name),
MinConfs: minConfs,
SpendUnconfirmed: minConfs == 0,
CoinSelectionStrategy: coinSelectionStrategy,
})
if err != nil {
return err
Expand Down
28 changes: 28 additions & 0 deletions cmd/lncli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,3 +564,31 @@ func networkParams(ctx *cli.Context) (*chaincfg.Params, error) {
return nil, fmt.Errorf("unknown network: %v", network)
}
}

// parseCoinSelectionStrategy parses a coin selection strategy string
// from the CLI to its lnrpc.CoinSelectionStrategy counterpart proto type.
func parseCoinSelectionStrategy(ctx *cli.Context) (
lnrpc.CoinSelectionStrategy, error) {

strategy := ctx.String(coinSelectionStrategyFlag.Name)
if !ctx.IsSet(coinSelectionStrategyFlag.Name) {
return lnrpc.CoinSelectionStrategy_STRATEGY_USE_GLOBAL_CONFIG,
nil
}

switch strategy {
case "global-config":
return lnrpc.CoinSelectionStrategy_STRATEGY_USE_GLOBAL_CONFIG,
nil

case "largest":
return lnrpc.CoinSelectionStrategy_STRATEGY_LARGEST, nil

case "random":
return lnrpc.CoinSelectionStrategy_STRATEGY_RANDOM, nil

default:
return 0, fmt.Errorf("unknown coin selection strategy "+
"%v", strategy)
}
}
20 changes: 17 additions & 3 deletions cmd/lncli/walletrpc_active.go
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,7 @@ var fundTemplatePsbtCommand = cli.Command{
"if required",
Value: -1,
},
coinSelectionStrategyFlag,
},
Action: actionDecorator(fundTemplatePsbt),
}
Expand Down Expand Up @@ -997,6 +998,11 @@ func fundTemplatePsbt(ctx *cli.Context) error {
"inputs/outputs flag")
}

coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
if err != nil {
return err
}

minConfs := int32(ctx.Uint64("min_confs"))
req := &walletrpc.FundPsbtRequest{
Account: ctx.String("account"),
Expand All @@ -1005,6 +1011,7 @@ func fundTemplatePsbt(ctx *cli.Context) error {
Template: &walletrpc.FundPsbtRequest_CoinSelect{
CoinSelect: coinSelect,
},
CoinSelectionStrategy: coinSelectionStrategy,
}

// Parse fee flags.
Expand Down Expand Up @@ -1167,6 +1174,7 @@ var fundPsbtCommand = cli.Command{
"transaction must satisfy",
Value: defaultUtxoMinConf,
},
coinSelectionStrategyFlag,
},
Action: actionDecorator(fundPsbt),
}
Expand All @@ -1180,11 +1188,17 @@ func fundPsbt(ctx *cli.Context) error {
return cli.ShowCommandHelp(ctx, "fund")
}

coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
if err != nil {
return err
}

minConfs := int32(ctx.Uint64("min_confs"))
req := &walletrpc.FundPsbtRequest{
Account: ctx.String("account"),
MinConfs: minConfs,
SpendUnconfirmed: minConfs == 0,
Account: ctx.String("account"),
MinConfs: minConfs,
SpendUnconfirmed: minConfs == 0,
CoinSelectionStrategy: coinSelectionStrategy,
}

// Parse template flags.
Expand Down
4 changes: 4 additions & 0 deletions docs/release-notes/release-notes-0.18.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ bitcoin peers' feefilter values into account](https://github.com/lightningnetwor
* [Allow callers of `ListSweeps` to specify the start
height](https://github.com/lightningnetwork/lnd/pull/7372).

* [Coin Selection Strategy](https://github.com/lightningnetwork/lnd/pull/8515)
add coin selection strategy option to the following on-chain RPC calls
`EstimateFee`, `SendMany`, `SendCoins`, `BatchOpenChannel`, `SendOutputs`, and `FundPsbt`.

## lncli Updates

* [Documented all available `lncli`
Expand Down
7 changes: 4 additions & 3 deletions funding/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,10 @@ func (b *Batcher) BatchFund(ctx context.Context,
Fees: &walletrpc.FundPsbtRequest_SatPerVbyte{
SatPerVbyte: uint64(feeRateSatPerVByte),
},
MinConfs: firstReq.MinConfs,
SpendUnconfirmed: firstReq.MinConfs == 0,
ChangeType: changeType,
MinConfs: firstReq.MinConfs,
SpendUnconfirmed: firstReq.MinConfs == 0,
ChangeType: changeType,
CoinSelectionStrategy: req.CoinSelectionStrategy,
}
fundPsbtResp, err := b.cfg.WalletKitServer.FundPsbt(ctx, fundPsbtReq)
if err != nil {
Expand Down
Loading
Loading