Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gas config to the client.toml #5020

Merged
merged 13 commits into from
May 11, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Misc Improvements

* [#5020](https://github.com/osmosis-labs/osmosis/pull/5020) Add gas config to the client.toml
* [#5105](https://github.com/osmosis-labs/osmosis/pull/5105) Lint stableswap in the same manner as all of Osmosis
* [#5065](https://github.com/osmosis-labs/osmosis/pull/5065) Use cosmossdk.io/errors
* [#4549](https://github.com/osmosis-labs/osmosis/pull/4549) Add single pool price estimate queries
Expand Down
234 changes: 234 additions & 0 deletions cmd/osmosisd/cmd/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
package cmd

import (
"bytes"
"encoding/json"
"fmt"
"os"
"path/filepath"
"text/template"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
viper "github.com/spf13/viper"
tmcli "github.com/tendermint/tendermint/libs/cli"
)

type OsmosisCustomClient struct {
ChainID string `mapstructure:"chain-id" json:"chain-id"`
KeyringBackend string `mapstructure:"keyring-backend" json:"keyring-backend"`
Output string `mapstructure:"output" json:"output"`
Node string `mapstructure:"node" json:"node"`
BroadcastMode string `mapstructure:"broadcast-mode" json:"broadcast-mode"`
Gas string `mapstructure:"gas" json:"gas"`
GasPrices string `mapstructure:"gas-prices" json:"gas-prices"`
GasAdjustment string `mapstructure:"gas-adjustment" json:"gas-adjustment"`
Fees string `mapstructure:"fees" json:"fees"`
}

// Override sdk ConfigCmd func
func ConfigCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "config <key> [value]",
Short: "Create or query an application CLI configuration file",
RunE: runConfigCmd,
Args: cobra.RangeArgs(0, 2),
}
return cmd
}

func runConfigCmd(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
configPath := filepath.Join(clientCtx.HomeDir, "config")

conf, err := getClientConfig(configPath, clientCtx.Viper)
if err != nil {
return fmt.Errorf("couldn't get client config: %v", err)
}

switch len(args) {
case 0:
s, err := json.MarshalIndent(conf, "", "\t")
if err != nil {
return err
}

cmd.Println(string(s))

case 1:
// it's a get
key := args[0]

switch key {
case flags.FlagChainID:
cmd.Println(conf.ChainID)
case flags.FlagKeyringBackend:
cmd.Println(conf.KeyringBackend)
case tmcli.OutputFlag:
cmd.Println(conf.Output)
case flags.FlagNode:
cmd.Println(conf.Node)
case flags.FlagBroadcastMode:
cmd.Println(conf.BroadcastMode)
case flags.FlagGas:
cmd.Println(conf.Gas)
case flags.FlagGasPrices:
cmd.Println(conf.GasPrices)
case flags.FlagGasAdjustment:
cmd.Println(conf.GasAdjustment)
case flags.FlagFees:
cmd.Println(conf.Fees)
default:
err := errUnknownConfigKey(key)
return fmt.Errorf("couldn't get the value for the key: %v, error: %v", key, err)
}

case 2:
// it's set
key, value := args[0], args[1]

switch key {
case flags.FlagChainID:
conf.ChainID = value
case flags.FlagKeyringBackend:
conf.KeyringBackend = value
case tmcli.OutputFlag:
conf.Output = value
case flags.FlagNode:
conf.Node = value
case flags.FlagBroadcastMode:
conf.BroadcastMode = value
case flags.FlagGas:
conf.Gas = value
case flags.FlagGasPrices:
conf.GasPrices = value
case flags.FlagGasAdjustment:
conf.GasAdjustment = value
case flags.FlagFees:
conf.Fees = value
default:
return errUnknownConfigKey(key)
}

confFile := filepath.Join(configPath, "client.toml")
if err := writeConfigToFile(confFile, conf); err != nil {
return fmt.Errorf("could not write client config to the file: %v", err)
}

default:
panic("cound not execute config command")
}

return nil
}

const defaultConfigTemplate = `# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml

###############################################################################
### Client Configuration ###
###############################################################################

# The network chain ID
chain-id = "{{ .ChainID }}"
# The keyring's backend, where the keys are stored (os|file|kwallet|pass|test|memory)
keyring-backend = "{{ .KeyringBackend }}"
# CLI output format (text|json)
output = "{{ .Output }}"
# <host>:<port> to Tendermint RPC interface for this chain
node = "{{ .Node }}"
# Transaction broadcasting mode (sync|async)
broadcast-mode = "{{ .BroadcastMode }}"


###############################################################################
### Osmosis Tx Configuration ###
###############################################################################
# Amount of gas per transaction
gas = "{{ .Gas }}"
# Price per unit of gas (ex: 0.005uosmo)
gas-prices = "{{ .GasPrices }}"
gas-adjustment = "{{ .GasAdjustment }}"
fees = "{{ .Fees }}"
`

// writeConfigToFile parses defaultConfigTemplate, renders config using the template and writes it to
// configFilePath.
func writeConfigToFile(configFilePath string, config *OsmosisCustomClient) error {
var buffer bytes.Buffer

tmpl := template.New("clientConfigFileTemplate")
configTemplate, err := tmpl.Parse(defaultConfigTemplate)
if err != nil {
return err
}

if err := configTemplate.Execute(&buffer, config); err != nil {
return err
}

return os.WriteFile(configFilePath, buffer.Bytes(), 0o600)
}

// getClientConfig reads values from client.toml file and unmarshalls them into ClientConfig
func getClientConfig(configPath string, v *viper.Viper) (*OsmosisCustomClient, error) {
v.AddConfigPath(configPath)
v.SetConfigName("client")
v.SetConfigType("toml")

if err := v.ReadInConfig(); err != nil {
return nil, err
}

conf := new(OsmosisCustomClient)
if err := v.Unmarshal(conf); err != nil {
return nil, err
}

return conf, nil
}

// Reads the custom extra values in the config.toml file if set.
// If they are, then use them.
func SetCustomEnvVariablesFromClientToml(ctx client.Context) {
configFilePath := filepath.Join(ctx.HomeDir, "config", "client.toml")

if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
return
}

viper := ctx.Viper
viper.SetConfigFile(configFilePath)

if err := viper.ReadInConfig(); err != nil {
panic(err)
}

setEnvFromConfig := func(key string, envVar string) {
// if the user sets the env key manually, then we don't want to override it
if os.Getenv(envVar) != "" {
return
}

// reads from the config file
val := viper.GetString(key)
if val != "" {
// Sets the env for this instance of the app only.
os.Setenv(envVar, val)
}
}

// Bound custom flags to environment variable
// gas
setEnvFromConfig("gas", "OSMOSISD_GAS")
setEnvFromConfig("gas-prices", "OSMOSISD_GAS_PRICES")
setEnvFromConfig("gas-adjustment", "OSMOSISD_GAS_ADJUSTMENT")
// fees
setEnvFromConfig("fees", "OSMOSISD_FEES")
}

func errUnknownConfigKey(key string) error {
return fmt.Errorf("unknown configuration key: %q", key)
}
8 changes: 6 additions & 2 deletions cmd/osmosisd/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/client/debug"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/keys"
Expand All @@ -43,6 +42,7 @@ import (

"github.com/joho/godotenv"

"github.com/cosmos/cosmos-sdk/client/config"
osmosis "github.com/osmosis-labs/osmosis/v15/app"
)

Expand All @@ -68,6 +68,10 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
WithHomeDir(homeDir).
WithViper("OSMOSIS")

// Allows you to add extra params to your client.toml
// gas, gas-price, gas-adjustment
SetCustomEnvVariablesFromClientToml(initClientCtx)

rootCmd := &cobra.Command{
Use: "osmosisd",
Short: "Start osmosis app",
Expand Down Expand Up @@ -182,7 +186,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
testnetCmd(osmosis.ModuleBasics, banktypes.GenesisBalancesIterator{}),
tmcmds.RollbackStateCmd,
debugCmd,
config.Cmd(),
ConfigCmd(),
ChangeEnvironmentCmd(),
PrintEnvironmentCmd(),
)
Expand Down