Summary of Bug
The floatingGasPriceEstimator incorrectly uses a Double conversion on the gas estimate amount. This causes decimal precision when the price returned from the floatingGasPrice() function is small (i.e. 1nhash).
When val newBaseFee = listOf((estimate.limit * price).toCoin(denom)) is calculated on a small price with a small-ish estimate.limit the estimate.limit * price is represented internally as a Double. When converted to a coin string via a toString the decimal is retained in the coin string like 100.0nhash. This causes a failure in CoinExtensions.discreteSum:
java.lang.NumberFormatException: For input string: "100.0"
...
io.provenance.client.common.extensions.CoinExtensionsKt.discreteSum(CoinExtensions.kt:37)
However, when a large price is used (like 1905) the code works because the result of estimate.limit * price is internally represented with scientific notation (e.g. 1.6764E8). Then when converted to a string no decimal is present. This is why this code has worked in the past: the fee overflows into scientific notation internally and no decimal returned from a toString.
Version
2.5.1
Steps to Reproduce
Use a the floatingGasPrices function and set a small gas price:
val pbClient = io.provenance.client.grpc.PbClient(
chainId = "testing", //"pio-testnet-1", //"pio-mainnet-1",
channelUri = URI("gprc://localhost:9090"), //URI("grpc://10.10.32.21:9090"), //URI("grpc://10.10.32.16:9090"),
gasEstimationMethod = floatingGasPrices(
delegate = MSG_FEE_CALCULATION,
gasPrices = constGasPrice(
Coin.newBuilder().setAmount("1").setDenom("nhash").build() //will fail because of gas-price <> 1nhash
)
),
opts = ChannelOpts(),
)
Expected error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "87669.0"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:668)
at java.base/java.math.BigInteger.<init>(BigInteger.java:538)
at java.base/java.math.BigInteger.<init>(BigInteger.java:676)
at io.provenance.client.common.extensions.CoinExtensionsKt.discreteSum(CoinExtensions.kt:37)
at io.provenance.client.grpc.BaseReq.buildAuthInfo(BaseReq.kt:63)
at io.provenance.client.grpc.AbstractPbClient.broadcastTx(AbstractPbClient.kt:139)
at io.provenance.client.grpc.AbstractPbClient.broadcastTx$default(AbstractPbClient.kt:132)
Fix
Do not convert the amount to Double and use Long or BigInteger calculations instead.
For Admin Use
Summary of Bug
The floatingGasPriceEstimator incorrectly uses a
Doubleconversion on the gas estimateamount. This causes decimal precision when thepricereturned from thefloatingGasPrice()function is small (i.e.1nhash).When val newBaseFee = listOf((estimate.limit * price).toCoin(denom)) is calculated on a small
pricewith a small-ishestimate.limittheestimate.limit * priceis represented internally as a Double. When converted to a coin string via atoStringthe decimal is retained in the coin string like100.0nhash. This causes a failure inCoinExtensions.discreteSum:However, when a large
priceis used (like1905) the code works because the result ofestimate.limit * priceis internally represented with scientific notation (e.g.1.6764E8). Then when converted to a string no decimal is present. This is why this code has worked in the past: thefeeoverflows into scientific notation internally and no decimal returned from atoString.Version
2.5.1
Steps to Reproduce
Use a the
floatingGasPricesfunction and set a small gas price:Expected error:
Fix
Do not convert the amount to Double and use Long or BigInteger calculations instead.
For Admin Use