Skip to content

Commit

Permalink
Merge pull request #8515 from mohamedawnallah/add-coin-selection-stra…
Browse files Browse the repository at this point in the history
…tegy-on-chain-rpc

coin select: add coin selection strategy option to all on-chain RPCs
  • Loading branch information
guggero committed Apr 2, 2024
2 parents b331e73 + 31526a0 commit b117551
Show file tree
Hide file tree
Showing 23 changed files with 4,296 additions and 3,880 deletions.
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 @@ -303,6 +303,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

0 comments on commit b117551

Please sign in to comment.