From aee609f26b8fcb0d96dfef8a09923465e71d0a50 Mon Sep 17 00:00:00 2001 From: Itay Date: Mon, 12 Jun 2023 12:21:07 +0200 Subject: [PATCH] feat: Add command to register rollapps (#50) --- cmd/config/init/DALightClient.go | 3 +- cmd/config/init/consts.go | 4 +- cmd/config/init/flags.go | 9 ++-- cmd/config/init/init.go | 22 +++++---- cmd/config/init/keys.go | 4 +- cmd/config/init/output.go | 9 ++-- cmd/config/init/persistence_config.go | 35 ++++++++++++++ cmd/config/init/relayer.go | 10 ++-- cmd/consts/consts.go | 13 +++++ cmd/register/register.go | 48 +++++++++++++++++++ cmd/root.go | 2 + .../error_handling.go} | 4 +- cmd/{config/init => utils}/utils.go | 4 +- test/config/init/init_test.go | 12 +++-- test/config/init/testutils/rollapp.go | 13 +++++ 15 files changed, 158 insertions(+), 34 deletions(-) create mode 100644 cmd/config/init/persistence_config.go create mode 100644 cmd/consts/consts.go create mode 100644 cmd/register/register.go rename cmd/{config/init/error_handler.go => utils/error_handling.go} (80%) rename cmd/{config/init => utils}/utils.go (63%) diff --git a/cmd/config/init/DALightClient.go b/cmd/config/init/DALightClient.go index b8bec5b4..470f89ac 100644 --- a/cmd/config/init/DALightClient.go +++ b/cmd/config/init/DALightClient.go @@ -3,10 +3,11 @@ package initconfig import ( "os/exec" "path/filepath" + "github.com/dymensionxyz/roller/cmd/consts" ) func initializeLightNodeConfig(initConfig InitConfig) error { - initLightNodeCmd := exec.Command(celestiaExecutablePath, "light", "init", "--p2p.network", "arabica", "--node.store", filepath.Join(initConfig.Home, ConfigDirName.DALightNode)) + initLightNodeCmd := exec.Command(consts.Executables.Celestia, "light", "init", "--p2p.network", "arabica", "--node.store", filepath.Join(initConfig.Home, ConfigDirName.DALightNode)) err := initLightNodeCmd.Run() if err != nil { return err diff --git a/cmd/config/init/consts.go b/cmd/config/init/consts.go index d6e17d06..4b8200c2 100644 --- a/cmd/config/init/consts.go +++ b/cmd/config/init/consts.go @@ -63,6 +63,4 @@ const defaultRollappRPC = "http://localhost:26657" const evmCoinType uint32 = 60 const KeysDirName = "keys" const cosmosDefaultCointype uint32 = 118 -const celestiaExecutablePath = "/usr/local/bin/roller_bins/celestia" -const defaultRollappBinaryPath = "/usr/local/bin/roller_bins/rollapp_evm" -const relayerExecutablePath = "/usr/local/bin/roller_bins/rly" +const RollerConfigFileName = "config.toml" diff --git a/cmd/config/init/flags.go b/cmd/config/init/flags.go index 6a5e1232..629be60d 100644 --- a/cmd/config/init/flags.go +++ b/cmd/config/init/flags.go @@ -1,7 +1,10 @@ package initconfig import ( + "github.com/dymensionxyz/roller/cmd/consts" "github.com/spf13/cobra" + + "github.com/dymensionxyz/roller/cmd/utils" ) func addFlags(cmd *cobra.Command) { @@ -9,7 +12,7 @@ func addFlags(cmd *cobra.Command) { cmd.Flags().StringP(FlagNames.DAEndpoint, "", "", "The data availability light node endpoint. Runs an Arabica Celestia light node if not provided") cmd.Flags().StringP(FlagNames.RollappBinary, "", "", "The rollapp binary. Should be passed only if you built a custom rollapp") cmd.Flags().Uint64P(FlagNames.Decimals, "", 18, "The number of decimal places a rollapp token supports") - cmd.Flags().StringP(FlagNames.Home, "", getRollerRootDir(), "The directory of the roller config files") + cmd.Flags().StringP(FlagNames.Home, "", utils.GetRollerRootDir(), "The directory of the roller config files") } func getDecimals(cmd *cobra.Command) uint64 { @@ -23,12 +26,12 @@ func getDecimals(cmd *cobra.Command) uint64 { func getRollappBinaryPath(cmd *cobra.Command) string { rollappBinaryPath := cmd.Flag(FlagNames.RollappBinary).Value.String() if rollappBinaryPath == "" { - return defaultRollappBinaryPath + return consts.Executables.RollappEVM } return rollappBinaryPath } -func getInitConfig(cmd *cobra.Command, args []string) InitConfig { +func GetInitConfig(cmd *cobra.Command, args []string) InitConfig { rollappId := args[0] denom := args[1] home := cmd.Flag(FlagNames.Home).Value.String() diff --git a/cmd/config/init/init.go b/cmd/config/init/init.go index de53652d..d8d181df 100644 --- a/cmd/config/init/init.go +++ b/cmd/config/init/init.go @@ -5,6 +5,7 @@ import ( "os" "github.com/spf13/cobra" + "github.com/dymensionxyz/roller/cmd/utils" ) type InitConfig struct { @@ -13,8 +14,8 @@ type InitConfig struct { RollappBinary string CreateDALightNode bool Denom string - HubID string Decimals uint64 + HubID string } func InitCmd() *cobra.Command { @@ -22,19 +23,19 @@ func InitCmd() *cobra.Command { Use: "init ", Short: "Initialize a RollApp configuration on your local machine.", Run: func(cmd *cobra.Command, args []string) { - initConfig := getInitConfig(cmd, args) + initConfig := GetInitConfig(cmd, args) isUniqueRollapp, err := isRollappIDUnique(initConfig.RollappID) - OutputCleanError(err) + utils.PrettifyErrorIfExists(err) if !isUniqueRollapp { - OutputCleanError(fmt.Errorf("Rollapp ID %s already exists on the hub. Please use a unique ID.", initConfig.RollappID)) + utils.PrettifyErrorIfExists(fmt.Errorf("Rollapp ID %s already exists on the hub. Please use a unique ID.", initConfig.RollappID)) } isRootExist, err := dirNotEmpty(initConfig.Home) - OutputCleanError(err) + utils.PrettifyErrorIfExists(err) if isRootExist { shouldOverwrite, err := promptOverwriteConfig(initConfig.Home) - OutputCleanError(err) + utils.PrettifyErrorIfExists(err) if shouldOverwrite { - OutputCleanError(os.RemoveAll(initConfig.Home)) + utils.PrettifyErrorIfExists(os.RemoveAll(initConfig.Home)) } else { os.Exit(0) } @@ -42,11 +43,11 @@ func InitCmd() *cobra.Command { addresses := initializeKeys(initConfig) if initConfig.CreateDALightNode { - OutputCleanError(initializeLightNodeConfig(initConfig)) + utils.PrettifyErrorIfExists(initializeLightNodeConfig(initConfig)) } initializeRollappConfig(initConfig) - OutputCleanError(initializeRollappGenesis(initConfig)) - OutputCleanError(initializeRelayerConfig(ChainConfig{ + utils.PrettifyErrorIfExists(initializeRollappGenesis(initConfig)) + utils.PrettifyErrorIfExists(initializeRelayerConfig(ChainConfig{ ID: initConfig.RollappID, RPC: defaultRollappRPC, Denom: initConfig.Denom, @@ -57,6 +58,7 @@ func InitCmd() *cobra.Command { Denom: "udym", AddressPrefix: addressPrefixes.Hub, }, initConfig)) + utils.PrettifyErrorIfExists(WriteConfigToTOML(initConfig)) printInitOutput(addresses, initConfig.RollappID) }, Args: cobra.ExactArgs(2), diff --git a/cmd/config/init/keys.go b/cmd/config/init/keys.go index 7dbcabd9..e287a301 100644 --- a/cmd/config/init/keys.go +++ b/cmd/config/init/keys.go @@ -81,7 +81,7 @@ func getDefaultKeysConfig(initConfig InitConfig) []KeyConfig { prefix: addressPrefixes.Rollapp, }, { - dir: path.Join(ConfigDirName.Relayer, KeysDirName, initConfig.HubID), + dir: path.Join(ConfigDirName.Relayer, KeysDirName, HubData.ID), keyId: KeyNames.HubRelayer, coinType: cosmosDefaultCointype, prefix: addressPrefixes.Hub, @@ -115,4 +115,4 @@ func initializeKeys(initConfig InitConfig) map[string]string { } return addresses } -} \ No newline at end of file +} diff --git a/cmd/config/init/output.go b/cmd/config/init/output.go index 9c46db05..933dd697 100644 --- a/cmd/config/init/output.go +++ b/cmd/config/init/output.go @@ -1,15 +1,16 @@ package initconfig import ( + "fmt" "os" - "github.com/fatih/color" "github.com/olekukonko/tablewriter" ) func printInitOutput(addresses map[string]string, rollappId string) { - color.New(color.FgCyan, color.Bold).Printf("šŸ’ˆ RollApp '%s' configuration files have been successfully generated on your local machine. Congratulations!\n\n", rollappId) - color.New(color.FgGreen, color.Bold).Printf("šŸ”‘ Key Details:\n\n") + fmt.Printf("šŸ’ˆ RollApp '%s' configuration files have been successfully generated on your local machine. Congratulations!\n\n", rollappId) + + fmt.Printf("šŸ”‘ Addresses:\n\n") data := [][]string{ {"Celestia", addresses[KeyNames.DALightNode]}, @@ -24,5 +25,5 @@ func printInitOutput(addresses map[string]string, rollappId string) { table.AppendBulk(data) table.Render() - color.New(color.FgYellow, color.Bold).Printf("\nšŸ”” Please fund these addresses to register and run the rollapp.\n") + fmt.Printf("\nšŸ”” Please fund these addresses to register and run the rollapp.\n") } diff --git a/cmd/config/init/persistence_config.go b/cmd/config/init/persistence_config.go new file mode 100644 index 00000000..63083039 --- /dev/null +++ b/cmd/config/init/persistence_config.go @@ -0,0 +1,35 @@ +package initconfig + +import ( + "io/ioutil" + "path/filepath" + + "github.com/pelletier/go-toml" +) + +func WriteConfigToTOML(InitConfig InitConfig) error { + tomlBytes, err := toml.Marshal(InitConfig) + if err != nil { + return err + } + err = ioutil.WriteFile(filepath.Join(InitConfig.Home, RollerConfigFileName), tomlBytes, 0644) + if err != nil { + return err + } + + return nil +} + +func LoadConfigFromTOML(root string) (InitConfig, error) { + var config InitConfig + tomlBytes, err := ioutil.ReadFile(filepath.Join(root, RollerConfigFileName)) + if err != nil { + return config, err + } + err = toml.Unmarshal(tomlBytes, &config) + if err != nil { + return config, err + } + + return config, nil +} diff --git a/cmd/config/init/relayer.go b/cmd/config/init/relayer.go index e4d7def7..a022047c 100644 --- a/cmd/config/init/relayer.go +++ b/cmd/config/init/relayer.go @@ -6,6 +6,8 @@ import ( "os" "os/exec" "path/filepath" + + "github.com/dymensionxyz/roller/cmd/consts" ) type RelayerFileChainConfig struct { @@ -78,7 +80,7 @@ func addChainToRelayer(fileChainConfig RelayerFileChainConfig, relayerHome strin if err != nil { return err } - addChainCmd := exec.Command(relayerExecutablePath, "chains", "add", fileChainConfig.Value.ChainID, "--home", relayerHome, "--file", chainFilePath) + addChainCmd := exec.Command(consts.Executables.Relayer, "chains", "add", fileChainConfig.Value.ChainID, "--home", relayerHome, "--file", chainFilePath) if err := addChainCmd.Run(); err != nil { return err } @@ -86,7 +88,7 @@ func addChainToRelayer(fileChainConfig RelayerFileChainConfig, relayerHome strin } func initRelayer(relayerHome string) error { - initRelayerConfigCmd := exec.Command(relayerExecutablePath, "config", "init", "--home", relayerHome) + initRelayerConfigCmd := exec.Command(consts.Executables.Relayer, "config", "init", "--home", relayerHome) return initRelayerConfigCmd.Run() } @@ -115,12 +117,12 @@ func addChainsConfig(rollappConfig ChainConfig, hubConfig ChainConfig, relayerHo } func setupPath(rollappConfig ChainConfig, hubConfig ChainConfig, relayerHome string) error { - setSettlementCmd := exec.Command(relayerExecutablePath, "chains", "set-settlement", hubConfig.ID, "--home", relayerHome) + setSettlementCmd := exec.Command(consts.Executables.Relayer, "chains", "set-settlement", hubConfig.ID, "--home", relayerHome) if err := setSettlementCmd.Run(); err != nil { return err } relayerPath := "hub-rollapp" - newPathCmd := exec.Command(relayerExecutablePath, "paths", "new", rollappConfig.ID, hubConfig.ID, relayerPath, "--src-port", "transfer", "--dst-port", "transfer", "--version", "ics20-1", "--home", relayerHome) + newPathCmd := exec.Command(consts.Executables.Relayer, "paths", "new", rollappConfig.ID, hubConfig.ID, relayerPath, "--src-port", "transfer", "--dst-port", "transfer", "--version", "ics20-1", "--home", relayerHome) if err := newPathCmd.Run(); err != nil { return err } diff --git a/cmd/consts/consts.go b/cmd/consts/consts.go new file mode 100644 index 00000000..47c59c89 --- /dev/null +++ b/cmd/consts/consts.go @@ -0,0 +1,13 @@ +package consts + +var Executables = struct { + Celestia string + RollappEVM string + Relayer string + Dymension string +}{ + Celestia: "/usr/local/bin/roller_bins/celestia", + RollappEVM: "/usr/local/bin/rollapp_evm", + Relayer: "/usr/local/bin/roller_bins/rly", + Dymension: "/usr/local/bin/roller_bins/dymd", +} diff --git a/cmd/register/register.go b/cmd/register/register.go new file mode 100644 index 00000000..118998cd --- /dev/null +++ b/cmd/register/register.go @@ -0,0 +1,48 @@ +package register + +import ( + "bytes" + "os/exec" + "path/filepath" + + initconfig "github.com/dymensionxyz/roller/cmd/config/init" + "github.com/dymensionxyz/roller/cmd/consts" + "github.com/dymensionxyz/roller/cmd/utils" + "github.com/spf13/cobra" +) + +func RegisterCmd() *cobra.Command { + registerCmd := &cobra.Command{ + Use: "register", + Short: "Registers the rollapp and the sequencer to the Dymension hub.", + Run: func(cmd *cobra.Command, args []string) { + home := cmd.Flag(initconfig.FlagNames.Home).Value.String() + rollappConfig, err := initconfig.LoadConfigFromTOML(home) + utils.PrettifyErrorIfExists(err) + utils.PrettifyErrorIfExists(registerRollapp(rollappConfig)) + }, + } + addFlags(registerCmd) + return registerCmd +} + +func addFlags(cmd *cobra.Command) { + cmd.Flags().StringP(initconfig.FlagNames.Home, "", utils.GetRollerRootDir(), "The directory of the roller config files") +} + +func registerRollapp(rollappConfig initconfig.InitConfig) error { + cmd := exec.Command( + consts.Executables.Dymension, "tx", "rollapp", "create-rollapp", + "--from", initconfig.KeyNames.HubSequencer, + "--keyring-backend", "test", + "--keyring-dir", filepath.Join(rollappConfig.Home, initconfig.ConfigDirName.Rollapp), + rollappConfig.RollappID, "stamp1", "genesis-path/1", "3", "3", `{"Addresses":[]}`, "--output", "json", + "--node", initconfig.HubData.RPC_URL, "--yes", "--broadcast-mode", "block", + ) + var stdout bytes.Buffer + var stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + error := cmd.Run() + return error +} diff --git a/cmd/root.go b/cmd/root.go index 8336a5a9..2827acb1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,6 +4,7 @@ import ( "os" "github.com/dymensionxyz/roller/cmd/config" + "github.com/dymensionxyz/roller/cmd/register" "github.com/dymensionxyz/roller/cmd/version" "github.com/spf13/cobra" ) @@ -26,4 +27,5 @@ func Execute() { func init() { rootCmd.AddCommand(config.ConfigCmd()) rootCmd.AddCommand(version.VersionCmd()) + rootCmd.AddCommand(register.RegisterCmd()) } diff --git a/cmd/config/init/error_handler.go b/cmd/utils/error_handling.go similarity index 80% rename from cmd/config/init/error_handler.go rename to cmd/utils/error_handling.go index 17327f70..9eaa8ac0 100644 --- a/cmd/config/init/error_handler.go +++ b/cmd/utils/error_handling.go @@ -1,4 +1,4 @@ -package initconfig +package utils import ( "os" @@ -6,7 +6,7 @@ import ( "github.com/fatih/color" ) -func OutputCleanError(err error) { +func PrettifyErrorIfExists(err error) { if err != nil { defer func() { if r := recover(); r != nil { diff --git a/cmd/config/init/utils.go b/cmd/utils/utils.go similarity index 63% rename from cmd/config/init/utils.go rename to cmd/utils/utils.go index 2867d36a..19e1b1ec 100644 --- a/cmd/config/init/utils.go +++ b/cmd/utils/utils.go @@ -1,10 +1,10 @@ -package initconfig +package utils import ( "os" "path/filepath" ) -func getRollerRootDir() string { +func GetRollerRootDir() string { return filepath.Join(os.Getenv("HOME"), ".roller") } diff --git a/test/config/init/init_test.go b/test/config/init/init_test.go index c2f80101..7c5ecf75 100644 --- a/test/config/init/init_test.go +++ b/test/config/init/init_test.go @@ -13,6 +13,8 @@ import ( ) func TestInitCmd(t *testing.T) { + DAEndpoint := "http://localhost:26659" + decimals := "6" testCases := []struct { name string goldenDirPath string @@ -27,8 +29,8 @@ func TestInitCmd(t *testing.T) { name: "Roller config init with custom flags", goldenDirPath: "./goldens/init_with_flags", optionalFlags: []string{ - "--" + initconfig.FlagNames.DAEndpoint, "http://localhost:26659", - "--" + initconfig.FlagNames.Decimals, "6", + "--" + initconfig.FlagNames.DAEndpoint, DAEndpoint, + "--" + initconfig.FlagNames.Decimals, decimals, }, }, } @@ -43,13 +45,17 @@ func TestInitCmd(t *testing.T) { assert.NoError(err) }() cmd := initconfig.InitCmd() + denom := "udym" rollappID := "mars" cmd.SetArgs(append([]string{ rollappID, - "udym", + denom, "--" + initconfig.FlagNames.Home, tempDir, }, tc.optionalFlags...)) assert.NoError(cmd.Execute()) + initConfig := initconfig.GetInitConfig(cmd, []string{rollappID, denom}) + assert.NoError(testutils.VerifyRollerConfig(initConfig)) + assert.NoError(os.Remove(filepath.Join(tempDir, initconfig.RollerConfigFileName))) assert.NoError(testutils.VerifyRollappKeys(tempDir)) assert.NoError(testutils.VerifyRelayerKeys(tempDir, rollappID, initconfig.HubData.ID)) if !testutils.Contains(tc.optionalFlags, "--"+initconfig.FlagNames.DAEndpoint) { diff --git a/test/config/init/testutils/rollapp.go b/test/config/init/testutils/rollapp.go index 44f0efc1..6820caa0 100644 --- a/test/config/init/testutils/rollapp.go +++ b/test/config/init/testutils/rollapp.go @@ -3,6 +3,8 @@ package testutils import ( "path/filepath" + "errors" + initconfig "github.com/dymensionxyz/roller/cmd/config/init" ) @@ -67,3 +69,14 @@ func SanitizeGenesis(genesisPath string) error { } return nil } + +func VerifyRollerConfig(rollappConfig initconfig.InitConfig) error { + existingConfig, err := initconfig.LoadConfigFromTOML(rollappConfig.Home) + if err != nil { + return err + } + if rollappConfig == existingConfig { + return nil + } + return errors.New("roller config does not match") +}