From 96755584d993bcacdf49e40b59cf00a7ad83f74b Mon Sep 17 00:00:00 2001 From: Itay Date: Sun, 18 Jun 2023 12:23:18 +0200 Subject: [PATCH 1/7] feat: Add ability to run rollapps with the `roller run` command (#66) --- cmd/config/init/consts.go | 2 - cmd/config/init/flags.go | 26 +++---- cmd/config/init/init.go | 20 +++-- cmd/config/init/keys.go | 22 ------ cmd/consts/consts.go | 4 +- cmd/register/register.go | 8 +- cmd/root.go | 2 + cmd/run/run.go | 62 +++++++++++++++ install.sh | 12 ++- .../da-light-node}/config.toml | 0 .../da-light-node/config.toml | 77 +++++++++++++++++++ test/config/init/init_test.go | 6 +- 12 files changed, 175 insertions(+), 66 deletions(-) create mode 100644 cmd/run/run.go rename test/config/init/goldens/{init_without_flags/light-node => init_with_flags/da-light-node}/config.toml (100%) create mode 100644 test/config/init/goldens/init_without_flags/da-light-node/config.toml diff --git a/cmd/config/init/consts.go b/cmd/config/init/consts.go index ea95005f..d59f9e82 100644 --- a/cmd/config/init/consts.go +++ b/cmd/config/init/consts.go @@ -2,13 +2,11 @@ package initconfig var FlagNames = struct { Home string - DAEndpoint string Decimals string RollappBinary string HubID string }{ Home: "home", - DAEndpoint: "data-availability-endpoint", Decimals: "decimals", RollappBinary: "rollapp-binary", HubID: "hub", diff --git a/cmd/config/init/flags.go b/cmd/config/init/flags.go index 41f1a5b5..ae614656 100644 --- a/cmd/config/init/flags.go +++ b/cmd/config/init/flags.go @@ -4,12 +4,12 @@ import ( "fmt" "github.com/dymensionxyz/roller/cmd/consts" + "github.com/dymensionxyz/roller/cmd/utils" "github.com/spf13/cobra" ) func addFlags(cmd *cobra.Command) { cmd.Flags().StringP(FlagNames.HubID, "", TestnetHubID, fmt.Sprintf("The ID of the Dymension hub. %s", getAvailableHubsMessage())) - 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") @@ -41,22 +41,20 @@ func getRollappBinaryPath(cmd *cobra.Command) string { return rollappBinaryPath } -func GetInitConfig(cmd *cobra.Command, args []string) InitConfig { +func GetInitConfig(initCmd *cobra.Command, args []string) InitConfig { rollappId := args[0] denom := args[1] - home := cmd.Flag(FlagNames.Home).Value.String() - createLightNode := !cmd.Flags().Changed(FlagNames.DAEndpoint) - rollappBinaryPath := getRollappBinaryPath(cmd) - decimals := getDecimals(cmd) - hubID := cmd.Flag(FlagNames.HubID).Value.String() + home := initCmd.Flag(utils.FlagNames.Home).Value.String() + rollappBinaryPath := getRollappBinaryPath(initCmd) + decimals := getDecimals(initCmd) + hubID := initCmd.Flag(FlagNames.HubID).Value.String() return InitConfig{ - Home: home, - RollappID: rollappId, - RollappBinary: rollappBinaryPath, - CreateDALightNode: createLightNode, - Denom: denom, - Decimals: decimals, - HubData: Hubs[hubID], + Home: home, + RollappID: rollappId, + RollappBinary: rollappBinaryPath, + Denom: denom, + Decimals: decimals, + HubData: Hubs[hubID], } } diff --git a/cmd/config/init/init.go b/cmd/config/init/init.go index 093baa3b..2dbdd2c6 100644 --- a/cmd/config/init/init.go +++ b/cmd/config/init/init.go @@ -9,13 +9,12 @@ import ( ) type InitConfig struct { - Home string - RollappID string - RollappBinary string - CreateDALightNode bool - Denom string - Decimals uint64 - HubData HubData + Home string + RollappID string + RollappBinary string + Denom string + Decimals uint64 + HubData HubData } func InitCmd() *cobra.Command { @@ -37,10 +36,9 @@ func InitCmd() *cobra.Command { } } - addresses := initializeKeys(initConfig) - if initConfig.CreateDALightNode { - utils.PrettifyErrorIfExists(initializeLightNodeConfig(initConfig)) - } + addresses, err := generateKeys(initConfig) + utils.PrettifyErrorIfExists(err) + utils.PrettifyErrorIfExists(initializeLightNodeConfig(initConfig)) initializeRollappConfig(initConfig) utils.PrettifyErrorIfExists(initializeRollappGenesis(initConfig)) utils.PrettifyErrorIfExists(initializeRelayerConfig(ChainConfig{ diff --git a/cmd/config/init/keys.go b/cmd/config/init/keys.go index 13d5a909..a6e657c5 100644 --- a/cmd/config/init/keys.go +++ b/cmd/config/init/keys.go @@ -76,28 +76,6 @@ func getDefaultKeysConfig(initConfig InitConfig) []utils.KeyConfig { ID: consts.KeyNames.RollappRelayer, CoinType: consts.CoinTypes.EVM, Prefix: consts.AddressPrefixes.Rollapp, - }, { - - Dir: path.Join(consts.ConfigDirName.DALightNode, KeysDirName), - ID: consts.KeyNames.DALightNode, - CoinType: consts.CoinTypes.Cosmos, - Prefix: consts.AddressPrefixes.DA, }, } } - -func initializeKeys(initConfig InitConfig) map[string]string { - if initConfig.CreateDALightNode { - addresses, err := generateKeys(initConfig) - if err != nil { - panic(err) - } - return addresses - } else { - addresses, err := generateKeys(initConfig, consts.KeyNames.DALightNode) - if err != nil { - panic(err) - } - return addresses - } -} diff --git a/cmd/consts/consts.go b/cmd/consts/consts.go index 44f244fc..1fb08633 100644 --- a/cmd/consts/consts.go +++ b/cmd/consts/consts.go @@ -22,7 +22,7 @@ var KeyNames = struct { HubSequencer: "hub_sequencer", RollappSequencer: "rollapp_sequencer", RollappRelayer: "relayer-rollapp-key", - DALightNode: "my-celes-key", + DALightNode: "my_celes_key", HubRelayer: "relayer-hub-key", } @@ -43,7 +43,7 @@ var ConfigDirName = struct { }{ Rollapp: "rollapp", Relayer: "relayer", - DALightNode: "light-node", + DALightNode: "da-light-node", } var CoinTypes = struct { diff --git a/cmd/register/register.go b/cmd/register/register.go index 05556514..9f654988 100644 --- a/cmd/register/register.go +++ b/cmd/register/register.go @@ -3,7 +3,6 @@ package register import ( "bytes" "errors" - "github.com/dymensionxyz/roller/cmd/consts" "path/filepath" "fmt" @@ -14,6 +13,7 @@ import ( initconfig "github.com/dymensionxyz/roller/cmd/config/init" "github.com/dymensionxyz/roller/cmd/utils" + "github.com/dymensionxyz/roller/cmd/consts" "github.com/spf13/cobra" ) @@ -34,14 +34,10 @@ func RegisterCmd() *cobra.Command { printRegisterOutput(rollappConfig) }, } - addFlags(registerCmd) + utils.AddGlobalFlags(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 := getRegisterRollappCmd(rollappConfig) var stdout bytes.Buffer diff --git a/cmd/root.go b/cmd/root.go index 2827acb1..d156a707 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -5,6 +5,7 @@ import ( "github.com/dymensionxyz/roller/cmd/config" "github.com/dymensionxyz/roller/cmd/register" + "github.com/dymensionxyz/roller/cmd/run" "github.com/dymensionxyz/roller/cmd/version" "github.com/spf13/cobra" ) @@ -28,4 +29,5 @@ func init() { rootCmd.AddCommand(config.ConfigCmd()) rootCmd.AddCommand(version.VersionCmd()) rootCmd.AddCommand(register.RegisterCmd()) + rootCmd.AddCommand(run.RunCmd()) } diff --git a/cmd/run/run.go b/cmd/run/run.go new file mode 100644 index 00000000..ef44cf63 --- /dev/null +++ b/cmd/run/run.go @@ -0,0 +1,62 @@ +package run + +import ( + "fmt" + "github.com/dymensionxyz/roller/cmd/consts" + "os/exec" + "path/filepath" + + initconfig "github.com/dymensionxyz/roller/cmd/config/init" + "github.com/dymensionxyz/roller/cmd/utils" + "github.com/spf13/cobra" +) + +const daLightClientEndpointFlag = "da-light-client-endpoint" + +func RunCmd() *cobra.Command { + runCmd := &cobra.Command{ + Use: "run", + Short: "Runs the rollapp sequencer.", + Run: func(cmd *cobra.Command, args []string) { + home := cmd.Flag(utils.FlagNames.Home).Value.String() + rollappConfig, err := initconfig.LoadConfigFromTOML(home) + utils.PrettifyErrorIfExists(err) + startRollappCmd := getStartRollapCmd(rollappConfig, cmd.Flag(daLightClientEndpointFlag).Value.String()) + startRollappErr := startRollappCmd.Run() + utils.PrettifyErrorIfExists(startRollappErr) + }, + } + addFlags(runCmd) + utils.AddGlobalFlags(runCmd) + return runCmd +} + +func addFlags(cmd *cobra.Command) { + cmd.Flags().StringP(daLightClientEndpointFlag, "", "http://localhost:26659", "The DA light client endpoint.") +} + +func getStartRollapCmd(rollappConfig initconfig.InitConfig, daLightClientEndpoint string) *exec.Cmd { + daConfig := fmt.Sprintf(`{"base_url": "%s", "timeout": 60000000000, "fee":20000, "gas_limit": 20000000, "namespace_id":[0,0,0,0,0,0,255,255]}`, daLightClientEndpoint) + rollappConfigDir := filepath.Join(rollappConfig.Home, consts.ConfigDirName.Rollapp) + settlementConfig := fmt.Sprintf(`{"node_address": "%s", "rollapp_id": "%s", "dym_account_name": "%s", "keyring_home_dir": "%s", "keyring_backend":"test", "gas_fees": "2000000udym"}`, + rollappConfig.HubData.RPC_URL, rollappConfig.RollappID, consts.KeyNames.HubSequencer, rollappConfigDir) + + return exec.Command( + rollappConfig.RollappBinary, "start", + "--dymint.aggregator", + "--json-rpc.enable", + "--json-rpc.api", "eth,txpool,personal,net,debug,web3,miner", + "--dymint.da_layer", "celestia", + "--dymint.da_config", daConfig, + "--dymint.settlement_layer", "dymension", + "--dymint.settlement_config", settlementConfig, + "--dymint.block_batch_size", "1200", + "--dymint.namespace_id", "000000000000ffff", + "--dymint.block_time", "0.2s", + "--home", rollappConfigDir, + "--log_level", "debug", + "--log-file", filepath.Join(rollappConfigDir, "rollapp.log"), + "--max-log-size", "2000", + "--module-log-level-override", "", + ) +} diff --git a/install.sh b/install.sh index 4639b2fe..122b0a2c 100755 --- a/install.sh +++ b/install.sh @@ -10,10 +10,12 @@ TGZ_URL="https://github.com/dymensionxyz/roller/releases/download/v0.0.0/roller_ # Create internal dir INTERNAL_DIR="/usr/local/bin/roller_bins" ROLLER_BIN_PATH="/usr/local/bin/roller" +ROLLAPP_EVM_PATH="/usr/local/bin/rollapp_evm" # The path where rollapp_evm will be installed -# Check if Roller binary already exists -if [ -f "$ROLLER_BIN_PATH" ] || [ -d "$INTERNAL_DIR" ]; then +# Check if Roller and rollapp_evm binaries already exist or the internal directory exists +if [ -f "$ROLLER_BIN_PATH" ] || [ -f "$ROLLAPP_EVM_PATH" ] || [ -d "$INTERNAL_DIR" ]; then sudo rm -f "$ROLLER_BIN_PATH" + sudo rm -f "$ROLLAPP_EVM_PATH" sudo rm -rf "$INTERNAL_DIR" fi @@ -25,14 +27,16 @@ sudo mkdir -p "/tmp/roller_tmp" echo "$EMOJI Downloading roller..." sudo curl -L "$TGZ_URL" --progress-bar | sudo tar -xz -C "/tmp/roller_tmp" -# Assuming that the tar file contains the lib folder and the roller binary inside the roller_bins directory. +# Assuming that the tar file contains the lib folder and the roller and rollapp_evm binaries inside the roller_bins directory. # Move binaries to their correct locations echo "$EMOJI Installing roller..." sudo mv "/tmp/roller_tmp/roller_bins/lib"/* "$INTERNAL_DIR" sudo mv "/tmp/roller_tmp/roller_bins/roller" "$ROLLER_BIN_PATH" +sudo mv "/tmp/roller_tmp/roller_bins/rollapp_evm" "$ROLLAPP_EVM_PATH" # move the rollapp_evm binary -# Make roller executable +# Make roller and rollapp_evm executables sudo chmod +x "$ROLLER_BIN_PATH" +sudo chmod +x "$ROLLAPP_EVM_PATH" # Cleanup temporary directory sudo rm -rf "/tmp/roller_tmp" diff --git a/test/config/init/goldens/init_without_flags/light-node/config.toml b/test/config/init/goldens/init_with_flags/da-light-node/config.toml similarity index 100% rename from test/config/init/goldens/init_without_flags/light-node/config.toml rename to test/config/init/goldens/init_with_flags/da-light-node/config.toml diff --git a/test/config/init/goldens/init_without_flags/da-light-node/config.toml b/test/config/init/goldens/init_without_flags/da-light-node/config.toml new file mode 100644 index 00000000..5e9f1c04 --- /dev/null +++ b/test/config/init/goldens/init_without_flags/da-light-node/config.toml @@ -0,0 +1,77 @@ +[Core] + IP = "0.0.0.0" + RPCPort = "0" + GRPCPort = "0" + +[State] + KeyringAccName = "" + KeyringBackend = "test" + +[P2P] + ListenAddresses = ["/ip4/0.0.0.0/udp/2121/quic-v1", "/ip6/::/udp/2121/quic-v1", "/ip4/0.0.0.0/tcp/2121", "/ip6/::/tcp/2121"] + AnnounceAddresses = [] + NoAnnounceAddresses = ["/ip4/0.0.0.0/udp/2121/quic-v1", "/ip4/127.0.0.1/udp/2121/quic-v1", "/ip6/::/udp/2121/quic-v1", "/ip4/0.0.0.0/tcp/2121", "/ip4/127.0.0.1/tcp/2121", "/ip6/::/tcp/2121"] + MutualPeers = [] + PeerExchange = false + RoutingTableRefreshPeriod = "1m0s" + [P2P.ConnManager] + Low = 50 + High = 100 + GracePeriod = "1m0s" + +[RPC] + Address = "0.0.0.0" + Port = "26658" + +[Gateway] + Address = "0.0.0.0" + Port = "26659" + Enabled = false + +[Share] + UseShareExchange = true + [Share.ShrExEDSParams] + ServerReadTimeout = "5s" + ServerWriteTimeout = "1m0s" + HandleRequestTimeout = "1m0s" + ConcurrencyLimit = 10 + BufferSize = 32768 + [Share.ShrExNDParams] + ServerReadTimeout = "5s" + ServerWriteTimeout = "1m0s" + HandleRequestTimeout = "1m0s" + ConcurrencyLimit = 10 + [Share.PeerManagerParams] + PoolValidationTimeout = "2m0s" + PeerCooldown = "3s" + GcInterval = "30s" + EnableBlackListing = false + [Share.LightAvailability] + SampleAmount = 16 + [Share.Discovery] + PeersLimit = 5 + AdvertiseInterval = "22h0m0s" + +[Header] + TrustedHash = "" + TrustedPeers = [] + [Header.Store] + StoreCacheSize = 4096 + IndexCacheSize = 16384 + WriteBatchSize = 2048 + [Header.Syncer] + TrustingPeriod = "168h0m0s" + [Header.Server] + WriteDeadline = "8s" + ReadDeadline = "1m0s" + RangeRequestTimeout = "10s" + [Header.Client] + MaxHeadersPerRangeRequest = 64 + RangeRequestTimeout = "8s" + +[DASer] + SamplingRange = 100 + ConcurrencyLimit = 16 + BackgroundStoreInterval = "10m0s" + SampleFrom = 1 + SampleTimeout = "4m0s" diff --git a/test/config/init/init_test.go b/test/config/init/init_test.go index 87ab1d7f..75ce9863 100644 --- a/test/config/init/init_test.go +++ b/test/config/init/init_test.go @@ -14,7 +14,6 @@ import ( ) func TestInitCmd(t *testing.T) { - DAEndpoint := "http://localhost:26659" decimals := "6" testCases := []struct { name string @@ -30,7 +29,6 @@ func TestInitCmd(t *testing.T) { name: "Roller config init with custom flags", goldenDirPath: "./goldens/init_with_flags", optionalFlags: []string{ - "--" + initconfig.FlagNames.DAEndpoint, DAEndpoint, "--" + initconfig.FlagNames.Decimals, decimals, }, }, @@ -59,9 +57,7 @@ func TestInitCmd(t *testing.T) { 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) { - assert.NoError(testutils.VerifyLightNodeKeys(tempDir)) - } + assert.NoError(testutils.VerifyLightNodeKeys(tempDir)) assert.NoError(testutils.ClearKeys(tempDir)) are_dirs_equal, err := testutils.CompareDirs(tempDir, tc.goldenDirPath) assert.NoError(err) From 825a385085fbec3fe9e234480a5cc3ac47e592fe Mon Sep 17 00:00:00 2001 From: Itay Date: Mon, 19 Jun 2023 16:54:13 +0200 Subject: [PATCH 2/7] feat: Add clear output to the roller run command (#68) --- cmd/config/init/DALightClient.go | 2 +- cmd/run/run.go | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cmd/config/init/DALightClient.go b/cmd/config/init/DALightClient.go index 20cda210..2179b982 100644 --- a/cmd/config/init/DALightClient.go +++ b/cmd/config/init/DALightClient.go @@ -1,9 +1,9 @@ package initconfig import ( - "github.com/dymensionxyz/roller/cmd/consts" "os/exec" "path/filepath" + "github.com/dymensionxyz/roller/cmd/consts" ) func initializeLightNodeConfig(initConfig InitConfig) error { diff --git a/cmd/run/run.go b/cmd/run/run.go index ef44cf63..770f808f 100644 --- a/cmd/run/run.go +++ b/cmd/run/run.go @@ -22,8 +22,14 @@ func RunCmd() *cobra.Command { rollappConfig, err := initconfig.LoadConfigFromTOML(home) utils.PrettifyErrorIfExists(err) startRollappCmd := getStartRollapCmd(rollappConfig, cmd.Flag(daLightClientEndpointFlag).Value.String()) - startRollappErr := startRollappCmd.Run() + startRollappErr := startRollappCmd.Start() utils.PrettifyErrorIfExists(startRollappErr) + fmt.Println("šŸ’ˆ The Rollapp sequencer is running on your local machine!") + fmt.Println("šŸ’ˆ EVM RPC: http://0.0.0.0:8545") + fmt.Println("šŸ’ˆ Node RPC: http://0.0.0.0:26657") + fmt.Println("šŸ’ˆ Rest API: http://0.0.0.0:1317") + err = startRollappCmd.Wait() + utils.PrettifyErrorIfExists(err) }, } addFlags(runCmd) From 3eb406f08a3467e35645282ec88ca3f2230c5024 Mon Sep 17 00:00:00 2001 From: Itay Date: Tue, 20 Jun 2023 16:09:43 +0200 Subject: [PATCH 3/7] fix: Add rollapp ID `xxxx_num_num` enforcement on `roller config init` (#84) --- cmd/config/init/flags.go | 17 +++++++++++++++++ cmd/config/init/init.go | 7 ++++++- .../init_with_flags/relayer/config/config.yaml | 6 +++--- .../init_with_flags/rollapp/config/client.toml | 2 +- .../init_with_flags/rollapp/config/genesis.json | 2 +- .../relayer/config/config.yaml | 6 +++--- .../rollapp/config/client.toml | 2 +- .../rollapp/config/genesis.json | 2 +- test/config/init/init_test.go | 2 +- 9 files changed, 34 insertions(+), 12 deletions(-) diff --git a/cmd/config/init/flags.go b/cmd/config/init/flags.go index ae614656..31d1a8ea 100644 --- a/cmd/config/init/flags.go +++ b/cmd/config/init/flags.go @@ -2,6 +2,7 @@ package initconfig import ( "fmt" + "regexp" "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/cmd/utils" @@ -21,10 +22,20 @@ func addFlags(cmd *cobra.Command) { if _, ok := Hubs[hubID]; !ok { return fmt.Errorf("invalid hub ID: %s. %s", hubID, getAvailableHubsMessage()) } + rollappID := args[0] + if !validateRollAppID(rollappID) { + return fmt.Errorf("invalid RollApp ID '%s'. %s", rollappID, getValidRollappIdMessage()) + } return nil } } +func getValidRollappIdMessage() string { + return "A valid RollApp ID should follow the format 'rollapp-name_EIP155_version', where 'rollapp-name' is made up of" + + " lowercase English letters, 'EIP155_version' is a 1 to 5 digit number representing the EIP155 rollapp ID, and '" + + "version' is a 1 to 5 digit number representing the version. For example: 'mars_9721_1'" +} + func getDecimals(cmd *cobra.Command) uint64 { decimals, err := cmd.Flags().GetUint64(FlagNames.Decimals) if err != nil { @@ -61,3 +72,9 @@ func GetInitConfig(initCmd *cobra.Command, args []string) InitConfig { func getAvailableHubsMessage() string { return fmt.Sprintf("Acceptable values are '%s', '%s' or '%s'", TestnetHubID, StagingHubID, LocalHubID) } + +func validateRollAppID(id string) bool { + pattern := `^[a-z]+_[0-9]{1,5}_[0-9]{1,5}$` + r, _ := regexp.Compile(pattern) + return r.MatchString(id) +} diff --git a/cmd/config/init/init.go b/cmd/config/init/init.go index 2dbdd2c6..d41f5aa5 100644 --- a/cmd/config/init/init.go +++ b/cmd/config/init/init.go @@ -1,6 +1,7 @@ package initconfig import ( + "fmt" "os" "github.com/dymensionxyz/roller/cmd/consts" @@ -19,8 +20,12 @@ type InitConfig struct { func InitCmd() *cobra.Command { initCmd := &cobra.Command{ - Use: "init ", + Use: "init ", Short: "Initialize a RollApp configuration on your local machine.", + Long: fmt.Sprintf(`Initialize a RollApp configuration on your local machine. + +%s +`, getValidRollappIdMessage()), Run: func(cmd *cobra.Command, args []string) { initConfig := GetInitConfig(cmd, args) utils.PrettifyErrorIfExists(VerifyUniqueRollappID(initConfig.RollappID, initConfig)) diff --git a/test/config/init/goldens/init_with_flags/relayer/config/config.yaml b/test/config/init/goldens/init_with_flags/relayer/config/config.yaml index b42735ff..d5717557 100644 --- a/test/config/init/goldens/init_with_flags/relayer/config/config.yaml +++ b/test/config/init/goldens/init_with_flags/relayer/config/config.yaml @@ -19,11 +19,11 @@ chains: output-format: json sign-mode: direct client-type: 07-tendermint - mars: + mars_1_1: type: cosmos value: key: relayer-rollapp-key - chain-id: mars + chain-id: mars_1_1 rpc-addr: http://localhost:26657 account-prefix: rol keyring-backend: test @@ -37,7 +37,7 @@ chains: paths: hub-rollapp: src: - chain-id: mars + chain-id: mars_1_1 dst: chain-id: 35-C src-channel-filter: diff --git a/test/config/init/goldens/init_with_flags/rollapp/config/client.toml b/test/config/init/goldens/init_with_flags/rollapp/config/client.toml index 65b6640e..f1ac6bee 100644 --- a/test/config/init/goldens/init_with_flags/rollapp/config/client.toml +++ b/test/config/init/goldens/init_with_flags/rollapp/config/client.toml @@ -6,7 +6,7 @@ ############################################################################### # The network chain ID -chain-id = "mars" +chain-id = "mars_1_1" # The keyring's backend, where the keys are stored (os|file|kwallet|pass|test|memory) keyring-backend = "os" # CLI output format (text|json) diff --git a/test/config/init/goldens/init_with_flags/rollapp/config/genesis.json b/test/config/init/goldens/init_with_flags/rollapp/config/genesis.json index e5eef8bb..eb05d17a 100644 --- a/test/config/init/goldens/init_with_flags/rollapp/config/genesis.json +++ b/test/config/init/goldens/init_with_flags/rollapp/config/genesis.json @@ -1,6 +1,6 @@ { "genesis_time": "PLACEHOLDER_TIMESTAMP", - "chain_id": "mars", + "chain_id": "mars_1_1", "initial_height": "1", "consensus_params": { "block": { diff --git a/test/config/init/goldens/init_without_flags/relayer/config/config.yaml b/test/config/init/goldens/init_without_flags/relayer/config/config.yaml index b42735ff..d5717557 100644 --- a/test/config/init/goldens/init_without_flags/relayer/config/config.yaml +++ b/test/config/init/goldens/init_without_flags/relayer/config/config.yaml @@ -19,11 +19,11 @@ chains: output-format: json sign-mode: direct client-type: 07-tendermint - mars: + mars_1_1: type: cosmos value: key: relayer-rollapp-key - chain-id: mars + chain-id: mars_1_1 rpc-addr: http://localhost:26657 account-prefix: rol keyring-backend: test @@ -37,7 +37,7 @@ chains: paths: hub-rollapp: src: - chain-id: mars + chain-id: mars_1_1 dst: chain-id: 35-C src-channel-filter: diff --git a/test/config/init/goldens/init_without_flags/rollapp/config/client.toml b/test/config/init/goldens/init_without_flags/rollapp/config/client.toml index 65b6640e..f1ac6bee 100644 --- a/test/config/init/goldens/init_without_flags/rollapp/config/client.toml +++ b/test/config/init/goldens/init_without_flags/rollapp/config/client.toml @@ -6,7 +6,7 @@ ############################################################################### # The network chain ID -chain-id = "mars" +chain-id = "mars_1_1" # The keyring's backend, where the keys are stored (os|file|kwallet|pass|test|memory) keyring-backend = "os" # CLI output format (text|json) diff --git a/test/config/init/goldens/init_without_flags/rollapp/config/genesis.json b/test/config/init/goldens/init_without_flags/rollapp/config/genesis.json index dbbca89d..72afbd7a 100644 --- a/test/config/init/goldens/init_without_flags/rollapp/config/genesis.json +++ b/test/config/init/goldens/init_without_flags/rollapp/config/genesis.json @@ -1,6 +1,6 @@ { "genesis_time": "PLACEHOLDER_TIMESTAMP", - "chain_id": "mars", + "chain_id": "mars_1_1", "initial_height": "1", "consensus_params": { "block": { diff --git a/test/config/init/init_test.go b/test/config/init/init_test.go index 75ce9863..36e8dc62 100644 --- a/test/config/init/init_test.go +++ b/test/config/init/init_test.go @@ -45,7 +45,7 @@ func TestInitCmd(t *testing.T) { }() initCmd := initconfig.InitCmd() denom := "udym" - rollappID := "mars" + rollappID := "mars_1_1" initCmd.SetArgs(append([]string{ rollappID, denom, From eb18261c620f4af8f78a54f775f0b4ea59d26295 Mon Sep 17 00:00:00 2001 From: Itay Date: Wed, 21 Jun 2023 12:58:15 +0200 Subject: [PATCH 4/7] feat: Add ability to run Celestia DA light node (#71) --- cmd/config/init/DALightClient.go | 1 + cmd/consts/consts.go | 16 ++++-- cmd/da-light-client/da_light_client.go | 15 +++++ cmd/da-light-client/start/start.go | 58 ++++++++++++++++++++ cmd/root.go | 6 +- cmd/sequencer/sequencer.go | 15 +++++ cmd/{run/run.go => sequencer/start/start.go} | 57 +++++++++++-------- cmd/utils/bash_commands.go | 23 ++++++++ cmd/utils/error_handling.go | 3 +- cmd/utils/keys.go | 36 +++++++++++- go.mod | 1 - 11 files changed, 199 insertions(+), 32 deletions(-) create mode 100644 cmd/da-light-client/da_light_client.go create mode 100644 cmd/da-light-client/start/start.go create mode 100644 cmd/sequencer/sequencer.go rename cmd/{run/run.go => sequencer/start/start.go} (51%) create mode 100644 cmd/utils/bash_commands.go diff --git a/cmd/config/init/DALightClient.go b/cmd/config/init/DALightClient.go index 2179b982..ea75f86b 100644 --- a/cmd/config/init/DALightClient.go +++ b/cmd/config/init/DALightClient.go @@ -3,6 +3,7 @@ package initconfig import ( "os/exec" "path/filepath" + "github.com/dymensionxyz/roller/cmd/consts" ) diff --git a/cmd/consts/consts.go b/cmd/consts/consts.go index 1fb08633..bde59811 100644 --- a/cmd/consts/consts.go +++ b/cmd/consts/consts.go @@ -1,15 +1,23 @@ package consts +import "fmt" + +const binsDir = "/usr/local/bin" + +var internalBinsDir = fmt.Sprintf("%s/roller_bins", binsDir) + var Executables = struct { Celestia string RollappEVM string Relayer string Dymension string + CelKey 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", + Celestia: fmt.Sprintf("%s/celestia", internalBinsDir), + CelKey: fmt.Sprintf("%s/cel-key", internalBinsDir), + RollappEVM: fmt.Sprintf("%s/rollapp_evm", binsDir), + Relayer: fmt.Sprintf("%s/rly", internalBinsDir), + Dymension: fmt.Sprintf("%s/dymd", internalBinsDir), } var KeyNames = struct { diff --git a/cmd/da-light-client/da_light_client.go b/cmd/da-light-client/da_light_client.go new file mode 100644 index 00000000..8988fdd0 --- /dev/null +++ b/cmd/da-light-client/da_light_client.go @@ -0,0 +1,15 @@ +package da_light_client + +import ( + da_start "github.com/dymensionxyz/roller/cmd/da-light-client/start" + "github.com/spf13/cobra" +) + +func DALightClientCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "da-light-client", + Short: "Commands for running and managing the data availability light client.", + } + cmd.AddCommand(da_start.Cmd()) + return cmd +} diff --git a/cmd/da-light-client/start/start.go b/cmd/da-light-client/start/start.go new file mode 100644 index 00000000..20ed3392 --- /dev/null +++ b/cmd/da-light-client/start/start.go @@ -0,0 +1,58 @@ +package start + +import ( + "fmt" + "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" +) + +const rpcEndpointFlag = "--rpc-endpoint" + +func Cmd() *cobra.Command { + runCmd := &cobra.Command{ + Use: "start", + Short: "Runs the rollapp sequencer.", + Run: func(cmd *cobra.Command, args []string) { + home := cmd.Flag(utils.FlagNames.Home).Value.String() + rollappConfig, err := initconfig.LoadConfigFromTOML(home) + utils.PrettifyErrorIfExists(err) + rpcEndpoint := cmd.Flag(rpcEndpointFlag).Value.String() + startRollappCmd := getStartCelestiaLCCmd(rollappConfig, rpcEndpoint) + utils.RunBashCmdAsync(startRollappCmd, printOutput, parseError) + }, + } + utils.AddGlobalFlags(runCmd) + addFlags(runCmd) + return runCmd +} + +func addFlags(cmd *cobra.Command) { + cmd.Flags().StringP(rpcEndpointFlag, "", "consensus-full-arabica-8.celestia-arabica.com", + "The DA rpc endpoint to connect to.") +} + +func printOutput() { + fmt.Println("šŸ’ˆ The data availability light node is running on your local machine!") + fmt.Println("šŸ’ˆ Light node endpoint: http://127.0.0.1:26659") +} + +func parseError(errMsg string) string { + return errMsg +} + +func getStartCelestiaLCCmd(rollappConfig initconfig.InitConfig, rpcEndpoint string) *exec.Cmd { + return exec.Command( + consts.Executables.Celestia, "light", "start", + "--core.ip", rpcEndpoint, + "--node.store", filepath.Join(rollappConfig.Home, consts.ConfigDirName.DALightNode), + "--gateway", + "--gateway.addr", "127.0.0.1", + "--gateway.port", "26659", + "--p2p.network", "arabica", + ) +} diff --git a/cmd/root.go b/cmd/root.go index d156a707..1a246d6d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,8 +4,9 @@ import ( "os" "github.com/dymensionxyz/roller/cmd/config" + da_light_client "github.com/dymensionxyz/roller/cmd/da-light-client" "github.com/dymensionxyz/roller/cmd/register" - "github.com/dymensionxyz/roller/cmd/run" + "github.com/dymensionxyz/roller/cmd/sequencer" "github.com/dymensionxyz/roller/cmd/version" "github.com/spf13/cobra" ) @@ -29,5 +30,6 @@ func init() { rootCmd.AddCommand(config.ConfigCmd()) rootCmd.AddCommand(version.VersionCmd()) rootCmd.AddCommand(register.RegisterCmd()) - rootCmd.AddCommand(run.RunCmd()) + rootCmd.AddCommand(da_light_client.DALightClientCmd()) + rootCmd.AddCommand(sequencer.SequencerCmd()) } diff --git a/cmd/sequencer/sequencer.go b/cmd/sequencer/sequencer.go new file mode 100644 index 00000000..96a03c5b --- /dev/null +++ b/cmd/sequencer/sequencer.go @@ -0,0 +1,15 @@ +package sequencer + +import ( + sequnecer_start "github.com/dymensionxyz/roller/cmd/sequencer/start" + "github.com/spf13/cobra" +) + +func SequencerCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "sequencer", + Short: "Commands for running and managing the RollApp sequnecer.", + } + cmd.AddCommand(sequnecer_start.StartCmd()) + return cmd +} diff --git a/cmd/run/run.go b/cmd/sequencer/start/start.go similarity index 51% rename from cmd/run/run.go rename to cmd/sequencer/start/start.go index 770f808f..b85a9bc2 100644 --- a/cmd/run/run.go +++ b/cmd/sequencer/start/start.go @@ -1,51 +1,64 @@ -package run +package sequnecer_start import ( "fmt" - "github.com/dymensionxyz/roller/cmd/consts" "os/exec" "path/filepath" + "strings" + initconfig "github.com/dymensionxyz/roller/cmd/config/init" + "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/cmd/utils" "github.com/spf13/cobra" ) -const daLightClientEndpointFlag = "da-light-client-endpoint" - -func RunCmd() *cobra.Command { +func StartCmd() *cobra.Command { runCmd := &cobra.Command{ - Use: "run", + Use: "start", Short: "Runs the rollapp sequencer.", Run: func(cmd *cobra.Command, args []string) { home := cmd.Flag(utils.FlagNames.Home).Value.String() rollappConfig, err := initconfig.LoadConfigFromTOML(home) utils.PrettifyErrorIfExists(err) - startRollappCmd := getStartRollapCmd(rollappConfig, cmd.Flag(daLightClientEndpointFlag).Value.String()) - startRollappErr := startRollappCmd.Start() - utils.PrettifyErrorIfExists(startRollappErr) - fmt.Println("šŸ’ˆ The Rollapp sequencer is running on your local machine!") - fmt.Println("šŸ’ˆ EVM RPC: http://0.0.0.0:8545") - fmt.Println("šŸ’ˆ Node RPC: http://0.0.0.0:26657") - fmt.Println("šŸ’ˆ Rest API: http://0.0.0.0:1317") - err = startRollappCmd.Wait() - utils.PrettifyErrorIfExists(err) + LightNodeEndpoint := cmd.Flag(FlagNames.DAEndpoint).Value.String() + startRollappCmd := getStartRollapCmd(rollappConfig, LightNodeEndpoint) + utils.RunBashCmdAsync(startRollappCmd, printOutput, parseError) }, } - addFlags(runCmd) utils.AddGlobalFlags(runCmd) + runCmd.Flags().StringP(FlagNames.DAEndpoint, "", "http://localhost:26659", "The data availability light node endpoint.") return runCmd } -func addFlags(cmd *cobra.Command) { - cmd.Flags().StringP(daLightClientEndpointFlag, "", "http://localhost:26659", "The DA light client endpoint.") +var FlagNames = struct { + DAEndpoint string +}{ + DAEndpoint: "da-endpoint", } -func getStartRollapCmd(rollappConfig initconfig.InitConfig, daLightClientEndpoint string) *exec.Cmd { - daConfig := fmt.Sprintf(`{"base_url": "%s", "timeout": 60000000000, "fee":20000, "gas_limit": 20000000, "namespace_id":[0,0,0,0,0,0,255,255]}`, daLightClientEndpoint) +func printOutput() { + fmt.Println("šŸ’ˆ The Rollapp sequencer is running on your local machine!") + fmt.Println("šŸ’ˆ EVM RPC: http://0.0.0.0:8545") + fmt.Println("šŸ’ˆ Node RPC: http://0.0.0.0:26657") + fmt.Println("šŸ’ˆ Rest API: http://0.0.0.0:1317") +} + +func parseError(errMsg string) string { + lines := strings.Split(errMsg, "\n") + if len(lines) > 0 && lines[0] == "Error: failed to initialize database: resource temporarily unavailable" { + return "The Rollapp sequencer is already running. Only one sequencer can run on the machine at any given time." + } + return errMsg +} + +func getStartRollapCmd(rollappConfig initconfig.InitConfig, lightNodeEndpoint string) *exec.Cmd { + daConfig := fmt.Sprintf(`{"base_url": "%s", "timeout": 60000000000, "fee":20000, "gas_limit": 20000000, "namespace_id":[0,0,0,0,0,0,255,255]}`, + lightNodeEndpoint) rollappConfigDir := filepath.Join(rollappConfig.Home, consts.ConfigDirName.Rollapp) - settlementConfig := fmt.Sprintf(`{"node_address": "%s", "rollapp_id": "%s", "dym_account_name": "%s", "keyring_home_dir": "%s", "keyring_backend":"test", "gas_fees": "2000000udym"}`, - rollappConfig.HubData.RPC_URL, rollappConfig.RollappID, consts.KeyNames.HubSequencer, rollappConfigDir) + + // TODO: Update the gas_fees to 2000000udym before 35-c launch. + settlementConfig := fmt.Sprintf(`{"node_address": "%s", "rollapp_id": "%s", "dym_account_name": "%s", "keyring_home_dir": "%s", "keyring_backend":"test", "gas_fees": "0udym"}`, rollappConfig.HubData.RPC_URL, rollappConfig.RollappID, consts.KeyNames.HubSequencer, rollappConfigDir) return exec.Command( rollappConfig.RollappBinary, "start", diff --git a/cmd/utils/bash_commands.go b/cmd/utils/bash_commands.go new file mode 100644 index 00000000..3d7f1880 --- /dev/null +++ b/cmd/utils/bash_commands.go @@ -0,0 +1,23 @@ +package utils + +import ( + "bytes" + "errors" + "os/exec" +) + +func RunBashCmdAsync(cmd *exec.Cmd, printOutput func(), parseError func(errMsg string) string) { + var stderr bytes.Buffer + cmd.Stderr = &stderr + err := cmd.Start() + if err != nil { + errMsg := parseError(stderr.String()) + PrettifyErrorIfExists(errors.New(errMsg)) + } + printOutput() + err = cmd.Wait() + if err != nil { + errMsg := parseError(stderr.String()) + PrettifyErrorIfExists(errors.New(errMsg)) + } +} diff --git a/cmd/utils/error_handling.go b/cmd/utils/error_handling.go index 9eaa8ac0..b84c305c 100644 --- a/cmd/utils/error_handling.go +++ b/cmd/utils/error_handling.go @@ -1,9 +1,8 @@ package utils import ( - "os" - "github.com/fatih/color" + "os" ) func PrettifyErrorIfExists(err error) { diff --git a/cmd/utils/keys.go b/cmd/utils/keys.go index a6a2a4f3..596464f4 100644 --- a/cmd/utils/keys.go +++ b/cmd/utils/keys.go @@ -1,11 +1,46 @@ package utils import ( + "bytes" + "encoding/json" + "errors" + "os/exec" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/bech32" + "github.com/dymensionxyz/roller/cmd/consts" ) +type KeyInfo struct { + Address string `json:"address"` +} + +func GetCelestiaAddress(keyringDir string) (string, error) { + cmd := exec.Command( + consts.Executables.CelKey, + "show", consts.KeyNames.DALightNode, "--node.type", "light", "--keyring-dir", keyringDir, "--keyring-backend", "test", "--output", "json", + ) + + var out bytes.Buffer + var stderr bytes.Buffer + cmd.Stdout = &out + cmd.Stderr = &stderr + + err := cmd.Run() + if err != nil { + return "", errors.New(stderr.String()) + } + + var key = &KeyInfo{} + err = json.Unmarshal(out.Bytes(), key) + if err != nil { + return "", err + } + + return key.Address, nil +} + type KeyConfig struct { Dir string ID string @@ -41,6 +76,5 @@ func GetAddress(keyConfig KeyConfig) (string, error) { if err != nil { return "", err } - return formattedAddress, nil } diff --git a/go.mod b/go.mod index 49e94026..6b36e61e 100644 --- a/go.mod +++ b/go.mod @@ -65,7 +65,6 @@ require ( github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect From 86193333d1fb78d1af22841b3ecbc0e1af36d0c4 Mon Sep 17 00:00:00 2001 From: Itay Date: Thu, 22 Jun 2023 13:23:12 +0200 Subject: [PATCH 5/7] feat: Add IBC channel creation capability from `roller relayer start` command (#74) --- cmd/config/init/DALightClient.go | 3 +- cmd/config/init/consts.go | 13 +-- cmd/config/init/flags.go | 4 +- cmd/config/init/genesis.go | 5 +- cmd/config/init/init.go | 26 ++--- cmd/config/init/keys.go | 101 +++++++++++++++--- cmd/config/init/output.go | 5 +- cmd/config/init/relayer.go | 10 +- cmd/config/init/rollapp.go | 5 +- cmd/config/init/unique_rollapp_id.go | 5 +- cmd/consts/consts.go | 5 +- cmd/da-light-client/start/start.go | 5 +- cmd/register/bash_commands.go | 10 +- cmd/register/register.go | 12 +-- cmd/relayer/relayer.go | 15 +++ cmd/relayer/start/start.go | 37 +++++++ cmd/root.go | 2 + cmd/run/run.go | 89 +++++++++++++++ cmd/sequencer/start/start.go | 5 +- cmd/utils/bash_commands.go | 26 +++++ .../persistence_config.go => utils/config.go} | 28 +++-- cmd/utils/error_handling.go | 1 + cmd/utils/keys.go | 40 ++++--- .../relayer/config/config.yaml | 4 +- .../relayer/config/config.yaml | 4 +- test/config/init/init_test.go | 2 +- test/config/init/testutils/keys.go | 8 +- test/config/init/testutils/rollapp.go | 5 +- 28 files changed, 368 insertions(+), 107 deletions(-) create mode 100644 cmd/relayer/relayer.go create mode 100644 cmd/relayer/start/start.go create mode 100644 cmd/run/run.go rename cmd/{config/init/persistence_config.go => utils/config.go} (54%) diff --git a/cmd/config/init/DALightClient.go b/cmd/config/init/DALightClient.go index ea75f86b..cc5cff7a 100644 --- a/cmd/config/init/DALightClient.go +++ b/cmd/config/init/DALightClient.go @@ -1,13 +1,14 @@ package initconfig import ( + "github.com/dymensionxyz/roller/cmd/utils" "os/exec" "path/filepath" "github.com/dymensionxyz/roller/cmd/consts" ) -func initializeLightNodeConfig(initConfig InitConfig) error { +func initializeLightNodeConfig(initConfig utils.RollappConfig) error { initLightNodeCmd := exec.Command(consts.Executables.Celestia, "light", "init", "--p2p.network", "arabica", "--node.store", filepath.Join(initConfig.Home, consts.ConfigDirName.DALightNode)) err := initLightNodeCmd.Run() if err != nil { diff --git a/cmd/config/init/consts.go b/cmd/config/init/consts.go index d59f9e82..fb705922 100644 --- a/cmd/config/init/consts.go +++ b/cmd/config/init/consts.go @@ -1,5 +1,7 @@ package initconfig +import "github.com/dymensionxyz/roller/cmd/utils" + var FlagNames = struct { Home string Decimals string @@ -16,7 +18,7 @@ const TestnetHubID = "35-C" const StagingHubID = "internal-devnet" const LocalHubID = "local" -var Hubs = map[string]HubData{ +var Hubs = map[string]utils.HubData{ TestnetHubID: { API_URL: "https://rest-hub-35c.dymension.xyz", ID: "35-C", @@ -34,13 +36,4 @@ var Hubs = map[string]HubData{ }, } -type HubData = struct { - API_URL string - ID string - RPC_URL string -} - const defaultRollappRPC = "http://localhost:26657" - -const KeysDirName = "keys" -const RollerConfigFileName = "config.toml" diff --git a/cmd/config/init/flags.go b/cmd/config/init/flags.go index 31d1a8ea..384ec3f2 100644 --- a/cmd/config/init/flags.go +++ b/cmd/config/init/flags.go @@ -52,14 +52,14 @@ func getRollappBinaryPath(cmd *cobra.Command) string { return rollappBinaryPath } -func GetInitConfig(initCmd *cobra.Command, args []string) InitConfig { +func GetInitConfig(initCmd *cobra.Command, args []string) utils.RollappConfig { rollappId := args[0] denom := args[1] home := initCmd.Flag(utils.FlagNames.Home).Value.String() rollappBinaryPath := getRollappBinaryPath(initCmd) decimals := getDecimals(initCmd) hubID := initCmd.Flag(FlagNames.HubID).Value.String() - return InitConfig{ + return utils.RollappConfig{ Home: home, RollappID: rollappId, RollappBinary: rollappBinaryPath, diff --git a/cmd/config/init/genesis.go b/cmd/config/init/genesis.go index ce07fc35..301a7be6 100644 --- a/cmd/config/init/genesis.go +++ b/cmd/config/init/genesis.go @@ -1,17 +1,18 @@ package initconfig import ( + "github.com/dymensionxyz/roller/cmd/utils" "io/ioutil" "fmt" "os/exec" "path/filepath" - "github.com/tidwall/sjson" "github.com/dymensionxyz/roller/cmd/consts" + "github.com/tidwall/sjson" ) -func initializeRollappGenesis(initConfig InitConfig) error { +func initializeRollappGenesis(initConfig utils.RollappConfig) error { zeros := initConfig.Decimals + 9 tokenAmount := "1" + fmt.Sprintf("%0*d", zeros, 0) + initConfig.Denom rollappConfigDirPath := filepath.Join(initConfig.Home, consts.ConfigDirName.Rollapp) diff --git a/cmd/config/init/init.go b/cmd/config/init/init.go index d41f5aa5..a169732d 100644 --- a/cmd/config/init/init.go +++ b/cmd/config/init/init.go @@ -9,15 +9,6 @@ import ( "github.com/spf13/cobra" ) -type InitConfig struct { - Home string - RollappID string - RollappBinary string - Denom string - Decimals uint64 - HubData HubData -} - func InitCmd() *cobra.Command { initCmd := &cobra.Command{ Use: "init ", @@ -36,16 +27,13 @@ func InitCmd() *cobra.Command { utils.PrettifyErrorIfExists(err) if shouldOverwrite { utils.PrettifyErrorIfExists(os.RemoveAll(initConfig.Home)) + utils.PrettifyErrorIfExists(os.MkdirAll(initConfig.Home, 0755)) } else { os.Exit(0) } + } else { + utils.PrettifyErrorIfExists(os.MkdirAll(initConfig.Home, 0755)) } - - addresses, err := generateKeys(initConfig) - utils.PrettifyErrorIfExists(err) - utils.PrettifyErrorIfExists(initializeLightNodeConfig(initConfig)) - initializeRollappConfig(initConfig) - utils.PrettifyErrorIfExists(initializeRollappGenesis(initConfig)) utils.PrettifyErrorIfExists(initializeRelayerConfig(ChainConfig{ ID: initConfig.RollappID, RPC: defaultRollappRPC, @@ -57,7 +45,13 @@ func InitCmd() *cobra.Command { Denom: "udym", AddressPrefix: consts.AddressPrefixes.Hub, }, initConfig)) - utils.PrettifyErrorIfExists(WriteConfigToTOML(initConfig)) + addresses, err := generateKeys(initConfig) + utils.PrettifyErrorIfExists(err) + utils.PrettifyErrorIfExists(initializeLightNodeConfig(initConfig)) + initializeRollappConfig(initConfig) + utils.PrettifyErrorIfExists(initializeRollappGenesis(initConfig)) + + utils.PrettifyErrorIfExists(utils.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 a6e657c5..57cee5c4 100644 --- a/cmd/config/init/keys.go +++ b/cmd/config/init/keys.go @@ -1,8 +1,10 @@ package initconfig import ( + "os/exec" "path" "path/filepath" + "strconv" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" @@ -10,15 +12,29 @@ import ( "github.com/dymensionxyz/roller/cmd/utils" ) -func generateKeys(initConfig InitConfig, excludeKeys ...string) (map[string]string, error) { - keys := getDefaultKeysConfig(initConfig) - excludeKeysMap := make(map[string]struct{}) - for _, key := range excludeKeys { - excludeKeysMap[key] = struct{}{} +func generateKeys(rollappConfig utils.RollappConfig) (map[string]string, error) { + sequencerAddresses, err := generateSequencersKeys(rollappConfig) + if err != nil { + return nil, err + } + relayerAddresses, err := generateRelayerKeys(rollappConfig) + if err != nil { + return nil, err } + return utils.MergeMaps(sequencerAddresses, relayerAddresses), nil +} + +func generateSequencersKeys(initConfig utils.RollappConfig) (map[string]string, error) { + keys := getSequencerKeysConfig() addresses := make(map[string]string) for _, key := range keys { - if _, exists := excludeKeysMap[key.ID]; !exists { + if key.Prefix == consts.AddressPrefixes.Rollapp { + address, err := createAddressBinary(key, consts.Executables.RollappEVM, initConfig.Home) + if err != nil { + return nil, err + } + addresses[key.ID] = address + } else { keyInfo, err := createKey(key, initConfig.Home) if err != nil { return nil, err @@ -51,7 +67,7 @@ func createKey(keyConfig utils.KeyConfig, home string) (keyring.Info, error) { return info, nil } -func getDefaultKeysConfig(initConfig InitConfig) []utils.KeyConfig { +func getSequencerKeysConfig() []utils.KeyConfig { return []utils.KeyConfig{ { Dir: consts.ConfigDirName.Rollapp, @@ -65,17 +81,72 @@ func getDefaultKeysConfig(initConfig InitConfig) []utils.KeyConfig { CoinType: consts.CoinTypes.EVM, Prefix: consts.AddressPrefixes.Rollapp, }, - { - Dir: path.Join(consts.ConfigDirName.Relayer, KeysDirName, initConfig.HubData.ID), - ID: consts.KeyNames.HubRelayer, - CoinType: consts.CoinTypes.Cosmos, - Prefix: consts.AddressPrefixes.Hub, - }, - { - Dir: path.Join(consts.ConfigDirName.Relayer, KeysDirName, initConfig.RollappID), + } +} + +func getRelayerKeysConfig(rollappConfig utils.RollappConfig) map[string]utils.KeyConfig { + return map[string]utils.KeyConfig{ + consts.KeyNames.RollappRelayer: { + Dir: path.Join(rollappConfig.Home, consts.ConfigDirName.Relayer), ID: consts.KeyNames.RollappRelayer, CoinType: consts.CoinTypes.EVM, Prefix: consts.AddressPrefixes.Rollapp, }, + consts.KeyNames.HubRelayer: { + Dir: path.Join(rollappConfig.Home, consts.ConfigDirName.Relayer), + ID: consts.KeyNames.HubRelayer, + CoinType: consts.CoinTypes.Cosmos, + Prefix: consts.AddressPrefixes.Hub, + }, + } +} + +func createAddressBinary(keyConfig utils.KeyConfig, binaryPath string, home string) (string, error) { + createKeyCommand := exec.Command(binaryPath, "keys", "add", keyConfig.ID, "--keyring-backend", "test", + "--keyring-dir", filepath.Join(home, keyConfig.Dir), "--output", "json") + out, err := utils.ExecBashCommand(createKeyCommand) + if err != nil { + return "", err + } + return utils.ParseAddressFromOutput(out) +} + +func generateRelayerKeys(rollappConfig utils.RollappConfig) (map[string]string, error) { + relayerAddresses := make(map[string]string) + keys := getRelayerKeysConfig(rollappConfig) + createRollappKeyCmd := getAddRlyKeyCmd(keys[consts.KeyNames.RollappRelayer], rollappConfig.RollappID) + createHubKeyCmd := getAddRlyKeyCmd(keys[consts.KeyNames.HubRelayer], rollappConfig.HubData.ID) + out, err := utils.ExecBashCommand(createRollappKeyCmd) + if err != nil { + return nil, err + } + relayerRollappAddress, err := utils.ParseAddressFromOutput(out) + if err != nil { + return nil, err + } + relayerAddresses[consts.KeyNames.RollappRelayer] = relayerRollappAddress + out, err = utils.ExecBashCommand(createHubKeyCmd) + if err != nil { + return nil, err } + relayerHubAddress, err := utils.ParseAddressFromOutput(out) + if err != nil { + return nil, err + } + relayerAddresses[consts.KeyNames.HubRelayer] = relayerHubAddress + return relayerAddresses, err +} + +func getAddRlyKeyCmd(keyConfig utils.KeyConfig, chainID string) *exec.Cmd { + return exec.Command( + consts.Executables.Relayer, + consts.KeysDirName, + "add", + chainID, + keyConfig.ID, + "--home", + keyConfig.Dir, + "--coin-type", + strconv.Itoa(int(keyConfig.CoinType)), + ) } diff --git a/cmd/config/init/output.go b/cmd/config/init/output.go index 41a6ef8f..bb87d86e 100644 --- a/cmd/config/init/output.go +++ b/cmd/config/init/output.go @@ -4,8 +4,8 @@ import ( "fmt" "os" - "github.com/olekukonko/tablewriter" "github.com/dymensionxyz/roller/cmd/consts" + "github.com/olekukonko/tablewriter" ) func printInitOutput(addresses map[string]string, rollappId string) { @@ -16,7 +16,8 @@ func printInitOutput(addresses map[string]string, rollappId string) { data := [][]string{ {"Celestia", addresses[consts.KeyNames.DALightNode]}, {"Sequencer", addresses[consts.KeyNames.HubSequencer]}, - {"Relayer", addresses[consts.KeyNames.HubRelayer]}, + {"Relayer, Hub", addresses[consts.KeyNames.HubRelayer]}, + {"Relayer, RollApp", addresses[consts.KeyNames.RollappRelayer]}, } table := tablewriter.NewWriter(os.Stdout) diff --git a/cmd/config/init/relayer.go b/cmd/config/init/relayer.go index b738d6c7..3ec7c765 100644 --- a/cmd/config/init/relayer.go +++ b/cmd/config/init/relayer.go @@ -2,6 +2,7 @@ package initconfig import ( "encoding/json" + "github.com/dymensionxyz/roller/cmd/utils" "io/ioutil" "os" "os/exec" @@ -102,7 +103,7 @@ func addChainsConfig(rollappConfig ChainConfig, hubConfig ChainConfig, relayerHo relayerHubConfig := getRelayerFileChainConfig(RelayerChainConfig{ ChainConfig: hubConfig, - GasPrices: "0.25" + hubConfig.Denom, + GasPrices: "0.0" + hubConfig.Denom, ClientType: "07-tendermint", KeyName: consts.KeyNames.HubRelayer, }) @@ -121,15 +122,16 @@ func setupPath(rollappConfig ChainConfig, hubConfig ChainConfig, relayerHome str if err := setSettlementCmd.Run(); err != nil { return err } - relayerPath := "hub-rollapp" - newPathCmd := exec.Command(consts.Executables.Relayer, "paths", "new", rollappConfig.ID, hubConfig.ID, relayerPath, "--src-port", "transfer", "--dst-port", "transfer", "--version", "ics20-1", "--home", relayerHome) + args := []string{"paths", "new", rollappConfig.ID, hubConfig.ID, consts.DefaultRelayerPath} + args = append(args, utils.GetRelayerDefaultFlags(relayerHome)...) + newPathCmd := exec.Command(consts.Executables.Relayer, args...) if err := newPathCmd.Run(); err != nil { return err } return nil } -func initializeRelayerConfig(rollappConfig ChainConfig, hubConfig ChainConfig, initConfig InitConfig) error { +func initializeRelayerConfig(rollappConfig ChainConfig, hubConfig ChainConfig, initConfig utils.RollappConfig) error { relayerHome := filepath.Join(initConfig.Home, consts.ConfigDirName.Relayer) if err := initRelayer(relayerHome); err != nil { return err diff --git a/cmd/config/init/rollapp.go b/cmd/config/init/rollapp.go index 44052187..10f1c3b3 100644 --- a/cmd/config/init/rollapp.go +++ b/cmd/config/init/rollapp.go @@ -1,15 +1,16 @@ package initconfig import ( + "github.com/dymensionxyz/roller/cmd/utils" "os" "os/exec" "path/filepath" - toml "github.com/pelletier/go-toml" "github.com/dymensionxyz/roller/cmd/consts" + toml "github.com/pelletier/go-toml" ) -func initializeRollappConfig(initConfig InitConfig) { +func initializeRollappConfig(initConfig utils.RollappConfig) { initRollappCmd := exec.Command(initConfig.RollappBinary, "init", consts.KeyNames.HubSequencer, "--chain-id", initConfig.RollappID, "--home", filepath.Join(initConfig.Home, consts.ConfigDirName.Rollapp)) err := initRollappCmd.Run() if err != nil { diff --git a/cmd/config/init/unique_rollapp_id.go b/cmd/config/init/unique_rollapp_id.go index 13e33188..ee8a2f18 100644 --- a/cmd/config/init/unique_rollapp_id.go +++ b/cmd/config/init/unique_rollapp_id.go @@ -2,10 +2,11 @@ package initconfig import ( "fmt" + "github.com/dymensionxyz/roller/cmd/utils" "net/http" ) -func IsRollappIDUnique(rollappID string, initConfig InitConfig) (bool, error) { +func IsRollappIDUnique(rollappID string, initConfig utils.RollappConfig) (bool, error) { url := initConfig.HubData.API_URL + "/dymensionxyz/dymension/rollapp/rollapp/" + rollappID req, err := http.NewRequest("GET", url, nil) @@ -31,7 +32,7 @@ func IsRollappIDUnique(rollappID string, initConfig InitConfig) (bool, error) { } } -func VerifyUniqueRollappID(rollappID string, initConfig InitConfig) error { +func VerifyUniqueRollappID(rollappID string, initConfig utils.RollappConfig) error { isUniqueRollapp, err := IsRollappIDUnique(rollappID, initConfig) if err != nil { return err diff --git a/cmd/consts/consts.go b/cmd/consts/consts.go index bde59811..57d5ae59 100644 --- a/cmd/consts/consts.go +++ b/cmd/consts/consts.go @@ -39,7 +39,7 @@ var AddressPrefixes = struct { Rollapp string DA string }{ - Rollapp: "rol", + Rollapp: "ethm", Hub: "dym", DA: "celestia", } @@ -61,3 +61,6 @@ var CoinTypes = struct { Cosmos: 118, EVM: 60, } + +const KeysDirName = "keys" +const DefaultRelayerPath = "hub-rollapp" diff --git a/cmd/da-light-client/start/start.go b/cmd/da-light-client/start/start.go index 20ed3392..e4d79a97 100644 --- a/cmd/da-light-client/start/start.go +++ b/cmd/da-light-client/start/start.go @@ -5,7 +5,6 @@ import ( "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" @@ -19,7 +18,7 @@ func Cmd() *cobra.Command { Short: "Runs the rollapp sequencer.", Run: func(cmd *cobra.Command, args []string) { home := cmd.Flag(utils.FlagNames.Home).Value.String() - rollappConfig, err := initconfig.LoadConfigFromTOML(home) + rollappConfig, err := utils.LoadConfigFromTOML(home) utils.PrettifyErrorIfExists(err) rpcEndpoint := cmd.Flag(rpcEndpointFlag).Value.String() startRollappCmd := getStartCelestiaLCCmd(rollappConfig, rpcEndpoint) @@ -45,7 +44,7 @@ func parseError(errMsg string) string { return errMsg } -func getStartCelestiaLCCmd(rollappConfig initconfig.InitConfig, rpcEndpoint string) *exec.Cmd { +func getStartCelestiaLCCmd(rollappConfig utils.RollappConfig, rpcEndpoint string) *exec.Cmd { return exec.Command( consts.Executables.Celestia, "light", "start", "--core.ip", rpcEndpoint, diff --git a/cmd/register/bash_commands.go b/cmd/register/bash_commands.go index e6ee856a..310a0684 100644 --- a/cmd/register/bash_commands.go +++ b/cmd/register/bash_commands.go @@ -1,6 +1,7 @@ package register import ( + "github.com/dymensionxyz/roller/cmd/utils" "os/exec" "path/filepath" @@ -8,11 +9,10 @@ import ( "strings" - initconfig "github.com/dymensionxyz/roller/cmd/config/init" "github.com/dymensionxyz/roller/cmd/consts" ) -func getRegisterRollappCmd(rollappConfig initconfig.InitConfig) *exec.Cmd { +func getRegisterRollappCmd(rollappConfig utils.RollappConfig) *exec.Cmd { cmdArgs := []string{ "tx", "rollapp", "create-rollapp", rollappConfig.RollappID, "stamp1", "genesis-path/1", "3", "3", `{"Addresses":[]}`, } @@ -22,7 +22,7 @@ func getRegisterRollappCmd(rollappConfig initconfig.InitConfig) *exec.Cmd { ) } -func showSequencerPubKey(rollappConfig initconfig.InitConfig) (string, error) { +func showSequencerPubKey(rollappConfig utils.RollappConfig) (string, error) { cmd := exec.Command( consts.Executables.RollappEVM, "dymint", @@ -37,7 +37,7 @@ func showSequencerPubKey(rollappConfig initconfig.InitConfig) (string, error) { return strings.ReplaceAll(strings.ReplaceAll(string(out), "\n", ""), "\\", ""), nil } -func getRegisterSequencerCmd(rollappConfig initconfig.InitConfig) (*exec.Cmd, error) { +func getRegisterSequencerCmd(rollappConfig utils.RollappConfig) (*exec.Cmd, error) { seqPubKey, err := showSequencerPubKey(rollappConfig) if err != nil { return nil, err @@ -54,7 +54,7 @@ func getRegisterSequencerCmd(rollappConfig initconfig.InitConfig) (*exec.Cmd, er return exec.Command(consts.Executables.Dymension, cmdArgs...), nil } -func getCommonFlags(rollappConfig initconfig.InitConfig) []string { +func getCommonFlags(rollappConfig utils.RollappConfig) []string { return []string{ "--from", consts.KeyNames.HubSequencer, "--keyring-backend", "test", diff --git a/cmd/register/register.go b/cmd/register/register.go index 9f654988..a6c97d7b 100644 --- a/cmd/register/register.go +++ b/cmd/register/register.go @@ -22,8 +22,8 @@ func 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) + home := cmd.Flag(utils.FlagNames.Home).Value.String() + rollappConfig, err := utils.LoadConfigFromTOML(home) utils.PrettifyErrorIfExists(err) utils.PrettifyErrorIfExists(initconfig.VerifyUniqueRollappID(rollappConfig.RollappID, rollappConfig)) utils.PrettifyErrorIfExists(registerRollapp(rollappConfig)) @@ -38,7 +38,7 @@ func RegisterCmd() *cobra.Command { return registerCmd } -func registerRollapp(rollappConfig initconfig.InitConfig) error { +func registerRollapp(rollappConfig utils.RollappConfig) error { cmd := getRegisterRollappCmd(rollappConfig) var stdout bytes.Buffer var stderr bytes.Buffer @@ -57,7 +57,7 @@ func registerRollapp(rollappConfig initconfig.InitConfig) error { return nil } -func handleStdErr(stderr bytes.Buffer, rollappConfig initconfig.InitConfig) error { +func handleStdErr(stderr bytes.Buffer, rollappConfig utils.RollappConfig) error { stderrStr := stderr.String() if len(stderrStr) > 0 { if strings.Contains(stderrStr, "key not found") { @@ -83,7 +83,7 @@ type Response struct { RawLog string `json:"raw_log"` } -func handleStdOut(stdout bytes.Buffer, rollappConfig initconfig.InitConfig) error { +func handleStdOut(stdout bytes.Buffer, rollappConfig utils.RollappConfig) error { var response Response err := json.NewDecoder(&stdout).Decode(&response) @@ -98,6 +98,6 @@ func handleStdOut(stdout bytes.Buffer, rollappConfig initconfig.InitConfig) erro return nil } -func printRegisterOutput(rollappConfig initconfig.InitConfig) { +func printRegisterOutput(rollappConfig utils.RollappConfig) { fmt.Printf("šŸ’ˆ Rollapp '%s' has been successfully registered on the hub.\n", rollappConfig.RollappID) } diff --git a/cmd/relayer/relayer.go b/cmd/relayer/relayer.go new file mode 100644 index 00000000..5db4c7fe --- /dev/null +++ b/cmd/relayer/relayer.go @@ -0,0 +1,15 @@ +package relayer + +import ( + start "github.com/dymensionxyz/roller/cmd/relayer/start" + "github.com/spf13/cobra" +) + +func Cmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "relayer", + Short: "Commands for running and managing the RollApp relayer.", + } + cmd.AddCommand(start.Start()) + return cmd +} diff --git a/cmd/relayer/start/start.go b/cmd/relayer/start/start.go new file mode 100644 index 00000000..db32a174 --- /dev/null +++ b/cmd/relayer/start/start.go @@ -0,0 +1,37 @@ +package start + +import ( + "fmt" + "github.com/dymensionxyz/roller/cmd/consts" + "github.com/dymensionxyz/roller/cmd/utils" + "github.com/spf13/cobra" + "os/exec" + "path/filepath" +) + +func Start() *cobra.Command { + registerCmd := &cobra.Command{ + Use: "start", + Short: "Starts a relayer between the Dymension hub and the rollapp.", + Run: func(cmd *cobra.Command, args []string) { + home := cmd.Flag(utils.FlagNames.Home).Value.String() + rollappConfig, err := utils.LoadConfigFromTOML(home) + utils.PrettifyErrorIfExists(err) + fmt.Println(rollappConfig) + createChannelCmd := getCreateChannelCmd(rollappConfig) + err = utils.ExecBashCommandWithOSOutput(createChannelCmd) + utils.PrettifyErrorIfExists(err) + }, + } + utils.AddGlobalFlags(registerCmd) + return registerCmd +} + +func getCreateChannelCmd(rollappConfig utils.RollappConfig) *exec.Cmd { + fmt.Println("Creating IBC channel...") + relayerHome := filepath.Join(rollappConfig.Home, consts.ConfigDirName.Relayer) + defaultRlyArgs := utils.GetRelayerDefaultFlags(relayerHome) + args := []string{"transact", "link", "-t300s", consts.DefaultRelayerPath} + args = append(args, defaultRlyArgs...) + return exec.Command(consts.Executables.Relayer, args...) +} diff --git a/cmd/root.go b/cmd/root.go index 1a246d6d..2857ed6a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,6 +6,7 @@ import ( "github.com/dymensionxyz/roller/cmd/config" da_light_client "github.com/dymensionxyz/roller/cmd/da-light-client" "github.com/dymensionxyz/roller/cmd/register" + "github.com/dymensionxyz/roller/cmd/relayer" "github.com/dymensionxyz/roller/cmd/sequencer" "github.com/dymensionxyz/roller/cmd/version" "github.com/spf13/cobra" @@ -32,4 +33,5 @@ func init() { rootCmd.AddCommand(register.RegisterCmd()) rootCmd.AddCommand(da_light_client.DALightClientCmd()) rootCmd.AddCommand(sequencer.SequencerCmd()) + rootCmd.AddCommand(relayer.Cmd()) } diff --git a/cmd/run/run.go b/cmd/run/run.go new file mode 100644 index 00000000..1d787a8a --- /dev/null +++ b/cmd/run/run.go @@ -0,0 +1,89 @@ +package run + +import ( + "fmt" + "github.com/dymensionxyz/roller/cmd/consts" + "os/exec" + "path/filepath" + + "errors" + + "bytes" + + "strings" + + "github.com/dymensionxyz/roller/cmd/utils" + "github.com/spf13/cobra" +) + +const daLightClientEndpointFlag = "da-light-client-endpoint" + +func RunCmd() *cobra.Command { + runCmd := &cobra.Command{ + Use: "run", + Short: "Runs the rollapp sequencer.", + Run: func(cmd *cobra.Command, args []string) { + home := cmd.Flag(utils.FlagNames.Home).Value.String() + rollappConfig, err := utils.LoadConfigFromTOML(home) + utils.PrettifyErrorIfExists(err) + startRollappCmd := getStartRollapCmd(rollappConfig, cmd.Flag(daLightClientEndpointFlag).Value.String()) + var stderr bytes.Buffer + startRollappCmd.Stderr = &stderr + startRollappErr := startRollappCmd.Start() + if startRollappErr != nil { + errMsg := parseError(stderr.String()) + utils.PrettifyErrorIfExists(errors.New(errMsg)) + } + utils.PrettifyErrorIfExists(startRollappErr) + fmt.Println("šŸ’ˆ The Rollapp sequencer is running on your local machine!") + fmt.Println("šŸ’ˆ EVM RPC: http://0.0.0.0:8545") + fmt.Println("šŸ’ˆ Node RPC: http://0.0.0.0:26657") + fmt.Println("šŸ’ˆ Rest API: http://0.0.0.0:1317") + err = startRollappCmd.Wait() + if err != nil { + errMsg := parseError(stderr.String()) + utils.PrettifyErrorIfExists(errors.New(errMsg)) + } + }, + } + utils.AddGlobalFlags(runCmd) + addFlags(runCmd) + return runCmd +} + +func addFlags(cmd *cobra.Command) { + cmd.Flags().StringP(daLightClientEndpointFlag, "", "http://localhost:26659", "The DA light client endpoint.") +} +func parseError(errMsg string) string { + lines := strings.Split(errMsg, "\n") + if len(lines) > 0 && lines[0] == "Error: failed to initialize database: resource temporarily unavailable" { + return "The Rollapp sequencer is already running. Only one sequencer can run on the machine at any given time." + } + return errMsg +} + +func getStartRollapCmd(rollappConfig utils.RollappConfig, daEndpoint string) *exec.Cmd { + daConfig := fmt.Sprintf(`{"base_url": "%s", "timeout": 60000000000, "fee":20000, "gas_limit": 20000000, "namespace_id":[0,0,0,0,0,0,255,255]}`, daEndpoint) + rollappConfigDir := filepath.Join(rollappConfig.Home, consts.ConfigDirName.Rollapp) + settlementConfig := fmt.Sprintf(`{"node_address": "%s", "rollapp_id": "%s", "dym_account_name": "%s", "keyring_home_dir": "%s", "keyring_backend":"test", "gas_fees": "2000000udym"}`, rollappConfig.HubData.RPC_URL, rollappConfig.RollappID, + consts.KeyNames.HubSequencer, rollappConfigDir) + + return exec.Command( + rollappConfig.RollappBinary, "start", + "--dymint.aggregator", + "--json-rpc.enable", + "--json-rpc.api", "eth,txpool,personal,net,debug,web3,miner", + "--dymint.da_layer", "celestia", + "--dymint.da_config", daConfig, + "--dymint.settlement_layer", "dymension", + "--dymint.settlement_config", settlementConfig, + "--dymint.block_batch_size", "1200", + "--dymint.namespace_id", "000000000000ffff", + "--dymint.block_time", "0.2s", + "--home", rollappConfigDir, + "--log_level", "debug", + "--log-file", filepath.Join(rollappConfigDir, "rollapp.log"), + "--max-log-size", "2000", + "--module-log-level-override", "", + ) +} diff --git a/cmd/sequencer/start/start.go b/cmd/sequencer/start/start.go index b85a9bc2..55363ab2 100644 --- a/cmd/sequencer/start/start.go +++ b/cmd/sequencer/start/start.go @@ -7,7 +7,6 @@ import ( "strings" - initconfig "github.com/dymensionxyz/roller/cmd/config/init" "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/cmd/utils" "github.com/spf13/cobra" @@ -19,7 +18,7 @@ func StartCmd() *cobra.Command { Short: "Runs the rollapp sequencer.", Run: func(cmd *cobra.Command, args []string) { home := cmd.Flag(utils.FlagNames.Home).Value.String() - rollappConfig, err := initconfig.LoadConfigFromTOML(home) + rollappConfig, err := utils.LoadConfigFromTOML(home) utils.PrettifyErrorIfExists(err) LightNodeEndpoint := cmd.Flag(FlagNames.DAEndpoint).Value.String() startRollappCmd := getStartRollapCmd(rollappConfig, LightNodeEndpoint) @@ -52,7 +51,7 @@ func parseError(errMsg string) string { return errMsg } -func getStartRollapCmd(rollappConfig initconfig.InitConfig, lightNodeEndpoint string) *exec.Cmd { +func getStartRollapCmd(rollappConfig utils.RollappConfig, lightNodeEndpoint string) *exec.Cmd { daConfig := fmt.Sprintf(`{"base_url": "%s", "timeout": 60000000000, "fee":20000, "gas_limit": 20000000, "namespace_id":[0,0,0,0,0,0,255,255]}`, lightNodeEndpoint) rollappConfigDir := filepath.Join(rollappConfig.Home, consts.ConfigDirName.Rollapp) diff --git a/cmd/utils/bash_commands.go b/cmd/utils/bash_commands.go index 3d7f1880..4e4d45ca 100644 --- a/cmd/utils/bash_commands.go +++ b/cmd/utils/bash_commands.go @@ -3,6 +3,8 @@ package utils import ( "bytes" "errors" + "fmt" + "os" "os/exec" ) @@ -21,3 +23,27 @@ func RunBashCmdAsync(cmd *exec.Cmd, printOutput func(), parseError func(errMsg s PrettifyErrorIfExists(errors.New(errMsg)) } } + +func GetRelayerDefaultFlags(root string) []string { + return []string{ + "--src-port", "transfer", "--dst-port", "transfer", "--version", "ics20-1", "--home", root, + } +} + +func ExecBashCommand(cmd *exec.Cmd) (bytes.Buffer, error) { + var stderr bytes.Buffer + var stdout bytes.Buffer + cmd.Stderr = &stderr + cmd.Stdout = &stdout + err := cmd.Run() + if err != nil { + return stdout, fmt.Errorf("command execution failed: %w, stderr: %s", err, stderr.String()) + } + return stdout, nil +} + +func ExecBashCommandWithOSOutput(cmd *exec.Cmd) error { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} diff --git a/cmd/config/init/persistence_config.go b/cmd/utils/config.go similarity index 54% rename from cmd/config/init/persistence_config.go rename to cmd/utils/config.go index 63083039..a19b2566 100644 --- a/cmd/config/init/persistence_config.go +++ b/cmd/utils/config.go @@ -1,13 +1,12 @@ -package initconfig +package utils import ( + "github.com/pelletier/go-toml" "io/ioutil" "path/filepath" - - "github.com/pelletier/go-toml" ) -func WriteConfigToTOML(InitConfig InitConfig) error { +func WriteConfigToTOML(InitConfig RollappConfig) error { tomlBytes, err := toml.Marshal(InitConfig) if err != nil { return err @@ -20,8 +19,8 @@ func WriteConfigToTOML(InitConfig InitConfig) error { return nil } -func LoadConfigFromTOML(root string) (InitConfig, error) { - var config InitConfig +func LoadConfigFromTOML(root string) (RollappConfig, error) { + var config RollappConfig tomlBytes, err := ioutil.ReadFile(filepath.Join(root, RollerConfigFileName)) if err != nil { return config, err @@ -33,3 +32,20 @@ func LoadConfigFromTOML(root string) (InitConfig, error) { return config, nil } + +type RollappConfig struct { + Home string + RollappID string + RollappBinary string + Denom string + Decimals uint64 + HubData HubData +} + +const RollerConfigFileName = "config.toml" + +type HubData = struct { + API_URL string + ID string + RPC_URL string +} diff --git a/cmd/utils/error_handling.go b/cmd/utils/error_handling.go index b84c305c..9bddc232 100644 --- a/cmd/utils/error_handling.go +++ b/cmd/utils/error_handling.go @@ -1,6 +1,7 @@ package utils import ( + "github.com/fatih/color" "os" ) diff --git a/cmd/utils/keys.go b/cmd/utils/keys.go index 596464f4..4943a4d2 100644 --- a/cmd/utils/keys.go +++ b/cmd/utils/keys.go @@ -3,7 +3,6 @@ package utils import ( "bytes" "encoding/json" - "errors" "os/exec" "github.com/cosmos/cosmos-sdk/crypto/keyring" @@ -16,29 +15,26 @@ type KeyInfo struct { Address string `json:"address"` } +func ParseAddressFromOutput(output bytes.Buffer) (string, error) { + var key = &KeyInfo{} + err := json.Unmarshal(output.Bytes(), key) + if err != nil { + return "", err + } + return key.Address, nil +} + func GetCelestiaAddress(keyringDir string) (string, error) { cmd := exec.Command( consts.Executables.CelKey, "show", consts.KeyNames.DALightNode, "--node.type", "light", "--keyring-dir", keyringDir, "--keyring-backend", "test", "--output", "json", ) - - var out bytes.Buffer - var stderr bytes.Buffer - cmd.Stdout = &out - cmd.Stderr = &stderr - - err := cmd.Run() - if err != nil { - return "", errors.New(stderr.String()) - } - - var key = &KeyInfo{} - err = json.Unmarshal(out.Bytes(), key) + output, err := ExecBashCommand(cmd) if err != nil { return "", err } - - return key.Address, nil + address, err := ParseAddressFromOutput(output) + return address, err } type KeyConfig struct { @@ -78,3 +74,15 @@ func GetAddress(keyConfig KeyConfig) (string, error) { } return formattedAddress, nil } + +func MergeMaps(map1, map2 map[string]string) map[string]string { + result := make(map[string]string) + for key, value := range map1 { + result[key] = value + } + for key, value := range map2 { + result[key] = value + } + + return result +} diff --git a/test/config/init/goldens/init_with_flags/relayer/config/config.yaml b/test/config/init/goldens/init_with_flags/relayer/config/config.yaml index d5717557..2118e654 100644 --- a/test/config/init/goldens/init_with_flags/relayer/config/config.yaml +++ b/test/config/init/goldens/init_with_flags/relayer/config/config.yaml @@ -13,7 +13,7 @@ chains: account-prefix: dym keyring-backend: test gas-adjustment: 1.2 - gas-prices: 0.25udym + gas-prices: 0.0udym debug: true timeout: 10s output-format: json @@ -25,7 +25,7 @@ chains: key: relayer-rollapp-key chain-id: mars_1_1 rpc-addr: http://localhost:26657 - account-prefix: rol + account-prefix: ethm keyring-backend: test gas-adjustment: 1.2 gas-prices: 0.0udym diff --git a/test/config/init/goldens/init_without_flags/relayer/config/config.yaml b/test/config/init/goldens/init_without_flags/relayer/config/config.yaml index d5717557..2118e654 100644 --- a/test/config/init/goldens/init_without_flags/relayer/config/config.yaml +++ b/test/config/init/goldens/init_without_flags/relayer/config/config.yaml @@ -13,7 +13,7 @@ chains: account-prefix: dym keyring-backend: test gas-adjustment: 1.2 - gas-prices: 0.25udym + gas-prices: 0.0udym debug: true timeout: 10s output-format: json @@ -25,7 +25,7 @@ chains: key: relayer-rollapp-key chain-id: mars_1_1 rpc-addr: http://localhost:26657 - account-prefix: rol + account-prefix: ethm keyring-backend: test gas-adjustment: 1.2 gas-prices: 0.0udym diff --git a/test/config/init/init_test.go b/test/config/init/init_test.go index 36e8dc62..9b2e3a49 100644 --- a/test/config/init/init_test.go +++ b/test/config/init/init_test.go @@ -54,7 +54,7 @@ func TestInitCmd(t *testing.T) { assert.NoError(initCmd.Execute()) initConfig := initconfig.GetInitConfig(initCmd, []string{rollappID, denom}) assert.NoError(testutils.VerifyRollerConfig(initConfig)) - assert.NoError(os.Remove(filepath.Join(tempDir, initconfig.RollerConfigFileName))) + assert.NoError(os.Remove(filepath.Join(tempDir, utils.RollerConfigFileName))) assert.NoError(testutils.VerifyRollappKeys(tempDir)) assert.NoError(testutils.VerifyRelayerKeys(tempDir, rollappID, initConfig.HubData.ID)) assert.NoError(testutils.VerifyLightNodeKeys(tempDir)) diff --git a/test/config/init/testutils/keys.go b/test/config/init/testutils/keys.go index 0f5db9c7..fab6431d 100644 --- a/test/config/init/testutils/keys.go +++ b/test/config/init/testutils/keys.go @@ -6,10 +6,10 @@ import ( "os" + "github.com/dymensionxyz/roller/cmd/consts" "path/filepath" "regexp" - "github.com/dymensionxyz/roller/cmd/consts" - + initconfig "github.com/dymensionxyz/roller/cmd/config/init" ) @@ -81,7 +81,7 @@ func verifyAndRemoveFilePattern(pattern string, dir string) error { } func getLightNodeKeysDir(root string) string { - return filepath.Join(root, consts.ConfigDirName.DALightNode, initconfig.KeysDirName) + return filepath.Join(root, consts.ConfigDirName.DALightNode, consts.KeysDirName) } func VerifyLightNodeKeys(root string) error { @@ -95,7 +95,7 @@ func VerifyLightNodeKeys(root string) error { } func getRelayerKeysDir(root string) string { - return filepath.Join(root, consts.ConfigDirName.Relayer, initconfig.KeysDirName) + return filepath.Join(root, consts.ConfigDirName.Relayer, consts.KeysDirName) } func VerifyRelayerKeys(root string, rollappID string, hubID string) error { diff --git a/test/config/init/testutils/rollapp.go b/test/config/init/testutils/rollapp.go index e7e01151..035db6b2 100644 --- a/test/config/init/testutils/rollapp.go +++ b/test/config/init/testutils/rollapp.go @@ -1,6 +1,7 @@ package testutils import ( + "github.com/dymensionxyz/roller/cmd/utils" "path/filepath" "errors" @@ -71,8 +72,8 @@ func SanitizeGenesis(genesisPath string) error { return nil } -func VerifyRollerConfig(rollappConfig initconfig.InitConfig) error { - existingConfig, err := initconfig.LoadConfigFromTOML(rollappConfig.Home) +func VerifyRollerConfig(rollappConfig utils.RollappConfig) error { + existingConfig, err := utils.LoadConfigFromTOML(rollappConfig.Home) if err != nil { return err } From cada29074c0159963fb7e36d6eb19b3f57548538 Mon Sep 17 00:00:00 2001 From: Itay Date: Thu, 22 Jun 2023 18:58:49 +0200 Subject: [PATCH 6/7] feat: Add ability to run the relayer (#78) --- cmd/config/init/consts.go | 2 +- cmd/config/init/init.go | 7 +- cmd/config/init/keys.go | 42 +++--------- cmd/register/bash_commands.go | 11 ++-- cmd/register/register.go | 4 +- cmd/relayer/start/create_ibc_channel.go | 71 +++++++++++++++++++++ cmd/relayer/start/get_active_src_channel.go | 51 +++++++++++++++ cmd/relayer/start/get_dst_connection_id.go | 37 +++++++++++ cmd/relayer/start/start.go | 39 ++++++++--- cmd/root.go | 2 +- cmd/sequencer/start/start.go | 2 +- cmd/utils/bash_commands.go | 67 ++++++++++++++----- cmd/utils/error_handling.go | 2 +- go.sum | 4 ++ test/config/init/init_test.go | 4 +- 15 files changed, 273 insertions(+), 72 deletions(-) create mode 100644 cmd/relayer/start/create_ibc_channel.go create mode 100644 cmd/relayer/start/get_active_src_channel.go create mode 100644 cmd/relayer/start/get_dst_connection_id.go diff --git a/cmd/config/init/consts.go b/cmd/config/init/consts.go index fb705922..aa9b1203 100644 --- a/cmd/config/init/consts.go +++ b/cmd/config/init/consts.go @@ -31,7 +31,7 @@ var Hubs = map[string]utils.HubData{ }, LocalHubID: { API_URL: "http://localhost:1317", - ID: "local", + ID: "local-testnet", RPC_URL: "http://localhost:36657", }, } diff --git a/cmd/config/init/init.go b/cmd/config/init/init.go index a169732d..02ecd75e 100644 --- a/cmd/config/init/init.go +++ b/cmd/config/init/init.go @@ -2,9 +2,10 @@ package initconfig import ( "fmt" + "github.com/dymensionxyz/roller/cmd/consts" "os" + "path/filepath" - "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/cmd/utils" "github.com/spf13/cobra" ) @@ -48,9 +49,11 @@ func InitCmd() *cobra.Command { addresses, err := generateKeys(initConfig) utils.PrettifyErrorIfExists(err) utils.PrettifyErrorIfExists(initializeLightNodeConfig(initConfig)) + daAddress, err := utils.GetCelestiaAddress(filepath.Join(initConfig.Home, consts.ConfigDirName.DALightNode, consts.KeysDirName)) + utils.PrettifyErrorIfExists(err) + addresses[consts.KeyNames.DALightNode] = daAddress initializeRollappConfig(initConfig) utils.PrettifyErrorIfExists(initializeRollappGenesis(initConfig)) - utils.PrettifyErrorIfExists(utils.WriteConfigToTOML(initConfig)) printInitOutput(addresses, initConfig.RollappID) }, diff --git a/cmd/config/init/keys.go b/cmd/config/init/keys.go index 57cee5c4..28bb3b62 100644 --- a/cmd/config/init/keys.go +++ b/cmd/config/init/keys.go @@ -6,8 +6,6 @@ import ( "path/filepath" "strconv" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/cmd/utils" ) @@ -28,45 +26,21 @@ func generateSequencersKeys(initConfig utils.RollappConfig) (map[string]string, keys := getSequencerKeysConfig() addresses := make(map[string]string) for _, key := range keys { + var address string + var err error if key.Prefix == consts.AddressPrefixes.Rollapp { - address, err := createAddressBinary(key, consts.Executables.RollappEVM, initConfig.Home) - if err != nil { - return nil, err - } - addresses[key.ID] = address + address, err = createAddressBinary(key, consts.Executables.RollappEVM, initConfig.Home) } else { - keyInfo, err := createKey(key, initConfig.Home) - if err != nil { - return nil, err - } - formattedAddress, err := utils.KeyInfoToBech32Address(keyInfo, key.Prefix) - if err != nil { - return nil, err - } - addresses[key.ID] = formattedAddress + address, err = createAddressBinary(key, consts.Executables.Dymension, initConfig.Home) } + if err != nil { + return nil, err + } + addresses[key.ID] = address } return addresses, nil } -func createKey(keyConfig utils.KeyConfig, home string) (keyring.Info, error) { - kr, err := keyring.New( - "", - keyring.BackendTest, - filepath.Join(home, keyConfig.Dir), - nil, - ) - if err != nil { - return nil, err - } - bip44Params := hd.NewFundraiserParams(0, keyConfig.CoinType, 0) - info, _, err := kr.NewMnemonic(keyConfig.ID, keyring.English, bip44Params.String(), "", hd.Secp256k1) - if err != nil { - return nil, err - } - return info, nil -} - func getSequencerKeysConfig() []utils.KeyConfig { return []utils.KeyConfig{ { diff --git a/cmd/register/bash_commands.go b/cmd/register/bash_commands.go index 310a0684..366e77da 100644 --- a/cmd/register/bash_commands.go +++ b/cmd/register/bash_commands.go @@ -16,7 +16,7 @@ func getRegisterRollappCmd(rollappConfig utils.RollappConfig) *exec.Cmd { cmdArgs := []string{ "tx", "rollapp", "create-rollapp", rollappConfig.RollappID, "stamp1", "genesis-path/1", "3", "3", `{"Addresses":[]}`, } - cmdArgs = append(cmdArgs, getCommonFlags(rollappConfig)...) + cmdArgs = append(cmdArgs, getCommonDymdTxFlags(rollappConfig)...) return exec.Command( consts.Executables.Dymension, cmdArgs..., ) @@ -50,16 +50,17 @@ func getRegisterSequencerCmd(rollappConfig utils.RollappConfig) (*exec.Cmd, erro rollappConfig.RollappID, description, } - cmdArgs = append(cmdArgs, getCommonFlags(rollappConfig)...) + cmdArgs = append(cmdArgs, getCommonDymdTxFlags(rollappConfig)...) return exec.Command(consts.Executables.Dymension, cmdArgs...), nil } -func getCommonFlags(rollappConfig utils.RollappConfig) []string { - return []string{ +func getCommonDymdTxFlags(rollappConfig utils.RollappConfig) []string { + commonFlags := utils.GetCommonDymdFlags(rollappConfig) + txArgs := []string{ "--from", consts.KeyNames.HubSequencer, "--keyring-backend", "test", "--keyring-dir", filepath.Join(rollappConfig.Home, consts.ConfigDirName.Rollapp), - "--node", rollappConfig.HubData.RPC_URL, "--output", "json", "--yes", "--broadcast-mode", "block", "--chain-id", rollappConfig.HubData.ID, } + return append(commonFlags, txArgs...) } diff --git a/cmd/register/register.go b/cmd/register/register.go index a6c97d7b..a7f3ce10 100644 --- a/cmd/register/register.go +++ b/cmd/register/register.go @@ -12,12 +12,12 @@ import ( "encoding/json" initconfig "github.com/dymensionxyz/roller/cmd/config/init" - "github.com/dymensionxyz/roller/cmd/utils" "github.com/dymensionxyz/roller/cmd/consts" + "github.com/dymensionxyz/roller/cmd/utils" "github.com/spf13/cobra" ) -func RegisterCmd() *cobra.Command { +func Cmd() *cobra.Command { registerCmd := &cobra.Command{ Use: "register", Short: "Registers the rollapp and the sequencer to the Dymension hub.", diff --git a/cmd/relayer/start/create_ibc_channel.go b/cmd/relayer/start/create_ibc_channel.go new file mode 100644 index 00000000..9b860c01 --- /dev/null +++ b/cmd/relayer/start/create_ibc_channel.go @@ -0,0 +1,71 @@ +package start + +import ( + "fmt" + "github.com/dymensionxyz/roller/cmd/consts" + "github.com/dymensionxyz/roller/cmd/utils" + "os/exec" + "path/filepath" +) + +// Creates an IBC channel between the hub and the client, and return the source channel ID. +func createIBCChannelIfNeeded(rollappConfig utils.RollappConfig) (string, error) { + createClientsCmd := getCreateClientsCmd(rollappConfig, rollappConfig.RollappID, rollappConfig.HubData.ID) + fmt.Println("Creating clients...") + if err := utils.ExecBashCmdWithOSOutput(createClientsCmd); err != nil { + return "", err + } + dstConnectionId, err := GetDstConnectionIDFromYAMLFile(filepath.Join(rollappConfig.Home, consts.ConfigDirName.Relayer, + "config", "config.yaml")) + if err != nil { + return "", err + } + if dstConnectionId == "" { + createConnectionCmd := getCreateConnectionCmd(rollappConfig) + fmt.Println("Creating connection...") + if err := utils.ExecBashCmdWithOSOutput(createConnectionCmd); err != nil { + return "", err + } + } + srcChannelId, err := GetSourceChannelForConnection(dstConnectionId, rollappConfig) + if err != nil { + return "", err + } + if srcChannelId == "" { + createChannelCmd := getCreateChannelCmd(rollappConfig) + fmt.Println("Creating channel...") + if err := utils.ExecBashCmdWithOSOutput(createChannelCmd); err != nil { + return "", err + } + srcChannelId, err = GetSourceChannelForConnection(dstConnectionId, rollappConfig) + if err != nil { + return "", err + } + } + return srcChannelId, nil +} + +func getCreateChannelCmd(config utils.RollappConfig) *exec.Cmd { + defaultRlyArgs := getRelayerDefaultArgs(config) + args := []string{"tx", "channel", "--override"} + args = append(args, defaultRlyArgs...) + return exec.Command(consts.Executables.Relayer, args...) +} + +func getCreateClientsCmd(rollappConfig utils.RollappConfig, srcId string, dstId string) *exec.Cmd { + defaultRlyArgs := getRelayerDefaultArgs(rollappConfig) + args := []string{"tx", "clients"} + args = append(args, defaultRlyArgs...) + return exec.Command(consts.Executables.Relayer, args...) +} + +func getRelayerDefaultArgs(config utils.RollappConfig) []string { + return []string{consts.DefaultRelayerPath, "--home", filepath.Join(config.Home, consts.ConfigDirName.Relayer)} +} + +func getCreateConnectionCmd(config utils.RollappConfig) *exec.Cmd { + defaultRlyArgs := getRelayerDefaultArgs(config) + args := []string{"tx", "connection"} + args = append(args, defaultRlyArgs...) + return exec.Command(consts.Executables.Relayer, args...) +} diff --git a/cmd/relayer/start/get_active_src_channel.go b/cmd/relayer/start/get_active_src_channel.go new file mode 100644 index 00000000..98663b24 --- /dev/null +++ b/cmd/relayer/start/get_active_src_channel.go @@ -0,0 +1,51 @@ +package start + +import ( + "encoding/json" + "github.com/dymensionxyz/roller/cmd/consts" + "github.com/dymensionxyz/roller/cmd/utils" + "os/exec" +) + +// GetSourceChannelForConnection Returns the open source channel for the given destination connection ID. If no open channel exists, it returns an +// empty string. +func GetSourceChannelForConnection(dstConnectionID string, rollappConfig utils.RollappConfig) (string, error) { + commonDymdFlags := utils.GetCommonDymdFlags(rollappConfig) + args := []string{"query", "ibc", "channel", "connections", dstConnectionID} + args = append(args, commonDymdFlags...) + cmd := exec.Command(consts.Executables.Dymension, args...) + out, err := cmd.Output() + if err != nil { + return "", err + } + channelId, err := GetOpenStateChannelID(out) + if err != nil { + return "", err + } + return channelId, nil +} + +type Channel struct { + State string `json:"state"` + Counterparty struct { + ChannelID string `json:"channel_id"` + } `json:"counterparty"` +} + +type ChannelList struct { + Channels []Channel `json:"channels"` +} + +func GetOpenStateChannelID(jsonData []byte) (string, error) { + var channels ChannelList + if err := json.Unmarshal(jsonData, &channels); err != nil { + return "", err + } + + for _, channel := range channels.Channels { + if channel.State == "STATE_OPEN" { + return channel.Counterparty.ChannelID, nil + } + } + return "", nil +} diff --git a/cmd/relayer/start/get_dst_connection_id.go b/cmd/relayer/start/get_dst_connection_id.go new file mode 100644 index 00000000..7bee7025 --- /dev/null +++ b/cmd/relayer/start/get_dst_connection_id.go @@ -0,0 +1,37 @@ +package start + +import ( + "fmt" + "gopkg.in/yaml.v2" + "io/ioutil" +) + +type RelayerConfigFile struct { + Paths map[string]Path `yaml:"paths"` +} + +type Path struct { + Dst Destination `yaml:"dst"` +} + +type Destination struct { + ConnectionID string `yaml:"connection-id"` +} + +// GetDstConnectionIDFromYAMLFile Returns the destination connection ID if it been created already, an empty string otherwise. +func GetDstConnectionIDFromYAMLFile(filename string) (string, error) { + + data, err := ioutil.ReadFile(filename) + if err != nil { + return "", err + } + var config RelayerConfigFile + err = yaml.Unmarshal(data, &config) + if err != nil { + return "", err + } + for _, path := range config.Paths { + return path.Dst.ConnectionID, nil + } + return "", fmt.Errorf("No paths found in YAML data") +} diff --git a/cmd/relayer/start/start.go b/cmd/relayer/start/start.go index db32a174..65d38b1e 100644 --- a/cmd/relayer/start/start.go +++ b/cmd/relayer/start/start.go @@ -9,6 +9,10 @@ import ( "path/filepath" ) +type RelayerConfig struct { + SrcChannelName string +} + func Start() *cobra.Command { registerCmd := &cobra.Command{ Use: "start", @@ -17,21 +21,40 @@ func Start() *cobra.Command { home := cmd.Flag(utils.FlagNames.Home).Value.String() rollappConfig, err := utils.LoadConfigFromTOML(home) utils.PrettifyErrorIfExists(err) - fmt.Println(rollappConfig) - createChannelCmd := getCreateChannelCmd(rollappConfig) - err = utils.ExecBashCommandWithOSOutput(createChannelCmd) + srcChannelId, err := createIBCChannelIfNeeded(rollappConfig) utils.PrettifyErrorIfExists(err) + updateClientsCmd := getUpdateClientsCmd(rollappConfig) + utils.RunCommandEvery(updateClientsCmd.Path, updateClientsCmd.Args[1:], 60) + relayPacketsCmd := getRelayPacketsCmd(rollappConfig, srcChannelId) + utils.RunCommandEvery(relayPacketsCmd.Path, relayPacketsCmd.Args[1:], 30) + startCmd := getRlyStartCmd(rollappConfig) + utils.RunBashCmdAsync(startCmd, func() { + fmt.Printf("šŸ’ˆ The relayer is running successfully on you local machine on channel %s!", srcChannelId) + }, parseError) }, } utils.AddGlobalFlags(registerCmd) return registerCmd } -func getCreateChannelCmd(rollappConfig utils.RollappConfig) *exec.Cmd { - fmt.Println("Creating IBC channel...") - relayerHome := filepath.Join(rollappConfig.Home, consts.ConfigDirName.Relayer) - defaultRlyArgs := utils.GetRelayerDefaultFlags(relayerHome) - args := []string{"transact", "link", "-t300s", consts.DefaultRelayerPath} +func parseError(errStr string) string { + // TODO + return errStr +} + +func getRlyStartCmd(config utils.RollappConfig) *exec.Cmd { + return exec.Command(consts.Executables.Relayer, "start", consts.DefaultRelayerPath, "-l", "1", "--home", + filepath.Join(config.Home, consts.ConfigDirName.Relayer)) +} + +func getUpdateClientsCmd(config utils.RollappConfig) *exec.Cmd { + defaultRlyArgs := getRelayerDefaultArgs(config) + args := []string{"tx", "update-clients"} args = append(args, defaultRlyArgs...) return exec.Command(consts.Executables.Relayer, args...) } + +func getRelayPacketsCmd(config utils.RollappConfig, srcChannel string) *exec.Cmd { + return exec.Command(consts.Executables.Relayer, "tx", "relay-packets", consts.DefaultRelayerPath, srcChannel, + "-l", "1", "--home", filepath.Join(config.Home, consts.ConfigDirName.Relayer)) +} diff --git a/cmd/root.go b/cmd/root.go index 2857ed6a..7d7611c8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -30,7 +30,7 @@ func Execute() { func init() { rootCmd.AddCommand(config.ConfigCmd()) rootCmd.AddCommand(version.VersionCmd()) - rootCmd.AddCommand(register.RegisterCmd()) + rootCmd.AddCommand(register.Cmd()) rootCmd.AddCommand(da_light_client.DALightClientCmd()) rootCmd.AddCommand(sequencer.SequencerCmd()) rootCmd.AddCommand(relayer.Cmd()) diff --git a/cmd/sequencer/start/start.go b/cmd/sequencer/start/start.go index 55363ab2..2cb3e0d5 100644 --- a/cmd/sequencer/start/start.go +++ b/cmd/sequencer/start/start.go @@ -68,7 +68,7 @@ func getStartRollapCmd(rollappConfig utils.RollappConfig, lightNodeEndpoint stri "--dymint.da_config", daConfig, "--dymint.settlement_layer", "dymension", "--dymint.settlement_config", settlementConfig, - "--dymint.block_batch_size", "1200", + "--dymint.block_batch_size", "50", "--dymint.namespace_id", "000000000000ffff", "--dymint.block_time", "0.2s", "--home", rollappConfigDir, diff --git a/cmd/utils/bash_commands.go b/cmd/utils/bash_commands.go index 4e4d45ca..250147f1 100644 --- a/cmd/utils/bash_commands.go +++ b/cmd/utils/bash_commands.go @@ -4,29 +4,38 @@ import ( "bytes" "errors" "fmt" + "io" "os" "os/exec" + "strings" + "time" ) -func RunBashCmdAsync(cmd *exec.Cmd, printOutput func(), parseError func(errMsg string) string) { - var stderr bytes.Buffer - cmd.Stderr = &stderr - err := cmd.Start() - if err != nil { - errMsg := parseError(stderr.String()) - PrettifyErrorIfExists(errors.New(errMsg)) - } - printOutput() - err = cmd.Wait() - if err != nil { - errMsg := parseError(stderr.String()) - PrettifyErrorIfExists(errors.New(errMsg)) +func GetRelayerDefaultFlags(root string) []string { + return []string{ + "--src-port", "transfer", "--dst-port", "transfer", "--version", "ics20-1", "--home", root, } } -func GetRelayerDefaultFlags(root string) []string { +func RunCommandEvery(command string, args []string, intervalSec int) { + go func() { + for { + cmd := exec.Command(command, args...) + var stderr bytes.Buffer + cmd.Stderr = &stderr + err := cmd.Run() + if err != nil { + // get the cmd args joined by space + fmt.Println("Cron command "+strings.Join(cmd.Args, " ")+" exited with error: ", stderr.String()) + } + time.Sleep(time.Duration(intervalSec) * time.Second) + } + }() +} + +func GetCommonDymdFlags(rollappConfig RollappConfig) []string { return []string{ - "--src-port", "transfer", "--dst-port", "transfer", "--version", "ics20-1", "--home", root, + "--node", rollappConfig.HubData.RPC_URL, "--output", "json", } } @@ -47,3 +56,31 @@ func ExecBashCommandWithOSOutput(cmd *exec.Cmd) error { cmd.Stderr = os.Stderr return cmd.Run() } + +func RunBashCmdAsync(cmd *exec.Cmd, printOutput func(), parseError func(errMsg string) string) { + var stderr bytes.Buffer + cmd.Stderr = &stderr + err := cmd.Start() + if err != nil { + errMsg := parseError(stderr.String()) + PrettifyErrorIfExists(errors.New(errMsg)) + } + printOutput() + err = cmd.Wait() + if err != nil { + errMsg := parseError(stderr.String()) + PrettifyErrorIfExists(errors.New(errMsg)) + } +} + +func ExecBashCmdWithOSOutput(cmd *exec.Cmd) error { + var stderr bytes.Buffer + cmd.Stdout = os.Stdout + mw := io.MultiWriter(os.Stderr, &stderr) + cmd.Stderr = mw + err := cmd.Run() + if err != nil { + return fmt.Errorf("command execution failed: %w, stderr: %s", err, stderr.String()) + } + return nil +} diff --git a/cmd/utils/error_handling.go b/cmd/utils/error_handling.go index 9bddc232..9eaa8ac0 100644 --- a/cmd/utils/error_handling.go +++ b/cmd/utils/error_handling.go @@ -1,9 +1,9 @@ package utils import ( + "os" "github.com/fatih/color" - "os" ) func PrettifyErrorIfExists(err error) { diff --git a/go.sum b/go.sum index 7050c3b0..72f77030 100644 --- a/go.sum +++ b/go.sum @@ -99,6 +99,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/confio/ics23/go v0.7.0 h1:00d2kukk7sPoHWL4zZBZwzxnpA2pec1NPdwbSokJ5w8= github.com/confio/ics23/go v0.7.0/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -144,6 +146,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= @@ -456,6 +459,7 @@ github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= diff --git a/test/config/init/init_test.go b/test/config/init/init_test.go index 9b2e3a49..ef46cb65 100644 --- a/test/config/init/init_test.go +++ b/test/config/init/init_test.go @@ -59,9 +59,9 @@ func TestInitCmd(t *testing.T) { assert.NoError(testutils.VerifyRelayerKeys(tempDir, rollappID, initConfig.HubData.ID)) assert.NoError(testutils.VerifyLightNodeKeys(tempDir)) assert.NoError(testutils.ClearKeys(tempDir)) - are_dirs_equal, err := testutils.CompareDirs(tempDir, tc.goldenDirPath) + areDirsEqual, err := testutils.CompareDirs(tempDir, tc.goldenDirPath) assert.NoError(err) - assert.True(are_dirs_equal) + assert.True(areDirsEqual) }) } } From b4c875e2508713204adf6c3507713903bc1258d9 Mon Sep 17 00:00:00 2001 From: Itay Date: Sun, 25 Jun 2023 10:55:09 +0200 Subject: [PATCH 7/7] feat: Add ability to list roller addresses with `roller keys list` command (#83) --- cmd/config/init/init.go | 6 +- cmd/config/init/keys.go | 14 ++--- cmd/config/init/output.go | 23 +------- cmd/config/init/rollapp.go | 3 +- cmd/consts/consts.go | 2 + cmd/keys/keys.go | 15 +++++ cmd/keys/list/list.go | 45 +++++++++++++++ cmd/register/bash_commands.go | 2 +- cmd/register/register.go | 11 ++-- cmd/root.go | 2 + cmd/sequencer/start/start.go | 4 +- cmd/utils/error_handling.go | 3 +- cmd/utils/keys.go | 80 ++++++++++++++++----------- test/config/init/testutils/keys.go | 2 +- test/config/init/testutils/rollapp.go | 19 +++++-- 15 files changed, 149 insertions(+), 82 deletions(-) create mode 100644 cmd/keys/keys.go create mode 100644 cmd/keys/list/list.go diff --git a/cmd/config/init/init.go b/cmd/config/init/init.go index 02ecd75e..fbde94a9 100644 --- a/cmd/config/init/init.go +++ b/cmd/config/init/init.go @@ -3,11 +3,9 @@ package initconfig import ( "fmt" "github.com/dymensionxyz/roller/cmd/consts" - "os" - "path/filepath" - "github.com/dymensionxyz/roller/cmd/utils" "github.com/spf13/cobra" + "os" ) func InitCmd() *cobra.Command { @@ -49,7 +47,7 @@ func InitCmd() *cobra.Command { addresses, err := generateKeys(initConfig) utils.PrettifyErrorIfExists(err) utils.PrettifyErrorIfExists(initializeLightNodeConfig(initConfig)) - daAddress, err := utils.GetCelestiaAddress(filepath.Join(initConfig.Home, consts.ConfigDirName.DALightNode, consts.KeysDirName)) + daAddress, err := utils.GetCelestiaAddress(initConfig.Home) utils.PrettifyErrorIfExists(err) addresses[consts.KeyNames.DALightNode] = daAddress initializeRollappConfig(initConfig) diff --git a/cmd/config/init/keys.go b/cmd/config/init/keys.go index 28bb3b62..9ea06844 100644 --- a/cmd/config/init/keys.go +++ b/cmd/config/init/keys.go @@ -41,10 +41,10 @@ func generateSequencersKeys(initConfig utils.RollappConfig) (map[string]string, return addresses, nil } -func getSequencerKeysConfig() []utils.KeyConfig { - return []utils.KeyConfig{ +func getSequencerKeysConfig() []utils.CreateKeyConfig { + return []utils.CreateKeyConfig{ { - Dir: consts.ConfigDirName.Rollapp, + Dir: consts.ConfigDirName.HubKeys, ID: consts.KeyNames.HubSequencer, CoinType: consts.CoinTypes.Cosmos, Prefix: consts.AddressPrefixes.Hub, @@ -58,8 +58,8 @@ func getSequencerKeysConfig() []utils.KeyConfig { } } -func getRelayerKeysConfig(rollappConfig utils.RollappConfig) map[string]utils.KeyConfig { - return map[string]utils.KeyConfig{ +func getRelayerKeysConfig(rollappConfig utils.RollappConfig) map[string]utils.CreateKeyConfig { + return map[string]utils.CreateKeyConfig{ consts.KeyNames.RollappRelayer: { Dir: path.Join(rollappConfig.Home, consts.ConfigDirName.Relayer), ID: consts.KeyNames.RollappRelayer, @@ -75,7 +75,7 @@ func getRelayerKeysConfig(rollappConfig utils.RollappConfig) map[string]utils.Ke } } -func createAddressBinary(keyConfig utils.KeyConfig, binaryPath string, home string) (string, error) { +func createAddressBinary(keyConfig utils.CreateKeyConfig, binaryPath string, home string) (string, error) { createKeyCommand := exec.Command(binaryPath, "keys", "add", keyConfig.ID, "--keyring-backend", "test", "--keyring-dir", filepath.Join(home, keyConfig.Dir), "--output", "json") out, err := utils.ExecBashCommand(createKeyCommand) @@ -111,7 +111,7 @@ func generateRelayerKeys(rollappConfig utils.RollappConfig) (map[string]string, return relayerAddresses, err } -func getAddRlyKeyCmd(keyConfig utils.KeyConfig, chainID string) *exec.Cmd { +func getAddRlyKeyCmd(keyConfig utils.CreateKeyConfig, chainID string) *exec.Cmd { return exec.Command( consts.Executables.Relayer, consts.KeysDirName, diff --git a/cmd/config/init/output.go b/cmd/config/init/output.go index bb87d86e..ae0f5745 100644 --- a/cmd/config/init/output.go +++ b/cmd/config/init/output.go @@ -2,30 +2,11 @@ package initconfig import ( "fmt" - "os" - - "github.com/dymensionxyz/roller/cmd/consts" - "github.com/olekukonko/tablewriter" + "github.com/dymensionxyz/roller/cmd/utils" ) func printInitOutput(addresses map[string]string, rollappId string) { 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[consts.KeyNames.DALightNode]}, - {"Sequencer", addresses[consts.KeyNames.HubSequencer]}, - {"Relayer, Hub", addresses[consts.KeyNames.HubRelayer]}, - {"Relayer, RollApp", addresses[consts.KeyNames.RollappRelayer]}, - } - - table := tablewriter.NewWriter(os.Stdout) - table.SetAlignment(tablewriter.ALIGN_LEFT) - table.SetHeaderAlignment(tablewriter.ALIGN_LEFT) - table.SetBorder(false) - table.AppendBulk(data) - table.Render() - + utils.PrintAddresses(addresses) fmt.Printf("\nšŸ”” Please fund these addresses to register and run the rollapp.\n") } diff --git a/cmd/config/init/rollapp.go b/cmd/config/init/rollapp.go index 10f1c3b3..9879c9d0 100644 --- a/cmd/config/init/rollapp.go +++ b/cmd/config/init/rollapp.go @@ -11,7 +11,8 @@ import ( ) func initializeRollappConfig(initConfig utils.RollappConfig) { - initRollappCmd := exec.Command(initConfig.RollappBinary, "init", consts.KeyNames.HubSequencer, "--chain-id", initConfig.RollappID, "--home", filepath.Join(initConfig.Home, consts.ConfigDirName.Rollapp)) + initRollappCmd := exec.Command(initConfig.RollappBinary, "init", consts.KeyNames.HubSequencer, "--chain-id", + initConfig.RollappID, "--home", filepath.Join(initConfig.Home, consts.ConfigDirName.Rollapp)) err := initRollappCmd.Run() if err != nil { panic(err) diff --git a/cmd/consts/consts.go b/cmd/consts/consts.go index 57d5ae59..0c3c685f 100644 --- a/cmd/consts/consts.go +++ b/cmd/consts/consts.go @@ -48,10 +48,12 @@ var ConfigDirName = struct { Rollapp string Relayer string DALightNode string + HubKeys string }{ Rollapp: "rollapp", Relayer: "relayer", DALightNode: "da-light-node", + HubKeys: "hub-keys", } var CoinTypes = struct { diff --git a/cmd/keys/keys.go b/cmd/keys/keys.go new file mode 100644 index 00000000..edf58bf8 --- /dev/null +++ b/cmd/keys/keys.go @@ -0,0 +1,15 @@ +package keys + +import ( + "github.com/dymensionxyz/roller/cmd/keys/list" + "github.com/spf13/cobra" +) + +func Cmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "keys", + Short: "Commands for managing the roller different keys.", + } + cmd.AddCommand(list.Cmd()) + return cmd +} diff --git a/cmd/keys/list/list.go b/cmd/keys/list/list.go new file mode 100644 index 00000000..a3d324d8 --- /dev/null +++ b/cmd/keys/list/list.go @@ -0,0 +1,45 @@ +package list + +import ( + "github.com/dymensionxyz/roller/cmd/consts" + "github.com/dymensionxyz/roller/cmd/utils" + "github.com/spf13/cobra" + "path/filepath" +) + +func Cmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "list", + Short: "List all the addresses of roller on the local machine.", + Run: func(cmd *cobra.Command, args []string) { + home := cmd.Flag(utils.FlagNames.Home).Value.String() + rollappConfig, err := utils.LoadConfigFromTOML(home) + utils.PrettifyErrorIfExists(err) + daAddr, err := utils.GetCelestiaAddress(rollappConfig.Home) + utils.PrettifyErrorIfExists(err) + addresses := map[string]string{} + addresses[consts.KeyNames.DALightNode] = daAddr + hubSeqAddr, err := utils.GetAddressBinary(utils.GetKeyConfig{ + Dir: filepath.Join(rollappConfig.Home, consts.ConfigDirName.HubKeys), + ID: consts.KeyNames.HubSequencer, + }, consts.Executables.Dymension) + utils.PrettifyErrorIfExists(err) + addresses[consts.KeyNames.HubSequencer] = hubSeqAddr + rollappSeqAddr, err := utils.GetAddressBinary(utils.GetKeyConfig{ + Dir: filepath.Join(rollappConfig.Home, consts.ConfigDirName.Rollapp), + ID: consts.KeyNames.RollappSequencer, + }, consts.Executables.RollappEVM) + utils.PrettifyErrorIfExists(err) + addresses[consts.KeyNames.RollappSequencer] = rollappSeqAddr + hubRlyAddr, err := utils.GetRelayerAddress(rollappConfig.Home, rollappConfig.HubData.ID) + utils.PrettifyErrorIfExists(err) + addresses[consts.KeyNames.HubRelayer] = hubRlyAddr + rollappRlyAddr, err := utils.GetRelayerAddress(rollappConfig.Home, rollappConfig.RollappID) + utils.PrettifyErrorIfExists(err) + addresses[consts.KeyNames.RollappRelayer] = rollappRlyAddr + utils.PrintAddresses(addresses) + }, + } + utils.AddGlobalFlags(cmd) + return cmd +} diff --git a/cmd/register/bash_commands.go b/cmd/register/bash_commands.go index 366e77da..f770de23 100644 --- a/cmd/register/bash_commands.go +++ b/cmd/register/bash_commands.go @@ -59,7 +59,7 @@ func getCommonDymdTxFlags(rollappConfig utils.RollappConfig) []string { txArgs := []string{ "--from", consts.KeyNames.HubSequencer, "--keyring-backend", "test", - "--keyring-dir", filepath.Join(rollappConfig.Home, consts.ConfigDirName.Rollapp), + "--keyring-dir", filepath.Join(rollappConfig.Home, consts.ConfigDirName.HubKeys), "--yes", "--broadcast-mode", "block", "--chain-id", rollappConfig.HubData.ID, } return append(commonFlags, txArgs...) diff --git a/cmd/register/register.go b/cmd/register/register.go index a7f3ce10..3c64e038 100644 --- a/cmd/register/register.go +++ b/cmd/register/register.go @@ -61,13 +61,12 @@ func handleStdErr(stderr bytes.Buffer, rollappConfig utils.RollappConfig) error stderrStr := stderr.String() if len(stderrStr) > 0 { if strings.Contains(stderrStr, "key not found") { - sequencerAddress, err := utils.GetAddress( - utils.KeyConfig{ - ID: consts.KeyNames.HubSequencer, - Prefix: consts.AddressPrefixes.Hub, - Dir: filepath.Join(rollappConfig.Home, consts.ConfigDirName.Rollapp), - CoinType: consts.CoinTypes.Cosmos, + sequencerAddress, err := utils.GetAddressBinary( + utils.GetKeyConfig{ + ID: consts.KeyNames.HubSequencer, + Dir: filepath.Join(rollappConfig.Home, consts.ConfigDirName.HubKeys), }, + consts.Executables.Dymension, ) if err != nil { return err diff --git a/cmd/root.go b/cmd/root.go index 7d7611c8..7d5b4a4c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -5,6 +5,7 @@ import ( "github.com/dymensionxyz/roller/cmd/config" da_light_client "github.com/dymensionxyz/roller/cmd/da-light-client" + "github.com/dymensionxyz/roller/cmd/keys" "github.com/dymensionxyz/roller/cmd/register" "github.com/dymensionxyz/roller/cmd/relayer" "github.com/dymensionxyz/roller/cmd/sequencer" @@ -34,4 +35,5 @@ func init() { rootCmd.AddCommand(da_light_client.DALightClientCmd()) rootCmd.AddCommand(sequencer.SequencerCmd()) rootCmd.AddCommand(relayer.Cmd()) + rootCmd.AddCommand(keys.Cmd()) } diff --git a/cmd/sequencer/start/start.go b/cmd/sequencer/start/start.go index 2cb3e0d5..9cd93516 100644 --- a/cmd/sequencer/start/start.go +++ b/cmd/sequencer/start/start.go @@ -55,9 +55,11 @@ func getStartRollapCmd(rollappConfig utils.RollappConfig, lightNodeEndpoint stri daConfig := fmt.Sprintf(`{"base_url": "%s", "timeout": 60000000000, "fee":20000, "gas_limit": 20000000, "namespace_id":[0,0,0,0,0,0,255,255]}`, lightNodeEndpoint) rollappConfigDir := filepath.Join(rollappConfig.Home, consts.ConfigDirName.Rollapp) + hubKeysDir := filepath.Join(rollappConfig.Home, consts.ConfigDirName.HubKeys) // TODO: Update the gas_fees to 2000000udym before 35-c launch. - settlementConfig := fmt.Sprintf(`{"node_address": "%s", "rollapp_id": "%s", "dym_account_name": "%s", "keyring_home_dir": "%s", "keyring_backend":"test", "gas_fees": "0udym"}`, rollappConfig.HubData.RPC_URL, rollappConfig.RollappID, consts.KeyNames.HubSequencer, rollappConfigDir) + settlementConfig := fmt.Sprintf(`{"node_address": "%s", "rollapp_id": "%s", "dym_account_name": "%s", "keyring_home_dir": "%s", "keyring_backend":"test", "gas_fees": "0udym"}`, + rollappConfig.HubData.RPC_URL, rollappConfig.RollappID, consts.KeyNames.HubSequencer, hubKeysDir) return exec.Command( rollappConfig.RollappBinary, "start", diff --git a/cmd/utils/error_handling.go b/cmd/utils/error_handling.go index 9eaa8ac0..b84c305c 100644 --- a/cmd/utils/error_handling.go +++ b/cmd/utils/error_handling.go @@ -1,9 +1,8 @@ package utils import ( - "os" - "github.com/fatih/color" + "os" ) func PrettifyErrorIfExists(err error) { diff --git a/cmd/utils/keys.go b/cmd/utils/keys.go index 4943a4d2..b673539b 100644 --- a/cmd/utils/keys.go +++ b/cmd/utils/keys.go @@ -3,11 +3,13 @@ package utils import ( "bytes" "encoding/json" + "fmt" + "github.com/olekukonko/tablewriter" + "os" "os/exec" + "path/filepath" + "strings" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/bech32" "github.com/dymensionxyz/roller/cmd/consts" ) @@ -24,10 +26,11 @@ func ParseAddressFromOutput(output bytes.Buffer) (string, error) { return key.Address, nil } -func GetCelestiaAddress(keyringDir string) (string, error) { +func GetCelestiaAddress(rollerRoot string) (string, error) { + daKeysDir := filepath.Join(rollerRoot, consts.ConfigDirName.DALightNode, consts.KeysDirName) cmd := exec.Command( - consts.Executables.CelKey, - "show", consts.KeyNames.DALightNode, "--node.type", "light", "--keyring-dir", keyringDir, "--keyring-backend", "test", "--output", "json", + consts.Executables.CelKey, "show", consts.KeyNames.DALightNode, "--node.type", "light", "--keyring-dir", + daKeysDir, "--keyring-backend", "test", "--output", "json", ) output, err := ExecBashCommand(cmd) if err != nil { @@ -37,42 +40,28 @@ func GetCelestiaAddress(keyringDir string) (string, error) { return address, err } -type KeyConfig struct { +type GetKeyConfig struct { + Dir string + ID string +} + +type CreateKeyConfig struct { Dir string ID string CoinType uint32 Prefix string } -func KeyInfoToBech32Address(info keyring.Info, prefix string) (string, error) { - pk := info.GetPubKey() - addr := types.AccAddress(pk.Address()) - bech32Address, err := bech32.ConvertAndEncode(prefix, addr.Bytes()) - if err != nil { - return "", err - } - return bech32Address, nil -} - -func GetAddress(keyConfig KeyConfig) (string, error) { - kr, err := keyring.New( - "", - keyring.BackendTest, - keyConfig.Dir, - nil, +func GetAddressBinary(keyConfig GetKeyConfig, binaryPath string) (string, error) { + showKeyCommand := exec.Command( + binaryPath, "keys", "show", keyConfig.ID, "--keyring-backend", "test", "--keyring-dir", keyConfig.Dir, + "--output", "json", ) + output, err := ExecBashCommand(showKeyCommand) if err != nil { return "", err } - keyInfo, err := kr.Key(keyConfig.ID) - if err != nil { - return "", err - } - formattedAddress, err := KeyInfoToBech32Address(keyInfo, keyConfig.Prefix) - if err != nil { - return "", err - } - return formattedAddress, nil + return ParseAddressFromOutput(output) } func MergeMaps(map1, map2 map[string]string) map[string]string { @@ -86,3 +75,30 @@ func MergeMaps(map1, map2 map[string]string) map[string]string { return result } + +func GetRelayerAddress(home string, chainID string) (string, error) { + showKeyCmd := exec.Command( + consts.Executables.Relayer, "keys", "show", chainID, "--home", filepath.Join(home, consts.ConfigDirName.Relayer), + ) + out, err := ExecBashCommand(showKeyCmd) + return strings.TrimSuffix(out.String(), "\n"), err +} + +func PrintAddresses(addresses map[string]string) { + fmt.Printf("šŸ”‘ Addresses:\n\n") + + data := [][]string{ + {"Celestia", addresses[consts.KeyNames.DALightNode]}, + {"Sequencer, Hub", addresses[consts.KeyNames.HubSequencer]}, + {"Sequencer, Rollapp", addresses[consts.KeyNames.RollappSequencer]}, + {"Relayer, Hub", addresses[consts.KeyNames.HubRelayer]}, + {"Relayer, RollApp", addresses[consts.KeyNames.RollappRelayer]}, + } + + table := tablewriter.NewWriter(os.Stdout) + table.SetAlignment(tablewriter.ALIGN_LEFT) + table.SetHeaderAlignment(tablewriter.ALIGN_LEFT) + table.SetBorder(false) + table.AppendBulk(data) + table.Render() +} diff --git a/test/config/init/testutils/keys.go b/test/config/init/testutils/keys.go index fab6431d..ce07c41b 100644 --- a/test/config/init/testutils/keys.go +++ b/test/config/init/testutils/keys.go @@ -17,7 +17,7 @@ const innerKeysDirName = "keyring-test" const addressPattern = `.*\.address` func ClearKeys(root string) error { - keyDirs := []string{getLightNodeKeysDir(root), getRelayerKeysDir(root), getRollappKeysDir(root)} + keyDirs := []string{getLightNodeKeysDir(root), getRelayerKeysDir(root), getRollappKeysDir(root), getHubKeysDir(root)} for _, dir := range keyDirs { if err := os.RemoveAll(dir); err != nil { return err diff --git a/test/config/init/testutils/rollapp.go b/test/config/init/testutils/rollapp.go index 035db6b2..a848c0dd 100644 --- a/test/config/init/testutils/rollapp.go +++ b/test/config/init/testutils/rollapp.go @@ -14,21 +14,28 @@ func getRollappKeysDir(root string) string { return filepath.Join(root, consts.ConfigDirName.Rollapp, innerKeysDirName) } +func getHubKeysDir(root string) string { + return filepath.Join(root, consts.ConfigDirName.HubKeys, innerKeysDirName) +} + func VerifyRollappKeys(root string) error { rollappKeysDir := getRollappKeysDir(root) sequencerKeyInfoPath := filepath.Join(rollappKeysDir, consts.KeyNames.RollappSequencer+".info") if err := verifyFileExists(sequencerKeyInfoPath); err != nil { return err } - relayerKeyInfoPath := filepath.Join(rollappKeysDir, consts.KeyNames.HubSequencer+".info") + hubKeysDir := getHubKeysDir(root) + relayerKeyInfoPath := filepath.Join(hubKeysDir, consts.KeyNames.HubSequencer+".info") if err := verifyFileExists(relayerKeyInfoPath); err != nil { return err } - for i := 0; i < 2; i++ { - err := verifyAndRemoveFilePattern(addressPattern, rollappKeysDir) - if err != nil { - return err - } + err := verifyAndRemoveFilePattern(addressPattern, rollappKeysDir) + if err != nil { + return err + } + err = verifyAndRemoveFilePattern(addressPattern, hubKeysDir) + if err != nil { + return err } nodeKeyPath := getNodeKeyPath(root) if err := verifyFileExists(nodeKeyPath); err != nil {