cmd/lncli: add fee limit flags to routing related commands

This commit is contained in:
Wilmer Paulino 2018-04-19 10:28:13 -04:00
parent 63f079d1a4
commit a9d873d248
No known key found for this signature in database
GPG Key ID: 6DF57B9F9514972F

@ -103,37 +103,6 @@ func actionDecorator(f func(*cli.Context) error) func(*cli.Context) error {
}
}
// calculateFeeLimit takes ctx and the amount for the payment in satoshis.
// It checks the fee_limit and fee_limit_percent flags and determines the
// the feeLimit based on those values. If both flags are set, calculateFeeLimit
// sets feeLimit to the Minumum value between them. If neither flag is set,
// feeLimit is set to the maximum int64 value as to avoid enforcing a limit.
func calculateFeeLimit(ctx *cli.Context, amount int64) int64 {
var (
feeLimit int64
feeLimitPercent int64
)
const MaxInt64Value int64 = 1<<63 - 1 // 9223372036854775807
feeLimit = MaxInt64Value
if ctx.IsSet("fee_limit_percent") {
feeRatio := float64(ctx.Int64("fee_limit_percent")) / 100
feeLimitPercent = int64(float64(amount) * feeRatio)
feeLimit = feeLimitPercent
}
if ctx.IsSet("fee_limit") {
feeLimit = ctx.Int64("fee_limit")
}
// If both fee_limit and fee_limit_percent are set, pick the minimum
if ctx.IsSet("fee_limit") && ctx.IsSet("fee_limit_percent") {
feeLimit = int64(math.Min(float64(feeLimit), float64(feeLimitPercent)))
}
return feeLimit
}
var newAddressCommand = cli.Command{
Name: "newaddress",
Category: "Wallet",
@ -1648,6 +1617,16 @@ var sendPaymentCommand = cli.Command{
Name: "amt, a",
Usage: "number of satoshis to send",
},
cli.Int64Flag{
Name: "fee_limit",
Usage: "maximum fee allowed in satoshis when sending" +
"the payment",
},
cli.Int64Flag{
Name: "fee_limit_percent",
Usage: "percentage of the payment's amount used as the" +
"maximum fee allowed when sending the payment",
},
cli.StringFlag{
Name: "payment_hash, r",
Usage: "the hash to use within the payment's HTLC",
@ -1664,18 +1643,36 @@ var sendPaymentCommand = cli.Command{
Name: "final_cltv_delta",
Usage: "the number of blocks the last hop has to reveal the preimage",
},
cli.Int64Flag{
Name: "fee_limit",
Usage: "maximum total fees for the payment in satoshis",
},
cli.Int64Flag{
Name: "fee_limit_percent",
Usage: "maximum total fees as a percentage of amt",
},
},
Action: sendPayment,
}
// retrieveFeeLimit retrieves the fee limit based on the different fee limit
// flags passed.
func retrieveFeeLimit(ctx *cli.Context) (*lnrpc.FeeLimit, error) {
switch {
case ctx.IsSet("fee_limit") && ctx.IsSet("fee_limit_percent"):
return nil, fmt.Errorf("either fee_limit or fee_limit_percent " +
"can be set, but not both")
case ctx.IsSet("fee_limit"):
return &lnrpc.FeeLimit{
Limit: &lnrpc.FeeLimit_Fixed{
Fixed: ctx.Int64("fee_limit"),
},
}, nil
case ctx.IsSet("fee_limit_percent"):
return &lnrpc.FeeLimit{
Limit: &lnrpc.FeeLimit_Percent{
Percent: ctx.Int64("fee_limit_percent"),
},
}, nil
}
// Since the fee limit flags aren't required, we don't return an error
// if they're not set.
return nil, nil
}
func sendPayment(ctx *cli.Context) error {
// Show command help if no arguments provided
if ctx.NArg() == 0 && ctx.NumFlags() == 0 {
@ -1683,22 +1680,33 @@ func sendPayment(ctx *cli.Context) error {
return nil
}
var req *lnrpc.SendRequest
// First, we'll retrieve the fee limit value passed since it can apply
// to both ways of sending payments (with the payment request or
// providing the details manually).
feeLimit, err := retrieveFeeLimit(ctx)
if err != nil {
return err
}
// If a payment request was provided, we can exit early since all of the
// details of the payment are encoded within the request.
if ctx.IsSet("pay_req") {
req = &lnrpc.SendRequest{
req := &lnrpc.SendRequest{
PaymentRequest: ctx.String("pay_req"),
Amt: ctx.Int64("amt"),
FeeLimit: feeLimit,
}
return sendPaymentRequest(ctx, req)
}
} else {
args := ctx.Args()
var (
destNode []byte
err error
amount int64
feeLimit int64
)
args := ctx.Args()
switch {
case ctx.IsSet("dest"):
destNode, err = hex.DecodeString(ctx.String("dest"))
@ -1727,9 +1735,7 @@ func sendPayment(ctx *cli.Context) error {
}
}
feeLimit = calculateFeeLimit(ctx, amount)
req = &lnrpc.SendRequest{
req := &lnrpc.SendRequest{
Dest: destNode,
Amt: amount,
FeeLimit: feeLimit,
@ -1769,7 +1775,6 @@ func sendPayment(ctx *cli.Context) error {
req.FinalCltvDelta = int32(delta)
}
}
}
return sendPaymentRequest(ctx, req)
}
@ -1824,11 +1829,13 @@ var payInvoiceCommand = cli.Command{
},
cli.Int64Flag{
Name: "fee_limit",
Usage: "maximum total fees for the payment in satoshis",
Usage: "maximum fee allowed in satoshis when sending" +
"the payment",
},
cli.Int64Flag{
Name: "fee_limit_percent",
Usage: "maximum total fees as a percentage of amt",
Usage: "percentage of the payment's amount used as the" +
"maximum fee allowed when sending the payment",
},
},
Action: actionDecorator(payInvoice),
@ -1838,9 +1845,6 @@ func payInvoice(ctx *cli.Context) error {
args := ctx.Args()
var payReq string
var feeLimit int64
var amt int64
switch {
case ctx.IsSet("pay_req"):
payReq = ctx.String("pay_req")
@ -1850,13 +1854,14 @@ func payInvoice(ctx *cli.Context) error {
return fmt.Errorf("pay_req argument missing")
}
amt = ctx.Int64("amt")
feeLimit = calculateFeeLimit(ctx, amt)
feeLimit, err := retrieveFeeLimit(ctx)
if err != nil {
return err
}
req := &lnrpc.SendRequest{
PaymentRequest: payReq,
Amt: amt,
Amt: ctx.Int64("amt"),
FeeLimit: feeLimit,
}
@ -2559,11 +2564,13 @@ var queryRoutesCommand = cli.Command{
},
cli.Int64Flag{
Name: "fee_limit",
Usage: "maximum total fees for the payment in satoshis",
Usage: "maximum fee allowed in satoshis when sending" +
"the payment",
},
cli.Int64Flag{
Name: "fee_limit_percent",
Usage: "maximum total fees as a percentage of amt",
Usage: "percentage of the payment's amount used as the" +
"maximum fee allowed when sending the payment",
},
cli.Int64Flag{
Name: "num_max_routes",
@ -2588,7 +2595,6 @@ func queryRoutes(ctx *cli.Context) error {
dest string
amt int64
err error
feeLimit int64
)
args := ctx.Args()
@ -2615,11 +2621,15 @@ func queryRoutes(ctx *cli.Context) error {
return fmt.Errorf("amt argument missing")
}
feeLimit = calculateFeeLimit(ctx, amt)
feeLimit, err := retrieveFeeLimit(ctx)
if err != nil {
return err
}
req := &lnrpc.QueryRoutesRequest{
PubKey: dest,
Amt: amt,
FeeLimit: feeLimit,
NumRoutes: int32(ctx.Int("num_max_routes")),
FinalCltvDelta: int32(ctx.Int("final_cltv_delta")),
}