lnrpc: fix the existing routing fee inaccuracy

When updating the channel routing policy, we encounter an inaccurate
precision error when calculating the routing fee. The issue stems from
the way the IEEE 754 standard works.

The solution here is to add a uint64 parameter (as mentioned in the
issue) and keep the float64 fee_rate parameter but rounding the product
of the base and fee rate.
This commit is contained in:
ErikEk
2021-09-11 23:43:35 +02:00
committed by Olaoluwa Osuntokun
parent 234fdc6c9c
commit ef1eff1058
6 changed files with 837 additions and 770 deletions

View File

@@ -1971,7 +1971,16 @@ var updateChannelPolicyCommand = cli.Command{
Usage: "the fee rate that will be charged " +
"proportionally based on the value of each " +
"forwarded HTLC, the lowest possible rate is 0 " +
"with a granularity of 0.000001 (millionths)",
"with a granularity of 0.000001 (millionths). Can not " +
"be set at the same time as fee_rate_ppm.",
},
cli.Uint64Flag{
Name: "fee_rate_ppm",
Usage: "the fee rate ppm (parts per million) that " +
"will be charged proportionally based on the value of each " +
"forwarded HTLC, the lowest possible rate is 0 " +
"with a granularity of 0.000001 (millionths). Can not " +
"be set at the same time as fee_rate.",
},
cli.Int64Flag{
Name: "time_lock_delta",
@@ -2032,6 +2041,7 @@ func updateChannelPolicy(ctx *cli.Context) error {
var (
baseFee int64
feeRate float64
feeRatePpm uint64
timeLockDelta int64
err error
)
@@ -2051,8 +2061,12 @@ func updateChannelPolicy(ctx *cli.Context) error {
}
switch {
case ctx.IsSet("fee_rate") && ctx.IsSet("fee_rate_ppm"):
return fmt.Errorf("fee_rate or fee_rate_ppm can not both be set")
case ctx.IsSet("fee_rate"):
feeRate = ctx.Float64("fee_rate")
case ctx.IsSet("fee_rate_ppm"):
feeRatePpm = ctx.Uint64("fee_rate_ppm")
case args.Present():
feeRate, err = strconv.ParseFloat(args.First(), 64)
if err != nil {
@@ -2061,7 +2075,7 @@ func updateChannelPolicy(ctx *cli.Context) error {
args = args.Tail()
default:
return fmt.Errorf("fee_rate argument missing")
return fmt.Errorf("fee_rate or fee_rate_ppm argument missing")
}
switch {
@@ -2100,7 +2114,6 @@ func updateChannelPolicy(ctx *cli.Context) error {
req := &lnrpc.PolicyUpdateRequest{
BaseFeeMsat: baseFee,
FeeRate: feeRate,
TimeLockDelta: uint32(timeLockDelta),
MaxHtlcMsat: ctx.Uint64("max_htlc_msat"),
}
@@ -2120,6 +2133,12 @@ func updateChannelPolicy(ctx *cli.Context) error {
}
}
if feeRate != 0 {
req.FeeRate = feeRate
} else if feeRatePpm != 0 {
req.FeeRatePpm = uint32(feeRatePpm)
}
resp, err := client.UpdateChannelPolicy(ctxc, req)
if err != nil {
return err