Skip to content

Invalid Fee Coin Calculation When Using Small Gas Price #67

Description

@jdfigure

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

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions