Skip to content

Commit

Permalink
Merge pull request #142 from renproject/feat/cosmos-estimate-gas
Browse files Browse the repository at this point in the history
Fix the gas price for cosmos compat chains
  • Loading branch information
tok-kkk authored Mar 30, 2022
2 parents d475196 + 1ff8685 commit 5161f01
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 10 deletions.
35 changes: 26 additions & 9 deletions chain/cosmos/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,27 @@ const (
DefaultChainID = pack.String("testnet")
// DefaultSignMode used in signing the tx
DefaultSignMode = 1
// DefaultDecimalsDivisor is used when estimating gas prices for some Cosmos
// chains, so that the result is an integer.
// For example, the recommended Terra gas price is currently 0.01133 uluna.
// To ensure we're only dealing with integers, the value can be represented
// as 1133. When the transaction builder is calculating fees, it will divide
// the total by the divisor (in this case 1e5), to calculate the actual
// value.
DefaultDecimalsDivisor = 1
)

// TxBuilderOptions only contains necessary options to build tx from tx builder
type TxBuilderOptions struct {
ChainID pack.String
ChainID pack.String
DecimalsDivisor pack.U256
}

// DefaultTxBuilderOptions returns TxBuilderOptions with the default settings.
func DefaultTxBuilderOptions() TxBuilderOptions {
return TxBuilderOptions{
ChainID: DefaultChainID,
ChainID: DefaultChainID,
DecimalsDivisor: pack.NewU256FromU64(DefaultDecimalsDivisor),
}
}

Expand All @@ -50,20 +60,27 @@ func (opts TxBuilderOptions) WithChainID(chainID pack.String) TxBuilderOptions {
return opts
}

func (opts TxBuilderOptions) WithDecimalsDivisor(decimalDivisor pack.U256) TxBuilderOptions {
opts.DecimalsDivisor = decimalDivisor
return opts
}

type txBuilder struct {
client *Client
chainID pack.String
signMode int32
client *Client
chainID pack.String
signMode int32
decimalsDivisor pack.U256
}

// NewTxBuilder returns an implementation of the transaction builder interface
// from the Cosmos Compat API, and exposes the functionality to build simple
// Cosmos based transactions.
func NewTxBuilder(options TxBuilderOptions, client *Client) account.TxBuilder {
return txBuilder{
signMode: DefaultSignMode,
client: client,
chainID: options.ChainID,
signMode: DefaultSignMode,
client: client,
chainID: options.ChainID,
decimalsDivisor: options.DecimalsDivisor,
}
}

Expand Down Expand Up @@ -107,7 +124,7 @@ func (builder txBuilder) BuildTx(ctx context.Context, fromPubKey *id.PubKey, to

fees := Coins{Coin{
Denom: builder.client.opts.CoinDenom,
Amount: pack.NewU64(gasPrice.Mul(gasLimit).Int().Uint64()),
Amount: pack.NewU64(gasPrice.Mul(gasLimit).Div(builder.decimalsDivisor).Int().Uint64()),
}}

accountNumber, err := builder.client.AccountNumber(ctx, from)
Expand Down
2 changes: 1 addition & 1 deletion chain/ethereum/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var (
)

type feeHistoryResult struct {
Reward [][]string `json:"reward"`
Reward [][]string `json:"reward"`
}

// GasOptions allow a user to configure the parameters used while heuristically recommending
Expand Down
46 changes: 46 additions & 0 deletions chain/terra/terra.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package terra

import (
"context"
"encoding/json"
"fmt"
"net/http"
"strconv"

"github.com/cosmos/cosmos-sdk/types"
"github.com/renproject/multichain/api/account"
"github.com/renproject/multichain/chain/cosmos"
"github.com/renproject/pack"
"github.com/terra-money/core/app"
)

const DefaultTerraDecimalsDivisor = 1e5

type (
// Client re-exports cosmos.Client
Client = cosmos.Client
Expand Down Expand Up @@ -54,3 +63,40 @@ func NewClient(opts ClientOptions) *Client {
func NewTxBuilder(opts TxBuilderOptions, client *Client) account.TxBuilder {
return cosmos.NewTxBuilder(opts, client)
}

type GasEstimator struct {
url string
decimals int
fallbackGas pack.U256
}

func NewHttpGasEstimator(url string, decimals int, fallbackGas pack.U256) GasEstimator {
return GasEstimator{
url: url,
decimals: decimals,
fallbackGas: fallbackGas,
}
}

func (gasEstimator GasEstimator) EstimateGas(ctx context.Context) (pack.U256, pack.U256, error) {
response, err := http.Get(gasEstimator.url)
if err != nil {
return gasEstimator.fallbackGas, gasEstimator.fallbackGas, err
}
defer response.Body.Close()

var results map[string]string
if err := json.NewDecoder(response.Body).Decode(&results); err != nil {
return gasEstimator.fallbackGas, gasEstimator.fallbackGas, err
}
gasPriceStr, ok := results["uluna"]
if !ok {
return gasEstimator.fallbackGas, gasEstimator.fallbackGas, fmt.Errorf("no uluna in response")
}
gasPriceFloat, err := strconv.ParseFloat(gasPriceStr, 64)
if err != nil {
return gasEstimator.fallbackGas, gasEstimator.fallbackGas, fmt.Errorf("invalid gas price, %v", err)
}
gasPrice := uint64(gasPriceFloat * float64(gasEstimator.decimals))
return pack.NewU256FromUint64(gasPrice), pack.NewU256FromUint64(gasPrice), nil
}

0 comments on commit 5161f01

Please sign in to comment.