Skip to content

Commit

Permalink
Feature: Add sequencer network config selection to sequencer comman…
Browse files Browse the repository at this point in the history
…ds (#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 <[email protected]>

* update getField comment

Co-authored-by: jesse snyder <[email protected]>

* address pr comments

---------

Co-authored-by: Jesse Snyder <[email protected]>
  • Loading branch information
sambukowski and steezeburger committed Aug 1, 2024
1 parent 04c7cba commit 58a9817
Show file tree
Hide file tree
Showing 17 changed files with 375 additions and 111 deletions.
36 changes: 34 additions & 2 deletions modules/cli/cmd/cliflaghandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion modules/cli/cmd/devrunner/config/networks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
2 changes: 1 addition & 1 deletion modules/cli/cmd/devrunner/utilities/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
19 changes: 19 additions & 0 deletions modules/cli/cmd/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"os"
"reflect"

log "github.com/sirupsen/logrus"
)
Expand All @@ -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
}
46 changes: 46 additions & 0 deletions modules/cli/cmd/helpers_test.go
Original file line number Diff line number Diff line change
@@ -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())
}
})

}
11 changes: 7 additions & 4 deletions modules/cli/cmd/sequencer/balances.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,21 @@ 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.")

viper.RegisterAlias("balance", "balances")
}

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) {
Expand Down
11 changes: 7 additions & 4 deletions modules/cli/cmd/sequencer/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
11 changes: 7 additions & 4 deletions modules/cli/cmd/sequencer/blockheight.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
44 changes: 22 additions & 22 deletions modules/cli/cmd/sequencer/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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()
Expand All @@ -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,
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -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.")
Expand All @@ -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.")
Expand Down
Loading

0 comments on commit 58a9817

Please sign in to comment.