From fe0e88746ec7f912dd81c661c7976f623fcc7f32 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Thu, 11 May 2023 08:45:00 +0700 Subject: [PATCH] Add gas config to the client.toml (#5020) * Create config.go fixing * config cmd * format * fix template * overwrite ReadFromClientConfig func: change ClientConfig => OsmosisCustomConfig * format * lint * go work sync * add gas configuration to client.toml * add fees var * format --------- Co-authored-by: Jacob Gadikian --- CHANGELOG.md | 1 + cmd/osmosisd/cmd/config.go | 234 +++++++++++++++++++++++++++++++++++++ cmd/osmosisd/cmd/root.go | 8 +- 3 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 cmd/osmosisd/cmd/config.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 81e86fd71ef..14d2c0377d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/cmd/osmosisd/cmd/config.go b/cmd/osmosisd/cmd/config.go new file mode 100644 index 00000000000..0be78e32ed6 --- /dev/null +++ b/cmd/osmosisd/cmd/config.go @@ -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 [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 }}" +# : 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) +} diff --git a/cmd/osmosisd/cmd/root.go b/cmd/osmosisd/cmd/root.go index dbfcd8b1dc5..a75eef05b8a 100644 --- a/cmd/osmosisd/cmd/root.go +++ b/cmd/osmosisd/cmd/root.go @@ -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" @@ -43,6 +42,7 @@ import ( "github.com/joho/godotenv" + "github.com/cosmos/cosmos-sdk/client/config" osmosis "github.com/osmosis-labs/osmosis/v15/app" ) @@ -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", @@ -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(), )