From 58a981738e6f60f6bc4e498b90b760dbc47cfab3 Mon Sep 17 00:00:00 2001 From: Sam Bukowski Date: Thu, 1 Aug 2024 14:45:59 -0600 Subject: [PATCH] Feature: Add sequencer network config selection to `sequencer` commands (#139) * add sequencer networks config and network flag to sequencer transfer command * update transfer command handler to use ChooseFlagValue func * move get network value * typo fix * add network config to remaining sequencer commands * add network flag to sequencer commands * make config structs more generic so we can easily add new networks * fix some doc comments * remove info log statement to fix tests * attempt to simplify flag handling with network config * update doc comment * add override flag option to flag handler * add CreateCliFlagHandlerWithOverrideFlag * put all logic in GetValue * update commands to use new GetValue * remove unneeded functions * update getField name Co-authored-by: jesse snyder * update getField comment Co-authored-by: jesse snyder * address pr comments --------- Co-authored-by: Jesse Snyder --- modules/cli/cmd/cliflaghandler.go | 36 ++++- modules/cli/cmd/devrunner/config/networks.go | 2 +- .../cli/cmd/devrunner/utilities/utilities.go | 2 +- modules/cli/cmd/helpers.go | 19 +++ modules/cli/cmd/helpers_test.go | 46 ++++++ modules/cli/cmd/sequencer/balances.go | 11 +- modules/cli/cmd/sequencer/block.go | 11 +- modules/cli/cmd/sequencer/blockheight.go | 11 +- modules/cli/cmd/sequencer/bridge.go | 44 +++--- modules/cli/cmd/sequencer/config.go | 143 ++++++++++++++++++ modules/cli/cmd/sequencer/constants.go | 13 +- modules/cli/cmd/sequencer/nonce.go | 12 +- modules/cli/cmd/sequencer/sudo/feeAsset.go | 38 ++--- modules/cli/cmd/sequencer/sudo/ibcRelayer.go | 38 ++--- .../cmd/sequencer/sudo/sudoAddressChange.go | 19 +-- .../cli/cmd/sequencer/sudo/validatorUpdate.go | 19 +-- modules/cli/cmd/sequencer/transfer.go | 22 +-- 17 files changed, 375 insertions(+), 111 deletions(-) create mode 100644 modules/cli/cmd/helpers_test.go create mode 100644 modules/cli/cmd/sequencer/config.go diff --git a/modules/cli/cmd/cliflaghandler.go b/modules/cli/cmd/cliflaghandler.go index a17d8355..8fd14cb1 100644 --- a/modules/cli/cmd/cliflaghandler.go +++ b/modules/cli/cmd/cliflaghandler.go @@ -13,8 +13,10 @@ import ( // CliFlagHandler is a struct that handles the binding of flags and the retrieval of the flag's string value type CliFlagHandler struct { - Cmd *cobra.Command - EnvPrefix string + Cmd *cobra.Command + EnvPrefix string + useConfigFlag string + config any } // CreateCliFlagHandler creates a new CliFlagHandler. @@ -25,6 +27,23 @@ func CreateCliFlagHandler(c *cobra.Command, envPrefix string) *CliFlagHandler { } } +// CreateCliFlagHandlerWithUseConfigFlag creates a new CliFlagHandler with a +// specified config override flag. When the config flag is set, that will +// trigger the flag handler to use the config preset values instead of the flag +// defaults. +func CreateCliFlagHandlerWithUseConfigFlag(c *cobra.Command, envPrefix string, configOverrideFlag string) *CliFlagHandler { + return &CliFlagHandler{ + Cmd: c, + EnvPrefix: envPrefix, + useConfigFlag: configOverrideFlag, + } +} + +// SetConfig sets the config for the CliFlagHandler. +func (f *CliFlagHandler) SetConfig(config any) { + f.config = config +} + // BindStringFlag binds a string flag to a cobra flag and viper env var handler for a // local command flag, and automatically creates the env var from the flag name. func (f *CliFlagHandler) BindStringFlag(name string, defaultValue string, usage string) { @@ -120,6 +139,19 @@ func (f *CliFlagHandler) GetValue(flagName string) string { panic(fmt.Sprintf("getValue: unsupported flag type: %s", valueKind)) } + if f.useConfigFlag != "" && f.Cmd.Flag(f.useConfigFlag).Changed { + // check if value exists in config and return it + if f.config != nil { + configValue, found := GetFieldValueByTag(f.config, "flag", flagName) + if found { + value := configValue.String() + log.Debugf("%s flag is set via config file: %s", flagName, value) + return value + } + log.Debugf("Config value for %s not found or invalid. Skipping.", flagName) + } + } + if f.Cmd.Flag(flagName).Changed { log.Debugf("%s flag is set with value: %s", flagName, value) return value diff --git a/modules/cli/cmd/devrunner/config/networks.go b/modules/cli/cmd/devrunner/config/networks.go index af3577da..68144dee 100644 --- a/modules/cli/cmd/devrunner/config/networks.go +++ b/modules/cli/cmd/devrunner/config/networks.go @@ -158,7 +158,7 @@ type NetworkConfig struct { NativeDenom string `mapstructure:"default_denom" toml:"default_denom"` } -// DefaultNetworksConfig returns a NetworksConfig struct populated with all +// DefaultNetworksConfigs returns a NetworksConfig struct populated with all // network defaults. func DefaultNetworksConfigs() NetworkConfigs { config := NetworkConfigs{ diff --git a/modules/cli/cmd/devrunner/utilities/utilities.go b/modules/cli/cmd/devrunner/utilities/utilities.go index c3c8dba4..0661f4ad 100644 --- a/modules/cli/cmd/devrunner/utilities/utilities.go +++ b/modules/cli/cmd/devrunner/utilities/utilities.go @@ -7,7 +7,7 @@ import ( log "github.com/sirupsen/logrus" ) -// copyFile copies the contents of the src file to dst. +// CopyFile copies the contents of the src file to dst. // If dst does not exist, it will be created, and if it does, it will be overwritten. func CopyFile(src, dst string) error { sourceFile, err := os.Open(src) diff --git a/modules/cli/cmd/helpers.go b/modules/cli/cmd/helpers.go index 402a4c28..c324b81c 100644 --- a/modules/cli/cmd/helpers.go +++ b/modules/cli/cmd/helpers.go @@ -2,6 +2,7 @@ package cmd import ( "os" + "reflect" log "github.com/sirupsen/logrus" ) @@ -15,3 +16,21 @@ func CreateDirOrPanic(dirName string) { panic(err) } } + +// GetFieldValueByTag gets a field's value from a struct by the specified tagName. +func GetFieldValueByTag(obj interface{}, tagName, tagValue string) (reflect.Value, bool) { + val := reflect.ValueOf(obj) + if val.Kind() == reflect.Ptr { + val = val.Elem() + } + + typ := val.Type() + for i := 0; i < val.NumField(); i++ { + field := typ.Field(i) + tag := field.Tag.Get(tagName) + if tag == tagValue { + return val.Field(i), true + } + } + return reflect.Value{}, false +} diff --git a/modules/cli/cmd/helpers_test.go b/modules/cli/cmd/helpers_test.go new file mode 100644 index 00000000..f9424773 --- /dev/null +++ b/modules/cli/cmd/helpers_test.go @@ -0,0 +1,46 @@ +package cmd + +import ( + "testing" +) + +func TestGetFieldValueByTag(t *testing.T) { + type testStruct struct { + Field1 string `flag:"field-1"` + Field2 int `tag2:"field-2"` + Field3 bool `b:"field-3"` + } + + s := testStruct{ + Field1: "value1", + Field2: 1, + Field3: true, + } + + t.Run("Get field by tag", func(t *testing.T) { + val1, ok := GetFieldValueByTag(s, "flag", "field-1") + if !ok { + t.Errorf("Expected to find field by tag") + } + if val1.String() != "value1" { + t.Errorf("Expected field value to be %s, got %s", s.Field1, val1.String()) + } + + val2, ok := GetFieldValueByTag(s, "tag2", "field-2") + if !ok { + t.Errorf("Expected to find field by tag") + } + if val2.Int() != 1 { + t.Errorf("Expected field value to be %d, got %s", s.Field2, val2.String()) + } + + val3, ok := GetFieldValueByTag(s, "b", "field-3") + if !ok { + t.Errorf("Expected to find field by tag") + } + if val3.Bool() != true { + t.Errorf("Expected field value to be %t, got %s", s.Field3, val3.String()) + } + }) + +} diff --git a/modules/cli/cmd/sequencer/balances.go b/modules/cli/cmd/sequencer/balances.go index ef19014a..17c0f5a1 100644 --- a/modules/cli/cmd/sequencer/balances.go +++ b/modules/cli/cmd/sequencer/balances.go @@ -24,6 +24,7 @@ func init() { SequencerCmd.AddCommand(balancesCmd) flagHandler := cmd.CreateCliFlagHandler(balancesCmd, cmd.EnvPrefix) + flagHandler.BindStringFlag("network", DefaultTargetNetwork, "Configure the values to target a specific network.") flagHandler.BindStringPFlag("sequencer-url", "u", DefaultSequencerURL, "The URL of the sequencer to retrieve the balance from.") flagHandler.BindBoolFlag("json", false, "Output an account's balances in JSON format.") @@ -31,11 +32,13 @@ func init() { } func balancesCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - url := flagHandler.GetValue("sequencer-url") - sequencerURL := AddPortToURL(url) + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = AddPortToURL(sequencerURL) address := args[0] if !strings.HasPrefix(address, DefaultAddressPrefix) { diff --git a/modules/cli/cmd/sequencer/block.go b/modules/cli/cmd/sequencer/block.go index d717f52f..8884ea2c 100644 --- a/modules/cli/cmd/sequencer/block.go +++ b/modules/cli/cmd/sequencer/block.go @@ -22,16 +22,19 @@ func init() { SequencerCmd.AddCommand(blockCmd) flagHandler := cmd.CreateCliFlagHandler(blockCmd, cmd.EnvPrefix) + flagHandler.BindStringFlag("network", DefaultTargetNetwork, "Configure the values to target a specific network.") flagHandler.BindStringPFlag("sequencer-url", "u", DefaultSequencerURL, "The URL of the sequencer to retrieve the block from.") flagHandler.BindBoolFlag("json", false, "Output the block in JSON format.") } func blockCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - url := flagHandler.GetValue("sequencer-url") - sequencerURL := AddPortToURL(url) + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = AddPortToURL(sequencerURL) height, err := strconv.ParseInt(args[0], 10, 64) if err != nil { diff --git a/modules/cli/cmd/sequencer/blockheight.go b/modules/cli/cmd/sequencer/blockheight.go index fba2f0ae..c4a46bc8 100644 --- a/modules/cli/cmd/sequencer/blockheight.go +++ b/modules/cli/cmd/sequencer/blockheight.go @@ -19,16 +19,19 @@ func init() { SequencerCmd.AddCommand(blockheightCmd) flagHandler := cmd.CreateCliFlagHandler(blockheightCmd, cmd.EnvPrefix) + flagHandler.BindStringFlag("network", DefaultTargetNetwork, "Configure the values to target a specific network.") flagHandler.BindStringPFlag("sequencer-url", "u", DefaultSequencerURL, "The URL of the sequencer to retrieve the balance from.") flagHandler.BindBoolFlag("json", false, "Output an account's balances in JSON format.") } func blockheightCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - url := flagHandler.GetValue("sequencer-url") - sequencerURL := AddPortToURL(url) + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = AddPortToURL(sequencerURL) blockheight, err := sequencer.GetBlockheight(sequencerURL) if err != nil { diff --git a/modules/cli/cmd/sequencer/bridge.go b/modules/cli/cmd/sequencer/bridge.go index ceaef6c5..5978808d 100644 --- a/modules/cli/cmd/sequencer/bridge.go +++ b/modules/cli/cmd/sequencer/bridge.go @@ -28,11 +28,17 @@ and is the only actor authorized to transfer out of this account.`, } func bridgeInitCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - url := flagHandler.GetValue("sequencer-url") - sequencerURL := AddPortToURL(url) + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = AddPortToURL(sequencerURL) + sequencerChainID := flagHandler.GetValue("sequencer-chain-id") + asset := flagHandler.GetValue("asset") + feeAsset := flagHandler.GetValue("fee-asset") + isAsync := flagHandler.GetValue("async") == "true" priv, err := GetPrivateKeyFromFlags(c) if err != nil { @@ -51,11 +57,6 @@ func bridgeInitCmdHandler(c *cobra.Command, args []string) { rollupName := args[0] - sequencerChainID := flagHandler.GetValue("sequencer-chain-id") - - asset := flagHandler.GetValue("asset") - feeAsset := flagHandler.GetValue("fee-asset") - sa := flagHandler.GetValue("sudo-address") if sa == "" { sa = fromAccount.Address.String() @@ -76,8 +77,6 @@ func bridgeInitCmdHandler(c *cobra.Command, args []string) { } withdrawerAddress := AddressFromText(wa) - isAsync := flagHandler.GetValue("async") == "true" - opts := sequencer.InitBridgeOpts{ IsAsync: isAsync, AddressPrefix: DefaultAddressPrefix, @@ -115,11 +114,17 @@ bridged to a destination chain address if an IBC relayer is running.`, } func bridgeLockCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - url := flagHandler.GetValue("sequencer-url") - sequencerURL := AddPortToURL(url) + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = AddPortToURL(sequencerURL) + sequencerChainID := flagHandler.GetValue("sequencer-chain-id") + asset := flagHandler.GetValue("asset") + feeAsset := flagHandler.GetValue("fee-asset") + isAsync := flagHandler.GetValue("async") == "true" priv, err := GetPrivateKeyFromFlags(c) if err != nil { @@ -141,15 +146,8 @@ func bridgeLockCmdHandler(c *cobra.Command, args []string) { to := args[1] toAddress := AddressFromText(to) - sequencerChainID := flagHandler.GetValue("sequencer-chain-id") - - asset := flagHandler.GetValue("asset") - feeAsset := flagHandler.GetValue("fee-asset") - destinationChainAddress := args[2] - isAsync := flagHandler.GetValue("async") == "true" - opts := sequencer.BridgeLockOpts{ IsAsync: isAsync, AddressPrefix: DefaultAddressPrefix, @@ -180,6 +178,7 @@ func init() { bridgeCmd.AddCommand(bridgeInitCmd) bifh := cmd.CreateCliFlagHandler(bridgeInitCmd, cmd.EnvPrefix) + bifh.BindStringFlag("network", DefaultTargetNetwork, "Configure the values to target a specific network.") bifh.BindStringPFlag("sequencer-chain-id", "c", DefaultSequencerChainID, "The chain ID of the sequencer.") bifh.BindStringFlag("asset", DefaultAsset, "The name of the asset we want to bridge.") bifh.BindStringFlag("fee-asset", DefaultFeeAsset, "The name of the asset used for fees.") @@ -199,6 +198,7 @@ func init() { bridgeCmd.AddCommand(bridgeLockCmd) blfh := cmd.CreateCliFlagHandler(bridgeLockCmd, cmd.EnvPrefix) + blfh.BindStringFlag("network", DefaultTargetNetwork, "Configure the values to target a specific network.") blfh.BindStringFlag("sequencer-chain-id", DefaultSequencerChainID, "The chain ID of the sequencer.") blfh.BindStringFlag("asset", DefaultAsset, "The asset to be locked and transferred.") blfh.BindStringFlag("fee-asset", DefaultFeeAsset, "The asset used to pay the transaction fee.") diff --git a/modules/cli/cmd/sequencer/config.go b/modules/cli/cmd/sequencer/config.go new file mode 100644 index 00000000..99172e11 --- /dev/null +++ b/modules/cli/cmd/sequencer/config.go @@ -0,0 +1,143 @@ +package sequencer + +import ( + "os" + "path/filepath" + + "github.com/astriaorg/astria-cli-go/modules/cli/cmd" + log "github.com/sirupsen/logrus" + + "github.com/pelletier/go-toml/v2" + "github.com/spf13/viper" +) + +// SequencerNetworkConfig is the struct that holds the configuration for +// interacting with a given Astria sequencer network. +type SequencerNetworkConfig struct { + SequencerChainId string `flag:"sequencer-chain-id" mapstructure:"sequencer_chain_id" toml:"sequencer_chain_id"` + SequencerURL string `flag:"sequencer-url" mapstructure:"sequencer_url" toml:"sequencer_url"` + Asset string `flag:"asset" mapstructure:"asset" toml:"asset"` + FeeAsset string `flag:"fee-asset" mapstructure:"fee_asset" toml:"fee_asset"` +} + +// SequencerNetworkConfigs is a map of SequencerNetworkConfig structs. +// Using a map here to allow for user to add new networks by adding a new section in the toml +type SequencerNetworkConfigs struct { + Configs map[string]SequencerNetworkConfig `mapstructure:"networks" toml:"networks"` +} + +// GetSequencerNetworkConfigsPresets returns a map of all sequencer network presets. +// Used to generate the initial config file. +func GetSequencerNetworkConfigsPresets() SequencerNetworkConfigs { + return SequencerNetworkConfigs{ + Configs: map[string]SequencerNetworkConfig{ + "local": { + SequencerChainId: "sequencer-test-chain-0", + SequencerURL: "http://127.0.0.1:26657", + Asset: "nria", + FeeAsset: "nria", + }, + "dusk": { + SequencerChainId: DefaultSequencerChainID, + SequencerURL: DefaultSequencerURL, + Asset: "nria", + FeeAsset: "nria", + }, + "dawn": { + SequencerChainId: "astria-dawn-0", + SequencerURL: "https://rpc.sequencer.dawn-0.devnet.astria.org", + Asset: "ibc/channel0/utia", + FeeAsset: "ibc/channel0/utia", + }, + "mainnet": { + SequencerChainId: "astria", + SequencerURL: "https://rpc.sequencer.astria.org/", + Asset: "ibc/channel0/utia", + FeeAsset: "ibc/channel0/utia", + }, + }, + } +} + +// LoadSequencerNetworkConfigsOrPanic loads the SequencerNetworkConfigs from the given +// path. If the file cannot be loaded or parsed, the function will panic. +func LoadSequencerNetworkConfigsOrPanic(path string) SequencerNetworkConfigs { + viper.SetConfigFile(path) + + if err := viper.ReadInConfig(); err != nil { + log.Fatalf("Error reading config file, %s", err) + panic(err) + } + + var config SequencerNetworkConfigs + if err := viper.Unmarshal(&config); err != nil { + log.Fatalf("Unable to decode toml into struct, %v", err) + panic(err) + } + + return config +} + +// BuildSequencerNetworkConfigsFilepath returns the path to the sequencer +// networks configuration file. The file is located in the user's home directory +// in the default Astria config directory (~/.astria/). +func BuildSequencerNetworkConfigsFilepath() string { + homePath, err := os.UserHomeDir() + if err != nil { + log.WithError(err).Error("Error getting home dir") + panic(err) + } + return filepath.Join(homePath, DefaultConfigDirName, DefaultSequencerNetworksConfigFilename) +} + +// CreateSequencerNetworkConfigs creates a sequencer networks configuration file at the +// given path. It will skip initialization if the file already exists. It will +// panic if the file cannot be created or if there is an error encoding the +// NetworksConfigs struct to a file. +func CreateSequencerNetworkConfigs(path string) { + _, err := os.Stat(path) + if err == nil { + log.Debugf("%s already exists. Skipping initialization.\n", path) + return + } + + config := GetSequencerNetworkConfigsPresets() + + file, err := os.Create(path) + if err != nil { + panic(err) + } + defer file.Close() + + // encode the struct to TOML and write to the file + if err := toml.NewEncoder(file).Encode(config); err != nil { + panic(err) + } + log.Infof("New network config file created successfully: %s\n", path) +} + +// GetSequencerNetworkSettingsFromConfig returns the SequencerNetworkConfig for +// the given network. The function automatically checks if the sequencer network +// config file exists, creates it if it does not, and then loads the config. +func GetSequencerNetworkSettingsFromConfig(network, path string) SequencerNetworkConfig { + sequencerConfig := LoadSequencerNetworkConfigsOrPanic(path) + + if _, ok := sequencerConfig.Configs[network]; !ok { + log.Fatalf("Network %s not found in config file at %s", network, path) + panic("Network not found in config file") + } + + return sequencerConfig.Configs[network] +} + +// GetNetworkConfigFromFlags returns a SequencerNetworkConfig based on the +// network flag value. It will create the network config file if it does not +// exist, and then load the config. +func GetNetworkConfigFromFlags(flagHandler *cmd.CliFlagHandler) SequencerNetworkConfig { + network := flagHandler.GetValue("network") + networksConfigPath := BuildSequencerNetworkConfigsFilepath() + CreateSequencerNetworkConfigs(networksConfigPath) + networkSettings := GetSequencerNetworkSettingsFromConfig(network, networksConfigPath) + + return networkSettings +} diff --git a/modules/cli/cmd/sequencer/constants.go b/modules/cli/cmd/sequencer/constants.go index 77e72d15..3834c5e4 100644 --- a/modules/cli/cmd/sequencer/constants.go +++ b/modules/cli/cmd/sequencer/constants.go @@ -1,9 +1,12 @@ package sequencer const ( - DefaultAddressPrefix = "astria" - DefaultSequencerURL = "https://rpc.sequencer.dusk-8.devnet.astria.org" - DefaultSequencerChainID = "astria-dusk-8" - DefaultAsset = "nria" - DefaultFeeAsset = "nria" + DefaultConfigDirName = ".astria" + DefaultAddressPrefix = "astria" + DefaultSequencerURL = "https://rpc.sequencer.dusk-8.devnet.astria.org" + DefaultSequencerChainID = "astria-dusk-8" + DefaultAsset = "nria" + DefaultFeeAsset = "nria" + DefaultSequencerNetworksConfigFilename = "sequencer-networks-config.toml" + DefaultTargetNetwork = "dusk" ) diff --git a/modules/cli/cmd/sequencer/nonce.go b/modules/cli/cmd/sequencer/nonce.go index 75824259..d2bff22f 100644 --- a/modules/cli/cmd/sequencer/nonce.go +++ b/modules/cli/cmd/sequencer/nonce.go @@ -25,15 +25,19 @@ func init() { flagHandler := cmd.CreateCliFlagHandler(nonceCmd, cmd.EnvPrefix) flagHandler.BindStringPFlag("sequencer-url", "u", DefaultSequencerURL, "The URL of the sequencer.") + flagHandler.BindStringFlag("network", DefaultTargetNetwork, "Configure the values to target a specific network.") flagHandler.BindBoolFlag("json", false, "Output in JSON format.") } func nonceCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) + + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = AddPortToURL(sequencerURL) - url := flagHandler.GetValue("sequencer-url") - sequencerURL := AddPortToURL(url) + printJSON := flagHandler.GetValue("json") == "true" address := args[0] if !strings.HasPrefix(address, DefaultAddressPrefix) { diff --git a/modules/cli/cmd/sequencer/sudo/feeAsset.go b/modules/cli/cmd/sequencer/sudo/feeAsset.go index 84420d0e..bd5e6249 100644 --- a/modules/cli/cmd/sequencer/sudo/feeAsset.go +++ b/modules/cli/cmd/sequencer/sudo/feeAsset.go @@ -25,13 +25,15 @@ var addFeeAssetCmd = &cobra.Command{ } func addFeeAssetCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" - - url := flagHandler.GetValue("sequencer-url") - sequencerURL := sequencercmd.AddPortToURL(url) + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := sequencercmd.GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - chainId := flagHandler.GetValue("sequencer-chain-id") + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = sequencercmd.AddPortToURL(sequencerURL) + sequencerChainID := flagHandler.GetValue("sequencer-chain-id") + isAsync := flagHandler.GetValue("async") == "true" asset := args[0] @@ -46,14 +48,12 @@ func addFeeAssetCmdHandler(c *cobra.Command, args []string) { panic(err) } - isAsync := flagHandler.GetValue("async") == "true" - opts := sequencer.FeeAssetOpts{ IsAsync: isAsync, AddressPrefix: sequencercmd.DefaultAddressPrefix, FromKey: from, SequencerURL: sequencerURL, - SequencerChainID: chainId, + SequencerChainID: sequencerChainID, Asset: asset, } tx, err := sequencer.AddFeeAsset(opts) @@ -78,13 +78,15 @@ var removeFeeAssetCmd = &cobra.Command{ } func removeFeeAssetCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" - - url := flagHandler.GetValue("sequencer-url") - sequencerURL := sequencercmd.AddPortToURL(url) + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := sequencercmd.GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - chainId := flagHandler.GetValue("sequencer-chain-id") + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = sequencercmd.AddPortToURL(sequencerURL) + sequencerChainID := flagHandler.GetValue("sequencer-chain-id") + isAsync := flagHandler.GetValue("async") == "true" asset := args[0] @@ -99,14 +101,12 @@ func removeFeeAssetCmdHandler(c *cobra.Command, args []string) { panic(err) } - isAsync := flagHandler.GetValue("async") == "true" - opts := sequencer.FeeAssetOpts{ IsAsync: isAsync, AddressPrefix: sequencercmd.DefaultAddressPrefix, FromKey: from, SequencerURL: sequencerURL, - SequencerChainID: chainId, + SequencerChainID: sequencerChainID, Asset: asset, } tx, err := sequencer.RemoveFeeAsset(opts) @@ -127,6 +127,7 @@ func init() { feeAssetCmd.AddCommand(addFeeAssetCmd) afafh := cmd.CreateCliFlagHandler(addFeeAssetCmd, cmd.EnvPrefix) + afafh.BindStringFlag("network", sequencercmd.DefaultTargetNetwork, "Configure the values to target a specific network.") afafh.BindStringPFlag("sequencer-url", "u", sequencercmd.DefaultSequencerURL, "The URL of the sequencer to add fee asset to.") afafh.BindBoolFlag("json", false, "Output the command result in JSON format.") afafh.BindBoolFlag("async", false, "If true, the function will return immediately. If false, the function will wait for the transaction to be seen on the network.") @@ -140,6 +141,7 @@ func init() { feeAssetCmd.AddCommand(removeFeeAssetCmd) rfafh := cmd.CreateCliFlagHandler(removeFeeAssetCmd, cmd.EnvPrefix) + rfafh.BindStringFlag("network", sequencercmd.DefaultTargetNetwork, "Configure the values to target a specific network.") rfafh.BindStringPFlag("sequencer-url", "u", sequencercmd.DefaultSequencerURL, "The URL of the sequencer to remove fee asset from.") rfafh.BindBoolFlag("json", false, "Output the command result in JSON format.") rfafh.BindBoolFlag("async", false, "If true, the function will return immediately. If false, the function will wait for the transaction to be seen on the network.") diff --git a/modules/cli/cmd/sequencer/sudo/ibcRelayer.go b/modules/cli/cmd/sequencer/sudo/ibcRelayer.go index e324b47c..a633f8d4 100644 --- a/modules/cli/cmd/sequencer/sudo/ibcRelayer.go +++ b/modules/cli/cmd/sequencer/sudo/ibcRelayer.go @@ -25,13 +25,15 @@ var addIBCRelayerCmd = &cobra.Command{ } func addIBCRelayerCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" - - url := flagHandler.GetValue("sequencer-url") - sequencerURL := sequencercmd.AddPortToURL(url) + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := sequencercmd.GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - chainId := flagHandler.GetValue("sequencer-chain-id") + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = sequencercmd.AddPortToURL(sequencerURL) + sequencerChainID := flagHandler.GetValue("sequencer-chain-id") + isAsync := flagHandler.GetValue("async") == "true" ibcAdd := args[0] addIbcAddress := sequencercmd.AddressFromText(ibcAdd) @@ -47,14 +49,12 @@ func addIBCRelayerCmdHandler(c *cobra.Command, args []string) { panic(err) } - isAsync := flagHandler.GetValue("async") == "true" - opts := sequencer.IBCRelayerOpts{ IsAsync: isAsync, AddressPrefix: sequencercmd.DefaultAddressPrefix, FromKey: from, SequencerURL: sequencerURL, - SequencerChainID: chainId, + SequencerChainID: sequencerChainID, IBCRelayerAddress: addIbcAddress, } tx, err := sequencer.AddIBCRelayer(opts) @@ -79,13 +79,15 @@ var removeIBCRelayerCmd = &cobra.Command{ } func removeIBCRelayerCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" - - url := flagHandler.GetValue("sequencer-url") - sequencerURL := sequencercmd.AddPortToURL(url) + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := sequencercmd.GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - chainId := flagHandler.GetValue("sequencer-chain-id") + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = sequencercmd.AddPortToURL(sequencerURL) + sequencerChainID := flagHandler.GetValue("sequencer-chain-id") + isAsync := flagHandler.GetValue("async") == "true" ibcRmv := args[0] rmvIbcAddress := sequencercmd.AddressFromText(ibcRmv) @@ -101,14 +103,12 @@ func removeIBCRelayerCmdHandler(c *cobra.Command, args []string) { panic(err) } - isAsync := flagHandler.GetValue("async") == "true" - opts := sequencer.IBCRelayerOpts{ IsAsync: isAsync, AddressPrefix: sequencercmd.DefaultAddressPrefix, FromKey: from, SequencerURL: sequencerURL, - SequencerChainID: chainId, + SequencerChainID: sequencerChainID, IBCRelayerAddress: rmvIbcAddress, } tx, err := sequencer.RemoveIBCRelayer(opts) @@ -129,6 +129,7 @@ func init() { IBCRelayerCmd.AddCommand(addIBCRelayerCmd) aibfh := cmd.CreateCliFlagHandler(addIBCRelayerCmd, cmd.EnvPrefix) + aibfh.BindStringFlag("network", sequencercmd.DefaultTargetNetwork, "Configure the values to target a specific network.") aibfh.BindStringPFlag("sequencer-url", "u", sequencercmd.DefaultSequencerURL, "The URL of the sequencer to add the relayer address to.") aibfh.BindBoolFlag("json", false, "Output the command result in JSON format.") aibfh.BindBoolFlag("async", false, "If true, the function will return immediately. If false, the function will wait for the transaction to be seen on the network.") @@ -142,6 +143,7 @@ func init() { IBCRelayerCmd.AddCommand(removeIBCRelayerCmd) ribfh := cmd.CreateCliFlagHandler(removeIBCRelayerCmd, cmd.EnvPrefix) + ribfh.BindStringFlag("network", sequencercmd.DefaultTargetNetwork, "Configure the values to target a specific network.") ribfh.BindStringPFlag("sequencer-url", "u", sequencercmd.DefaultSequencerURL, "The URL of the sequencer to remove the relayer address from.") ribfh.BindBoolFlag("json", false, "Output the command result in JSON format.") ribfh.BindBoolFlag("async", false, "If true, the function will return immediately. If false, the function will wait for the transaction to be seen on the network.") diff --git a/modules/cli/cmd/sequencer/sudo/sudoAddressChange.go b/modules/cli/cmd/sequencer/sudo/sudoAddressChange.go index 885ba190..64125d4c 100644 --- a/modules/cli/cmd/sequencer/sudo/sudoAddressChange.go +++ b/modules/cli/cmd/sequencer/sudo/sudoAddressChange.go @@ -19,13 +19,15 @@ var sudoAddressChangeCmd = &cobra.Command{ } func sudoAddressChangeCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" - - url := flagHandler.GetValue("sequencer-url") - sequencerURL := sequencercmd.AddPortToURL(url) + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := sequencercmd.GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - chainId := flagHandler.GetValue("sequencer-chain-id") + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = sequencercmd.AddPortToURL(sequencerURL) + sequencerChainID := flagHandler.GetValue("sequencer-chain-id") + isAsync := flagHandler.GetValue("async") == "true" to := args[0] toAddress := sequencercmd.AddressFromText(to) @@ -41,15 +43,13 @@ func sudoAddressChangeCmdHandler(c *cobra.Command, args []string) { panic(err) } - isAsync := flagHandler.GetValue("async") == "true" - opts := sequencer.ChangeSudoAddressOpts{ IsAsync: isAsync, AddressPrefix: sequencercmd.DefaultAddressPrefix, FromKey: from, UpdateAddress: toAddress, SequencerURL: sequencerURL, - SequencerChainID: chainId, + SequencerChainID: sequencerChainID, } tx, err := sequencer.ChangeSudoAddress(opts) if err != nil { @@ -68,6 +68,7 @@ func init() { sudoCmd.AddCommand(sudoAddressChangeCmd) flaghandler := cmd.CreateCliFlagHandler(sudoAddressChangeCmd, cmd.EnvPrefix) + flaghandler.BindStringFlag("network", sequencercmd.DefaultTargetNetwork, "Configure the values to target a specific network.") flaghandler.BindBoolFlag("json", false, "Output the command result in JSON format.") flaghandler.BindBoolFlag("async", false, "If true, the function will return immediately. If false, the function will wait for the transaction to be seen on the network.") flaghandler.BindStringPFlag("sequencer-url", "u", sequencercmd.DefaultSequencerURL, "The URL of the sequencer to update the sudo address on.") diff --git a/modules/cli/cmd/sequencer/sudo/validatorUpdate.go b/modules/cli/cmd/sequencer/sudo/validatorUpdate.go index 1d8acb64..a84e5d2e 100644 --- a/modules/cli/cmd/sequencer/sudo/validatorUpdate.go +++ b/modules/cli/cmd/sequencer/sudo/validatorUpdate.go @@ -21,13 +21,15 @@ var validatorUpdateCmd = &cobra.Command{ } func validatorUpdateCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" - - url := flagHandler.GetValue("sequencer-url") - sequencerURL := sequencercmd.AddPortToURL(url) + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := sequencercmd.GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - chainId := flagHandler.GetValue("sequencer-chain-id") + printJSON := flagHandler.GetValue("json") == "true" + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = sequencercmd.AddPortToURL(sequencerURL) + sequencerChainID := flagHandler.GetValue("sequencer-chain-id") + isAsync := flagHandler.GetValue("async") == "true" pk := args[0] pubKey, err := sequencercmd.PublicKeyFromText(pk) @@ -54,8 +56,6 @@ func validatorUpdateCmdHandler(c *cobra.Command, args []string) { panic(err) } - isAsync := flagHandler.GetValue("async") == "true" - opts := sequencer.UpdateValidatorOpts{ IsAsync: isAsync, AddressPrefix: sequencercmd.DefaultAddressPrefix, @@ -63,7 +63,7 @@ func validatorUpdateCmdHandler(c *cobra.Command, args []string) { PubKey: pubKey, Power: power, SequencerURL: sequencerURL, - SequencerChainID: chainId, + SequencerChainID: sequencerChainID, } tx, err := sequencer.UpdateValidator(opts) if err != nil { @@ -82,6 +82,7 @@ func init() { sudoCmd.AddCommand(validatorUpdateCmd) flaghandler := cmd.CreateCliFlagHandler(validatorUpdateCmd, cmd.EnvPrefix) + flaghandler.BindStringFlag("network", sequencercmd.DefaultTargetNetwork, "Configure the values to target a specific network.") flaghandler.BindBoolFlag("json", false, "Output the command result in JSON format.") flaghandler.BindBoolFlag("async", false, "If true, the function will return immediately. If false, the function will wait for the transaction to be seen on the network.") flaghandler.BindStringPFlag("sequencer-url", "u", sequencercmd.DefaultSequencerURL, "The URL of the sequencer to update the validator on.") diff --git a/modules/cli/cmd/sequencer/transfer.go b/modules/cli/cmd/sequencer/transfer.go index 5ad33d61..d5cdf575 100644 --- a/modules/cli/cmd/sequencer/transfer.go +++ b/modules/cli/cmd/sequencer/transfer.go @@ -27,6 +27,7 @@ func init() { flagHandler.BindStringFlag("privkey", "", "The private key of the sender.") flagHandler.BindStringFlag("asset", DefaultAsset, "The asset to be transferred.") flagHandler.BindStringFlag("fee-asset", DefaultFeeAsset, "The asset used for paying fees.") + flagHandler.BindStringFlag("network", DefaultTargetNetwork, "Configure the values to target a specific network.") flagHandler.BindBoolFlag("async", false, "If true, the function will return immediately. If false, the function will wait for the transaction to be seen on the network.") transferCmd.MarkFlagsOneRequired("keyfile", "keyring-address", "privkey") @@ -34,11 +35,17 @@ func init() { } func transferCmdHandler(c *cobra.Command, args []string) { - flagHandler := cmd.CreateCliFlagHandler(c, cmd.EnvPrefix) - printJSON := flagHandler.GetValue("json") == "true" + flagHandler := cmd.CreateCliFlagHandlerWithUseConfigFlag(c, cmd.EnvPrefix, "network") + networkConfig := GetNetworkConfigFromFlags(flagHandler) + flagHandler.SetConfig(networkConfig) - url := flagHandler.GetValue("sequencer-url") - sequencerURL := AddPortToURL(url) + sequencerURL := flagHandler.GetValue("sequencer-url") + sequencerURL = AddPortToURL(sequencerURL) + asset := flagHandler.GetValue("asset") + feeAsset := flagHandler.GetValue("fee-asset") + sequencerChainID := flagHandler.GetValue("sequencer-chain-id") + + printJSON := flagHandler.GetValue("json") == "true" priv, err := GetPrivateKeyFromFlags(c) if err != nil { @@ -60,11 +67,6 @@ func transferCmdHandler(c *cobra.Command, args []string) { panic(err) } - asset := flagHandler.GetValue("asset") - feeAsset := flagHandler.GetValue("fee-asset") - - chainId := flagHandler.GetValue("sequencer-chain-id") - isAsync := flagHandler.GetValue("async") == "true" opts := sequencer.TransferOpts{ @@ -76,7 +78,7 @@ func transferCmdHandler(c *cobra.Command, args []string) { Amount: amount, Asset: asset, FeeAsset: feeAsset, - SequencerChainID: chainId, + SequencerChainID: sequencerChainID, } tx, err := sequencer.Transfer(opts) if err != nil {