diff --git a/cmd/config/export/export.go b/cmd/config/export/export.go index 399a61fe..0498e546 100644 --- a/cmd/config/export/export.go +++ b/cmd/config/export/export.go @@ -36,8 +36,8 @@ func Cmd() *cobra.Command { coinType = 60 } rly := relayer.NewRelayer(rlpCfg.Home, rlpCfg.RollappID, rlpCfg.HubData.ID) - srcChannel, hubChannel, err := rly.LoadActiveChannel() - if err != nil || srcChannel == "" || hubChannel == "" { + _, _, err = rly.LoadActiveChannel() + if err != nil || rly.SrcChannel == "" || rly.DstChannel == "" { utils.PrettifyErrorIfExists(errors.New("failed to export rollapp json." + " Please verify that the rollapp is running on your local machine and a relayer channel has been established")) } @@ -62,8 +62,8 @@ func Cmd() *cobra.Command { Website: "", Logo: logoDefaultPath, Ibc: IbcConfig{ - HubChannel: hubChannel, - Channel: srcChannel, + HubChannel: rly.SrcChannel, + Channel: rly.DstChannel, Timeout: 172800000, }, Type: RollApp, diff --git a/cmd/config/init/genesis.go b/cmd/config/init/genesis.go index 824fd290..ce7d57d4 100644 --- a/cmd/config/init/genesis.go +++ b/cmd/config/init/genesis.go @@ -30,18 +30,17 @@ func GetGenesisFilePath(root string) string { // TODO(#130): fix to support epochs func getDefaultGenesisParams( - sequencerAddr, genesisOperatorAddress string, + sequencerAddr, genesisOperatorAddress string, raCfg *config.RollappConfig, ) []PathValue { return []PathValue{ // these should be injected from the genesis creator - // {"consensus_params.block.max_gas", "40000000"}, - // {"app_state.feemarket.params.no_base_fee", true}, - // {"app_state.feemarket.params.min_gas_price", "0.0"}, - // {"app_state.distribution.params.base_proposer_reward", "0.8"}, - // {"app_state.distribution.params.community_tax", "0.00002"}, - // {"app_state.gov.voting_params.voting_period", "300s"}, - // {"app_state.staking.params.unbonding_time", "3628800s"}, - // {"app_state.bank.denom_metadata", getBankDenomMetadata(denom, decimals)}, + {"consensus_params.block.max_gas", "40000000"}, + {"app_state.feemarket.params.no_base_fee", true}, + {"app_state.feemarket.params.min_gas_price", "0.0"}, + {"app_state.distribution.params.base_proposer_reward", "0.8"}, + {"app_state.distribution.params.community_tax", "0.00002"}, + {"app_state.gov.voting_params.voting_period", "300s"}, + {"app_state.bank.denom_metadata", getBankDenomMetadata(raCfg.BaseDenom, raCfg.Decimals)}, {"app_state.sequencers.genesis_operator_address", genesisOperatorAddress}, { @@ -73,7 +72,7 @@ func UpdateJSONParams(jsonFilePath string, params []PathValue) error { return nil } -func UpdateGenesisParams(home string) error { +func UpdateGenesisParams(home string, raCfg *config.RollappConfig) error { oa, err := getGenesisOperatorAddress(home) if err != nil { return err @@ -87,8 +86,9 @@ func UpdateGenesisParams(home string) error { if err != nil { return err } - params := getDefaultGenesisParams(sa, oa) + params := getDefaultGenesisParams(sa, oa, raCfg) + // TODO: move to generalized helper addGenAccountCmd := exec.Command( consts.Executables.RollappEVM, "add-genesis-account", @@ -109,6 +109,22 @@ func UpdateGenesisParams(home string) error { return UpdateJSONParams(genesisFilePath, params) } +func GetAddGenesisAccountCmd(addr, amount string, raCfg *config.RollappConfig) *exec.Cmd { + home := utils.GetRollerRootDir() + cmd := exec.Command( + consts.Executables.RollappEVM, + "add-genesis-account", + addr, + fmt.Sprintf("%s%s", consts.DefaultTokenSupply, raCfg.BaseDenom), + "--home", + fmt.Sprintf("%s/%s", home, consts.ConfigDirName.Rollapp), + "--keyring-backend", + "test", + ) + + return cmd +} + func getGenesisOperatorAddress(home string) (string, error) { rollappConfigDirPath := filepath.Join(home, consts.ConfigDirName.Rollapp) getOperatorAddrCommand := exec.Command( diff --git a/cmd/config/init/keys.go b/cmd/config/init/keys.go index 89698bcb..a46c8586 100644 --- a/cmd/config/init/keys.go +++ b/cmd/config/init/keys.go @@ -3,34 +3,17 @@ package initconfig import ( "fmt" "os/exec" + "path" "path/filepath" + "github.com/pterm/pterm" + "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/cmd/utils" "github.com/dymensionxyz/roller/config" ) -func GenerateKeys(rollappConfig config.RollappConfig) ([]utils.KeyInfo, error) { - // var addresses []utils.KeyInfo - - sequencerAddresses, err := generateSequencersKeys(rollappConfig) - if err != nil { - fmt.Println("failed to generate sequencerAddresses") - return nil, err - } - - // addresses = append(addresses, sequencerAddresses...) - - // relayerAddresses, err := generateRelayerKeys(rollappConfig) - // if err != nil { - // return nil, err - // } - // addresses = append(addresses, relayerAddresses...) - - return sequencerAddresses, nil -} - -func generateSequencersKeys(initConfig config.RollappConfig) ([]utils.KeyInfo, error) { +func GenerateSequencersKeys(initConfig config.RollappConfig) ([]utils.KeyInfo, error) { keys := getSequencerKeysConfig(initConfig) addresses := make([]utils.KeyInfo, 0) for _, key := range keys { @@ -40,11 +23,13 @@ func generateSequencersKeys(initConfig config.RollappConfig) ([]utils.KeyInfo, e if err != nil { return nil, err } - addresses = append(addresses, utils.KeyInfo{ - Address: address.Address, - Name: key.ID, - Mnemonic: address.Mnemonic, - }) + addresses = append( + addresses, utils.KeyInfo{ + Address: address.Address, + Name: key.ID, + Mnemonic: address.Mnemonic, + }, + ) } return addresses, nil } @@ -68,6 +53,13 @@ func getSequencerKeysConfig(rollappConfig config.RollappConfig) []utils.KeyConfi // Eventhough the hub can get evm signatures, we still use the native Type: config.SDK_ROLLAPP, }, + { + Dir: consts.ConfigDirName.HubKeys, + ID: consts.KeysIds.HubGenesis, + ChainBinary: consts.Executables.Dymension, + // Eventhough the hub can get evm signatures, we still use the native + Type: config.SDK_ROLLAPP, + }, { Dir: consts.ConfigDirName.Rollapp, ID: consts.KeysIds.RollappSequencer, @@ -77,22 +69,22 @@ func getSequencerKeysConfig(rollappConfig config.RollappConfig) []utils.KeyConfi } } -// func getRelayerKeysConfig(rollappConfig config.RollappConfig) map[string]utils.KeyConfig { -// return map[string]utils.KeyConfig{ -// consts.KeysIds.RollappRelayer: { -// Dir: path.Join(rollappConfig.Home, consts.ConfigDirName.Relayer), -// ID: consts.KeysIds.RollappRelayer, -// ChainBinary: rollappConfig.RollappBinary, -// Type: rollappConfig.VMType, -// }, -// consts.KeysIds.HubRelayer: { -// Dir: path.Join(rollappConfig.Home, consts.ConfigDirName.Relayer), -// ID: consts.KeysIds.HubRelayer, -// ChainBinary: consts.Executables.Dymension, -// Type: config.SDK_ROLLAPP, -// }, -// } -// } +func getRelayerKeysConfig(rollappConfig config.RollappConfig) map[string]utils.KeyConfig { + return map[string]utils.KeyConfig{ + consts.KeysIds.RollappRelayer: { + Dir: path.Join(rollappConfig.Home, consts.ConfigDirName.Relayer), + ID: consts.KeysIds.RollappRelayer, + ChainBinary: rollappConfig.RollappBinary, + Type: rollappConfig.VMType, + }, + consts.KeysIds.HubRelayer: { + Dir: path.Join(rollappConfig.Home, consts.ConfigDirName.Relayer), + ID: consts.KeysIds.HubRelayer, + ChainBinary: consts.Executables.Dymension, + Type: config.SDK_ROLLAPP, + }, + } +} func CreateAddressBinary( keyConfig utils.KeyConfig, @@ -111,55 +103,124 @@ func CreateAddressBinary( return utils.ParseAddressFromOutput(out) } -// func generateRelayerKeys(rollappConfig config.RollappConfig) ([]utils.AddressData, error) { -// relayerAddresses := make([]utils.AddressData, 0) -// keys := getRelayerKeysConfig(rollappConfig) -// createRollappKeyCmd := getAddRlyKeyCmd( -// keys[consts.KeysIds.RollappRelayer], -// rollappConfig.RollappID, -// ) -// createHubKeyCmd := getAddRlyKeyCmd(keys[consts.KeysIds.HubRelayer], rollappConfig.HubData.ID) -// out, err := utils.ExecBashCommandWithStdout(createRollappKeyCmd) -// if err != nil { -// return nil, err -// } -// relayerRollappAddress, err := utils.ParseAddressFromOutput(out) -// if err != nil { -// return nil, err -// } -// relayerAddresses = append(relayerAddresses, utils.AddressData{ -// Addr: relayerRollappAddress, -// Name: consts.KeysIds.RollappRelayer, -// }) -// out, err = utils.ExecBashCommandWithStdout(createHubKeyCmd) -// if err != nil { -// return nil, err -// } -// relayerHubAddress, err := utils.ParseAddressFromOutput(out) -// if err != nil { -// return nil, err -// } -// relayerAddresses = append(relayerAddresses, utils.AddressData{ -// Addr: relayerHubAddress, -// Name: consts.KeysIds.HubRelayer, -// }) -// return relayerAddresses, err -// } - -// func getAddRlyKeyCmd(keyConfig utils.KeyConfig, chainID string) *exec.Cmd { -// coinType := "118" -// if keyConfig.Type == config.EVM_ROLLAPP { -// coinType = "60" -// } -// return exec.Command( -// consts.Executables.Relayer, -// "keys", -// "add", -// chainID, -// keyConfig.ID, -// "--home", -// keyConfig.Dir, -// "--coin-type", -// coinType, -// ) -// } +func GetRelayerKeys(rollappConfig config.RollappConfig) ([]utils.KeyInfo, error) { + pterm.Info.Println("getting relayer keys") + relayerAddresses := make([]utils.KeyInfo, 0) + keys := getRelayerKeysConfig(rollappConfig) + + showRollappKeyCmd := getShowRlyKeyCmd( + keys[consts.KeysIds.RollappRelayer], + rollappConfig.RollappID, + ) + showHubKeyCmd := getShowRlyKeyCmd( + keys[consts.KeysIds.HubRelayer], + rollappConfig.HubData.ID, + ) + + out, err := utils.ExecBashCommandWithStdout(showRollappKeyCmd) + if err != nil { + pterm.Error.Printf("failed to retrieve rollapp key: %v\n", err) + } + relayerRollappAddress, err := utils.ParseAddressFromOutput(out) + if err != nil { + pterm.Error.Printf("failed to extract rollapp key: %v\n", err) + } + fmt.Println(relayerRollappAddress) + + out, err = utils.ExecBashCommandWithStdout(showHubKeyCmd) + if err != nil { + pterm.Error.Printf("failed to retrieve hub key: %v\n", err) + } + relayerHubAddress, err := utils.ParseAddressFromOutput(out) + if err != nil { + pterm.Error.Printf("failed to extract hub key: %v\n", err) + } + fmt.Println(relayerHubAddress) + + relayerAddresses = append( + relayerAddresses, *relayerRollappAddress, + ) + relayerAddresses = append( + relayerAddresses, *relayerHubAddress, + ) + + return relayerAddresses, nil +} + +func GenerateRelayerKeys(rollappConfig config.RollappConfig) ([]utils.KeyInfo, error) { + pterm.Info.Println("creating relayer keys") + relayerAddresses := make([]utils.KeyInfo, 0) + keys := getRelayerKeysConfig(rollappConfig) + + createRollappKeyCmd := getAddRlyKeyCmd( + keys[consts.KeysIds.RollappRelayer], + rollappConfig.RollappID, + ) + createHubKeyCmd := getAddRlyKeyCmd(keys[consts.KeysIds.HubRelayer], rollappConfig.HubData.ID) + + pterm.Info.Println("creating relayer rollapp key") + out, err := utils.ExecBashCommandWithStdout(createRollappKeyCmd) + if err != nil { + return nil, err + } + relayerRollappAddress, err := utils.ParseAddressFromOutput(out) + relayerRollappAddress.Name = consts.KeysIds.RollappRelayer + if err != nil { + return nil, err + } + relayerAddresses = append( + relayerAddresses, *relayerRollappAddress, + ) + + pterm.Info.Println("creating relayer hub key") + out, err = utils.ExecBashCommandWithStdout(createHubKeyCmd) + if err != nil { + return nil, err + } + relayerHubAddress, err := utils.ParseAddressFromOutput(out) + relayerHubAddress.Name = consts.KeysIds.HubRelayer + if err != nil { + return nil, err + } + relayerAddresses = append( + relayerAddresses, *relayerHubAddress, + ) + + return relayerAddresses, nil +} + +func getAddRlyKeyCmd(keyConfig utils.KeyConfig, chainID string) *exec.Cmd { + coinType := "118" + if keyConfig.Type == config.EVM_ROLLAPP { + coinType = "60" + } + return exec.Command( + consts.Executables.Relayer, + "keys", + "add", + chainID, + keyConfig.ID, + "--home", + keyConfig.Dir, + "--coin-type", + coinType, + ) +} + +func getShowRlyKeyCmd(keyConfig utils.KeyConfig, chainID string) *exec.Cmd { + coinType := "118" + if keyConfig.Type == config.EVM_ROLLAPP { + coinType = "60" + } + return exec.Command( + consts.Executables.Relayer, + "keys", + "show", + chainID, + keyConfig.ID, + "--home", + keyConfig.Dir, + "--coin-type", + coinType, + ) +} diff --git a/cmd/config/init/output.go b/cmd/config/init/output.go index ccd3ce1c..3ff79a09 100644 --- a/cmd/config/init/output.go +++ b/cmd/config/init/output.go @@ -50,7 +50,10 @@ func (o *OutputHandler) PromptOverwriteConfig(home string) (bool, error) { if o.NoOutput { return true, nil } - return utils.PromptBool( - fmt.Sprintf("Directory %s is not empty. Do you want to overwrite", home), - ) + + shouldOverwrite, _ := pterm.DefaultInteractiveConfirm.WithDefaultText( + fmt.Sprintf("Directory %s is not empty. Do you want to overwrite it?", home), + ).WithDefaultValue(false).Show() + + return shouldOverwrite, nil } diff --git a/cmd/config/init/relayer.go b/cmd/config/init/relayer.go index 1f643b20..1d0b8771 100644 --- a/cmd/config/init/relayer.go +++ b/cmd/config/init/relayer.go @@ -6,6 +6,8 @@ import ( "os/exec" "path/filepath" + "github.com/pterm/pterm" + "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/config" "github.com/dymensionxyz/roller/relayer" @@ -44,7 +46,7 @@ func writeTmpChainConfig(chainConfig RelayerFileChainConfig, fileName string) (s } filePath := filepath.Join(os.TempDir(), fileName) // nolint:gofumpt - if err := os.WriteFile(filePath, file, 0644); err != nil { + if err := os.WriteFile(filePath, file, 0o644); err != nil { return "", err } return filePath, nil @@ -107,17 +109,21 @@ func addChainsConfig( hubConfig relayer.ChainConfig, relayerHome string, ) error { - relayerRollappConfig := getRelayerFileChainConfig(RelayerChainConfig{ - ChainConfig: rollappConfig, - GasPrices: rollappConfig.GasPrices + rollappConfig.Denom, - KeyName: consts.KeysIds.RollappRelayer, - }) - - relayerHubConfig := getRelayerFileChainConfig(RelayerChainConfig{ - ChainConfig: hubConfig, - GasPrices: hubConfig.GasPrices + hubConfig.Denom, - KeyName: consts.KeysIds.HubRelayer, - }) + relayerRollappConfig := getRelayerFileChainConfig( + RelayerChainConfig{ + ChainConfig: rollappConfig, + GasPrices: rollappConfig.GasPrices + rollappConfig.Denom, + KeyName: consts.KeysIds.RollappRelayer, + }, + ) + + relayerHubConfig := getRelayerFileChainConfig( + RelayerChainConfig{ + ChainConfig: hubConfig, + GasPrices: hubConfig.GasPrices + hubConfig.Denom, + KeyName: consts.KeysIds.HubRelayer, + }, + ) if err := addChainToRelayer(relayerRollappConfig, relayerHome); err != nil { return err @@ -128,20 +134,21 @@ func addChainsConfig( return nil } -func initializeRelayerConfig( +func InitializeRelayerConfig( rollappConfig relayer.ChainConfig, hubConfig relayer.ChainConfig, initConfig config.RollappConfig, ) error { + pterm.Info.Println("initializing relayer config") + relayerHome := filepath.Join(initConfig.Home, consts.ConfigDirName.Relayer) + if err := initRelayer(relayerHome); err != nil { return err } if err := addChainsConfig(rollappConfig, hubConfig, relayerHome); err != nil { return err } - if err := relayer.CreatePath(initConfig); err != nil { - return err - } + return nil } diff --git a/cmd/consts/consts.go b/cmd/consts/consts.go index 497fb240..4859419b 100644 --- a/cmd/consts/consts.go +++ b/cmd/consts/consts.go @@ -35,11 +35,13 @@ var Executables = struct { var KeysIds = struct { HubSequencer string + HubGenesis string RollappSequencer string RollappRelayer string HubRelayer string }{ HubSequencer: "hub_sequencer", + HubGenesis: "hub_genesis", RollappSequencer: "rollapp_genesis_account", RollappRelayer: "relayer-rollapp-key", HubRelayer: "relayer-hub-key", @@ -79,7 +81,7 @@ var Denoms = struct { const ( KeysDirName = "keys" - DefaultRelayerPath = "rollapp-hub" + DefaultRelayerPath = "hub-rollapp" DefaultRollappRPC = "http://localhost:26657" ) diff --git a/cmd/relayer/relayer.go b/cmd/relayer/relayer.go index 442b10a9..0aae4ce2 100644 --- a/cmd/relayer/relayer.go +++ b/cmd/relayer/relayer.go @@ -3,8 +3,9 @@ package relayer import ( "github.com/spf13/cobra" - "github.com/dymensionxyz/roller/cmd/relayer/start" + "github.com/dymensionxyz/roller/cmd/relayer/run" "github.com/dymensionxyz/roller/cmd/relayer/status" + "github.com/dymensionxyz/roller/cmd/rollapp/start" ) func Cmd() *cobra.Command { @@ -12,7 +13,8 @@ func Cmd() *cobra.Command { Use: "relayer", Short: "Commands for running and managing the RollApp relayer.", } - cmd.AddCommand(start.Start()) + cmd.AddCommand(run.Cmd()) + cmd.AddCommand(start.Cmd()) cmd.AddCommand(status.Cmd()) return cmd } diff --git a/cmd/relayer/run/run.go b/cmd/relayer/run/run.go new file mode 100644 index 00000000..70181a3e --- /dev/null +++ b/cmd/relayer/run/run.go @@ -0,0 +1,303 @@ +package run + +import ( + "context" + "fmt" + "math/big" + "os" + "path/filepath" + + "github.com/pterm/pterm" + "github.com/spf13/cobra" + + initconfig "github.com/dymensionxyz/roller/cmd/config/init" + "github.com/dymensionxyz/roller/cmd/consts" + "github.com/dymensionxyz/roller/cmd/utils" + "github.com/dymensionxyz/roller/config" + "github.com/dymensionxyz/roller/relayer" + "github.com/dymensionxyz/roller/sequencer" + global_utils "github.com/dymensionxyz/roller/utils" +) + +// TODO: Test relaying on 35-C and update the prices +var ( + oneDayRelayPriceHub = big.NewInt(1) + oneDayRelayPriceRollapp = big.NewInt(1) +) + +const ( + flagOverride = "override" +) + +func Cmd() *cobra.Command { + relayerStartCmd := &cobra.Command{ + Use: "run", + Short: "Runs a relayer between the Dymension hub and the rollapp.", + Run: func(cmd *cobra.Command, args []string) { + home := cmd.Flag(utils.FlagNames.Home).Value.String() + relayerHome := filepath.Join(home, consts.ConfigDirName.Relayer) + rollappConfig, err := config.LoadConfigFromTOML(home) + if err != nil { + pterm.Error.Printf("failed to load rollapp config: %v\n", err) + return + } + rollerConfigFilePath := filepath.Join(utils.GetRollerRootDir(), "roller.toml") + relayerLogFilePath := utils.GetRelayerLogPath(rollappConfig) + relayerLogger := utils.GetLogger(relayerLogFilePath) + + /* ---------------------------- Initialize relayer --------------------------- */ + outputHandler := initconfig.NewOutputHandler(false) + isDirEmpty, err := global_utils.DirNotEmpty(relayerHome) + if err != nil { + pterm.Error.Printf("failed to check %s: %v\n", relayerHome, err) + return + } + + var shouldOverwrite bool + if isDirEmpty { + outputHandler.StopSpinner() + shouldOverwrite, err = outputHandler.PromptOverwriteConfig(relayerHome) + if err != nil { + pterm.Error.Printf("failed to get your input: %v\n", err) + return + } + } + + if shouldOverwrite { + pterm.Info.Println("overriding the existing relayer channel") + err = os.RemoveAll(relayerHome) + if err != nil { + pterm.Error.Printf("failed to recuresively remove %s: %v\n", relayerHome, err) + return + } + + err = os.MkdirAll(relayerHome, 0o755) + if err != nil { + pterm.Error.Printf("failed to create %s: %v\n", relayerHome, err) + return + } + + rollappPrefix, err := global_utils.GetKeyFromTomlFile( + rollerConfigFilePath, + "bech32_prefix", + ) + if err != nil { + pterm.Error.Printf("failed to retrieve bech32_prefix: %v\n", err) + return + } + + err = initconfig.InitializeRelayerConfig( + relayer.ChainConfig{ + ID: rollappConfig.RollappID, + RPC: consts.DefaultRollappRPC, + Denom: rollappConfig.Denom, + AddressPrefix: rollappPrefix, + GasPrices: "0", + }, relayer.ChainConfig{ + ID: rollappConfig.HubData.ID, + RPC: rollappConfig.HubData.RPC_URL, + Denom: consts.Denoms.Hub, + AddressPrefix: consts.AddressPrefixes.Hub, + GasPrices: rollappConfig.HubData.GAS_PRICE, + }, rollappConfig, + ) + if err != nil { + pterm.Error.Printf( + "failed to initialize relayer config: %v\n", + err, + ) + return + } + + if err := relayer.CreatePath(rollappConfig); err != nil { + pterm.Error.Printf("failed to create relayer IBC path: %v\n", err) + return + } + } + + rly := relayer.NewRelayer( + rollappConfig.Home, + rollappConfig.RollappID, + rollappConfig.HubData.ID, + ) + rly.SetLogger(relayerLogger) + _, _, err = rly.LoadActiveChannel() + if err != nil { + pterm.Error.Printf("failed to load active channel, %v", err) + return + } + logFileOption := utils.WithLoggerLogging(relayerLogger) + + utils.RequireMigrateIfNeeded(rollappConfig) + + err = rollappConfig.Validate() + if err != nil { + pterm.Error.Printf("failed to validate rollapp config: %v\n", err) + return + } + + var createIbcChannels bool + + if rly.ChannelReady() && !shouldOverwrite { + pterm.DefaultSection.WithIndentCharacter("💈"). + Println("IBC transfer channel is already established!") + + status := fmt.Sprintf("Active src, %s <-> %s, dst", rly.SrcChannel, rly.DstChannel) + err := rly.WriteRelayerStatus(status) + if err != nil { + fmt.Println(err) + } + } + + if !rly.ChannelReady() { + createIbcChannels, _ = pterm.DefaultInteractiveConfirm.WithDefaultText( + fmt.Sprintf( + "no channel found. would you like to create a new IBC channel for %s?", + rollappConfig.RollappID, + ), + ).Show() + + if !createIbcChannels { + pterm.Warning.Println("you can't run a relayer without an ibc channel") + return + } + } + + if createIbcChannels || shouldOverwrite { + if shouldOverwrite { + keys, err := initconfig.GenerateRelayerKeys(rollappConfig) + if err != nil { + pterm.Error.Printf("failed to create relayer keys: %v\n", err) + return + } + + for _, key := range keys { + key.Print(utils.WithMnemonic(), utils.WithName()) + } + + pterm.Info.Println("please fund the keys below with X respectively: ") + for _, k := range keys { + k.Print(utils.WithName()) + } + interactiveContinue, _ := pterm.DefaultInteractiveConfirm.WithDefaultText( + "Press enter when the keys are funded: ", + ).WithDefaultValue(true).Show() + if !interactiveContinue { + return + } + } + + err = VerifyRelayerBalances(rollappConfig) + if err != nil { + pterm.Error.Printf("failed to verify relayer balances: %v\n", err) + return + } + + pterm.Info.Println("establishing IBC transfer channel") + seq := sequencer.GetInstance(rollappConfig) + _, err = rly.CreateIBCChannel(shouldOverwrite, logFileOption, seq) + if err != nil { + pterm.Error.Printf("failed to create IBC channel: %v\n", err) + return + } + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go utils.RunBashCmdAsync( + ctx, + rly.GetStartCmd(), + func() {}, + func(errMessage string) string { return errMessage }, + logFileOption, + ) + pterm.Info.Printf( + "The relayer is running successfully on you local machine!\nChannels:\nsrc, %s <-> %s, dst", + rly.SrcChannel, + rly.DstChannel, + ) + + select {} + }, + } + + relayerStartCmd.Flags(). + BoolP(flagOverride, "", false, "override the existing relayer clients and channels") + return relayerStartCmd +} + +func VerifyRelayerBalances(rolCfg config.RollappConfig) error { + insufficientBalances, err := GetRelayerInsufficientBalances(rolCfg) + if err != nil { + return err + } + utils.PrintInsufficientBalancesIfAny(insufficientBalances, rolCfg) + + return nil +} + +func GetRlyHubInsufficientBalances( + config config.RollappConfig, +) ([]utils.NotFundedAddressData, error) { + HubRlyAddr, err := utils.GetRelayerAddress(config.Home, config.HubData.ID) + if err != nil { + pterm.Error.Printf("failed to get relayer address: %v", err) + return nil, err + } + + HubRlyBalance, err := utils.QueryBalance( + utils.ChainQueryConfig{ + RPC: config.HubData.RPC_URL, + Denom: consts.Denoms.Hub, + Binary: consts.Executables.Dymension, + }, HubRlyAddr, + ) + if err != nil { + pterm.Error.Printf("failed to query %s balances: %v", HubRlyAddr, err) + return nil, err + } + + insufficientBalances := make([]utils.NotFundedAddressData, 0) + if HubRlyBalance.Amount.Cmp(oneDayRelayPriceHub) < 0 { + insufficientBalances = append( + insufficientBalances, utils.NotFundedAddressData{ + KeyName: consts.KeysIds.HubRelayer, + Address: HubRlyAddr, + CurrentBalance: HubRlyBalance.Amount, + RequiredBalance: oneDayRelayPriceHub, + Denom: consts.Denoms.Hub, + Network: config.HubData.ID, + }, + ) + } + return insufficientBalances, nil +} + +func GetRelayerInsufficientBalances( + config config.RollappConfig, +) ([]utils.NotFundedAddressData, error) { + insufficientBalances, err := GetRlyHubInsufficientBalances(config) + if err != nil { + return insufficientBalances, err + } + + rolRlyData, err := relayer.GetRolRlyAccData(config) + if err != nil { + return insufficientBalances, err + } + + if rolRlyData.Balance.Amount.Cmp(oneDayRelayPriceRollapp) < 0 { + insufficientBalances = append( + insufficientBalances, utils.NotFundedAddressData{ + KeyName: consts.KeysIds.RollappRelayer, + Address: rolRlyData.Address, + CurrentBalance: rolRlyData.Balance.Amount, + RequiredBalance: oneDayRelayPriceRollapp, + Denom: config.Denom, + Network: config.RollappID, + }, + ) + } + + return insufficientBalances, nil +} diff --git a/cmd/rollapp/init/main.go b/cmd/rollapp/init/main.go index df4fff6a..6d9a3830 100644 --- a/cmd/rollapp/init/main.go +++ b/cmd/rollapp/init/main.go @@ -16,10 +16,9 @@ var Cmd = &cobra.Command{ Long: ``, Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - pterm.DefaultHeader.WithFullWidth().Printfln("welcome to roller") err := initconfig.AddFlags(cmd) if err != nil { - fmt.Println("failed to add flags") + pterm.Error.Println("failed to add flags") return } @@ -40,10 +39,12 @@ var Cmd = &cobra.Command{ } options := []string{"mock", "dymension"} - backend, _ := pterm.DefaultInteractiveSelect.WithOptions(options).Show() - isMockBackend := backend == "mock" + backend, _ := pterm.DefaultInteractiveSelect. + WithDefaultText("select the settlement layer type"). + WithOptions(options). + Show() - if isMockBackend { + if backend == "mock" { err := runInit(cmd, WithMockSettlement()) if err != nil { fmt.Println("failed to run init: ", err) diff --git a/cmd/rollapp/init/utils.go b/cmd/rollapp/init/utils.go index fa88c5c6..a9388e5e 100644 --- a/cmd/rollapp/init/utils.go +++ b/cmd/rollapp/init/utils.go @@ -59,6 +59,7 @@ func runInit(cmd *cobra.Command, opts ...Option) error { defer outputHandler.StopSpinner() + // TODO: extract into util isRootExist, err := global_utils.DirNotEmpty(home) if err != nil { utils.PrettifyErrorIfExists(err) @@ -84,7 +85,7 @@ func runInit(cmd *cobra.Command, opts ...Option) error { } // nolint:gofumpt - err = os.MkdirAll(home, 0755) + err = os.MkdirAll(home, 0o755) if err != nil { utils.PrettifyErrorIfExists(err) return err @@ -100,8 +101,8 @@ func runInit(cmd *cobra.Command, opts ...Option) error { return err } } else { - config := NewMockRollerConfig() - err := WriteMockRollerconfigToFile(config) + mockRollerConfig := NewMockRollerConfig() + err := WriteMockRollerconfigToFile(mockRollerConfig) if err != nil { return err } @@ -125,31 +126,9 @@ func runInit(cmd *cobra.Command, opts ...Option) error { // TODO: create all dirs here outputHandler.StartSpinner(" Initializing RollApp configuration files...") - /* ---------------------------- Initialize relayer --------------------------- */ - // 20240607 relayer will be handled using a separate, relayer command - // rollerConfigFilePath := filepath.Join(utils.GetRollerRootDir(), "roller.toml") - // rollappPrefix, err := global_utils.GetKeyFromTomlFile(rollerConfigFilePath, "bech32_prefix") - // utils.PrettifyErrorIfExists(err) - - // err = initializeRelayerConfig(relayer.ChainConfig{ - // ID: initConfig.RollappID, - // RPC: consts.DefaultRollappRPC, - // Denom: initConfig.Denom, - // AddressPrefix: rollappPrefix, - // GasPrices: "0", - // }, relayer.ChainConfig{ - // ID: initConfig.HubData.ID, - // RPC: initConfig.HubData.ARCHIVE_RPC_URL, - // Denom: consts.Denoms.Hub, - // AddressPrefix: consts.AddressPrefixes.Hub, - // GasPrices: initConfig.HubData.GAS_PRICE, - // }, initConfig) - // if err != nil { - // return err - // } /* ------------------------------ Generate keys ----------------------------- */ - addresses, err := initconfig.GenerateKeys(initConfig) + addresses, err := initconfig.GenerateSequencersKeys(initConfig) if err != nil { utils.PrettifyErrorIfExists(err) return err @@ -168,11 +147,13 @@ func runInit(cmd *cobra.Command, opts ...Option) error { } if daAddress != nil { - addresses = append(addresses, utils.KeyInfo{ - Name: damanager.GetKeyName(), - Address: daAddress.Address, - Mnemonic: mnemonic, - }) + addresses = append( + addresses, utils.KeyInfo{ + Name: damanager.GetKeyName(), + Address: daAddress.Address, + Mnemonic: mnemonic, + }, + ) } /* --------------------------- Initialize Rollapp -------------------------- */ @@ -194,7 +175,7 @@ func runInit(cmd *cobra.Command, opts ...Option) error { } // adds the sequencer address to the whitelists - err = initconfig.UpdateGenesisParams(home) + err = initconfig.UpdateGenesisParams(home, &initConfig) if err != nil { return err } @@ -206,6 +187,59 @@ func runInit(cmd *cobra.Command, opts ...Option) error { return err } + err = global_utils.UpdateFieldInToml(rollerConfigFilePath, "HubData.ID", initConfig.HubData.ID) + if err != nil { + fmt.Println("failed to add HubData.ID to roller.toml: ", err) + return err + } + + err = global_utils.UpdateFieldInToml( + rollerConfigFilePath, + "HubData.rpc_url", + initConfig.HubData.RPC_URL, + ) + if err != nil { + fmt.Println("failed to add HubData.RpcUrl to roller.toml: ", err) + return err + } + + err = global_utils.UpdateFieldInToml( + rollerConfigFilePath, + "HubData.gas_price", + initConfig.HubData.GAS_PRICE, + ) + if err != nil { + fmt.Println("failed to add HubData.GasPrices to roller.toml: ", err) + return err + } + + err = global_utils.UpdateFieldInToml( + rollerConfigFilePath, + "da", + strings.ToLower(string(initConfig.DA)), + ) + if err != nil { + fmt.Println("failed to add HubData.RpcUrl to roller.toml: ", err) + return err + } + + err = global_utils.UpdateFieldInToml( + rollerConfigFilePath, + "rollapp_binary", + strings.ToLower(consts.Executables.RollappEVM), + ) + if err != nil { + fmt.Println("failed to add HubData.RpcUrl to roller.toml: ", err) + return err + } + + /* ------------------------------ Create Init Files ---------------------------- */ + err = WriteDenomMetadata(initConfig) + if err != nil { + fmt.Println("failed to create denom metadata: ", err) + return err + } + // 20240607 genesis is generated using the genesis-creator // err = initializeRollappGenesis(initConfig) // if err != nil { diff --git a/cmd/run/run.go b/cmd/run/run.go index 6755dfc8..d3b3c35f 100644 --- a/cmd/run/run.go +++ b/cmd/run/run.go @@ -8,7 +8,7 @@ import ( "github.com/spf13/cobra" - relayer_start "github.com/dymensionxyz/roller/cmd/relayer/start" + relayer_run "github.com/dymensionxyz/roller/cmd/relayer/run" rollapp_start "github.com/dymensionxyz/roller/cmd/rollapp/start" "github.com/dymensionxyz/roller/cmd/utils" "github.com/dymensionxyz/roller/config" @@ -139,11 +139,12 @@ func verifyBalances(rollappConfig config.RollappConfig) { utils.PrettifyErrorIfExists(err) sequencerInsufficientBalances, err := utils.GetSequencerInsufficientAddrs( - rollappConfig, rollapp_start.OneDaySequencePrice) + rollappConfig, rollapp_start.OneDaySequencePrice, + ) utils.PrettifyErrorIfExists(err) insufficientBalances = append(insufficientBalances, sequencerInsufficientBalances...) - rlyAddrs, err := relayer_start.GetRlyHubInsufficientBalances(rollappConfig) + rlyAddrs, err := relayer_run.GetRlyHubInsufficientBalances(rollappConfig) utils.PrettifyErrorIfExists(err) insufficientBalances = append(insufficientBalances, rlyAddrs...) utils.PrintInsufficientBalancesIfAny(insufficientBalances, rollappConfig) diff --git a/cmd/tx/fund_faucet/fund_faucet.go b/cmd/tx/fund_faucet/fund_faucet.go index 9f37688f..247eed31 100644 --- a/cmd/tx/fund_faucet/fund_faucet.go +++ b/cmd/tx/fund_faucet/fund_faucet.go @@ -58,8 +58,8 @@ func fundFaucet(cmd *cobra.Command, args []string) error { utils.RunOnInterrupt(outputHandler.StopSpinner) outputHandler.StartSpinner(" Loading relayer channel...") rly := relayer.NewRelayer(rlpCfg.Home, rlpCfg.RollappID, rlpCfg.HubData.ID) - srcChannel, _, err := rly.LoadActiveChannel() - if err != nil || srcChannel == "" { + _, _, err = rly.LoadActiveChannel() + if err != nil || rly.SrcChannel == "" { return errors.New("failed to load relayer channel. Please make sure that the rollapp is " + "running on your local machine and a relayer channel has been established") } @@ -79,7 +79,7 @@ func fundFaucet(cmd *cobra.Command, args []string) error { "ibc-transfer", "transfer", "transfer", - srcChannel, + rly.SrcChannel, faucetAddr, actualFaucetAmount.String()+rlpCfg.Denom, "--from", diff --git a/cmd/utils/bash_commands.go b/cmd/utils/bash_commands.go index 4080547e..6b83058d 100644 --- a/cmd/utils/bash_commands.go +++ b/cmd/utils/bash_commands.go @@ -135,7 +135,7 @@ func ExecBashCmd(cmd *exec.Cmd, options ...CommandOption) error { } err := cmd.Run() if err != nil { - return fmt.Errorf("command execution failed: %w", err) + return fmt.Errorf("command execution failed: %v", err) } return nil } diff --git a/cmd/utils/error_handling.go b/cmd/utils/error_handling.go index af98d0f3..ee75caed 100644 --- a/cmd/utils/error_handling.go +++ b/cmd/utils/error_handling.go @@ -4,7 +4,7 @@ import ( "os" "os/signal" - "github.com/fatih/color" + "github.com/pterm/pterm" "github.com/dymensionxyz/roller/config" "github.com/dymensionxyz/roller/version" @@ -17,8 +17,7 @@ func PrettifyErrorIfExists(err error, printAdditionalInfo ...func()) { os.Exit(1) } }() - //nolint:errcheck,gosec - color.New(color.FgRed, color.Bold).Printf("💈 %s\n", err.Error()) + pterm.Error.Printf("💈 %s\n", err.Error()) for _, printInfo := range printAdditionalInfo { printInfo() @@ -33,10 +32,11 @@ func RequireMigrateIfNeeded(rlpCfg config.RollappConfig) { configRollerVersion := version.TrimVersionStr(rlpCfg.RollerVersion) if configRollerVersion != currentRollerVersion { //nolint:errcheck,gosec - color.New(color.FgRed, color.Bold). - Printf("💈 Your rollapp config version ('%s') is older than your"+ + pterm.Warning.Printf( + "💈 Your rollapp config version ('%s') is older than your"+ " installed roller version ('%s'),"+ - " please run 'roller migrate' to update your config.\n", configRollerVersion, currentRollerVersion) + " please run 'roller migrate' to update your config.\n", configRollerVersion, currentRollerVersion, + ) os.Exit(1) } } diff --git a/cmd/utils/key_info.go b/cmd/utils/key_info.go new file mode 100644 index 00000000..a3ab2782 --- /dev/null +++ b/cmd/utils/key_info.go @@ -0,0 +1,111 @@ +package utils + +import ( + "bytes" + "encoding/json" + "fmt" + "os/exec" + + "github.com/pterm/pterm" +) + +// KeyInfo struct stores information about a generated wallet +type KeyInfo struct { + Name string `json:"name"` + Address string `json:"address"` + Mnemonic string `json:"mnemonic"` + PrintName bool + PrintMnemonic bool +} + +type KeyInfoOption func(*KeyInfo) + +func WithName() KeyInfoOption { + return func(opts *KeyInfo) { + opts.PrintName = true + } +} + +func WithMnemonic() KeyInfoOption { + return func(opts *KeyInfo) { + opts.PrintMnemonic = true + } +} + +func (ki *KeyInfo) Print(o ...KeyInfoOption) { + for _, opt := range o { + opt(ki) + } + + if ki.PrintName { + pterm.DefaultBasicText.Println(pterm.LightGreen(ki.Name)) + } + + fmt.Printf("\t%s\n", ki.Address) + + if ki.PrintMnemonic { + fmt.Printf("\t%s\n", ki.Mnemonic) + fmt.Println() + fmt.Println(pterm.LightYellow("💡 save the information and keep it safe")) + } + + fmt.Println() +} + +func ParseAddressFromOutput(output bytes.Buffer) (*KeyInfo, error) { + key := &KeyInfo{} + err := json.Unmarshal(output.Bytes(), key) + if err != nil { + return nil, err + } + return key, nil +} + +func GetAddressBinary(keyConfig KeyConfig, binaryPath string) (*KeyInfo, error) { + showKeyCommand := exec.Command( + binaryPath, + "keys", + "show", + keyConfig.ID, + "--keyring-backend", + "test", + "--keyring-dir", + keyConfig.Dir, + "--output", + "json", + ) + output, err := ExecBashCommandWithStdout(showKeyCommand) + if err != nil { + return nil, err + } + return ParseAddressFromOutput(output) +} + +// TODO: refactor into options, with title +func PrintAddressesWithTitle(addresses []KeyInfo) { + pterm.DefaultSection.WithIndentCharacter("🔑").Println("Addresses") + for _, address := range addresses { + address.Print(WithMnemonic(), WithName()) + } +} + +// TODO: remove this function as it's redundant to PrintAddressesWithTitle +func PrintSecretAddressesWithTitle(addresses []SecretAddressData) { + fmt.Printf("🔑 Addresses:\n") + PrintSecretAddresses(addresses) +} + +// TODO: remove this struct as it's redundant to KeyInfo +type SecretAddressData struct { + AddressData + Mnemonic string +} + +// TODO: remove this function as it's redundant to *KeyInfo.Print +func PrintSecretAddresses(addresses []SecretAddressData) { + for _, address := range addresses { + fmt.Println(address.AddressData.Name) + fmt.Println(address.AddressData.Addr) + fmt.Println(address.Mnemonic) + } +} diff --git a/cmd/utils/keys.go b/cmd/utils/keys.go index 0727a557..169698fd 100644 --- a/cmd/utils/keys.go +++ b/cmd/utils/keys.go @@ -1,8 +1,6 @@ package utils import ( - "bytes" - "encoding/json" "fmt" "os/exec" "path/filepath" @@ -27,78 +25,6 @@ type KeyConfig struct { // TODO: KeyInfo and AddressData seem redundant, should be moved into // location -// KeyInfo struct stores information about a generated wallet -type KeyInfo struct { - Name string `json:"name"` - Address string `json:"address"` - Mnemonic string `json:"mnemonic"` - PrintName bool - PrintMnemonic bool -} - -type KeyInfoOption func(*KeyInfo) - -func WithName() KeyInfoOption { - return func(opts *KeyInfo) { - opts.PrintName = true - } -} - -func WithMnemonic() KeyInfoOption { - return func(opts *KeyInfo) { - opts.PrintMnemonic = true - } -} - -func (ki *KeyInfo) Print(o ...KeyInfoOption) { - for _, opt := range o { - opt(ki) - } - - if ki.PrintName { - pterm.DefaultBasicText.Println(pterm.LightGreen(ki.Name)) - } - - fmt.Printf("\t%s\n", ki.Address) - - if ki.PrintMnemonic { - fmt.Printf("\t%s\n", ki.Mnemonic) - fmt.Println() - fmt.Println(pterm.LightYellow("💡 save the information and keep it safe")) - } - - fmt.Println() -} - -func ParseAddressFromOutput(output bytes.Buffer) (*KeyInfo, error) { - key := &KeyInfo{} - err := json.Unmarshal(output.Bytes(), key) - if err != nil { - return nil, err - } - return key, nil -} - -func GetAddressBinary(keyConfig KeyConfig, binaryPath string) (*KeyInfo, error) { - showKeyCommand := exec.Command( - binaryPath, - "keys", - "show", - keyConfig.ID, - "--keyring-backend", - "test", - "--keyring-dir", - keyConfig.Dir, - "--output", - "json", - ) - output, err := ExecBashCommandWithStdout(showKeyCommand) - if err != nil { - return nil, err - } - return ParseAddressFromOutput(output) -} - func GetRelayerAddress(home string, chainID string) (string, error) { showKeyCmd := exec.Command( consts.Executables.Relayer, @@ -109,6 +35,10 @@ func GetRelayerAddress(home string, chainID string) (string, error) { filepath.Join(home, consts.ConfigDirName.Relayer), ) out, err := ExecBashCommandWithStdout(showKeyCmd) + if err != nil { + pterm.Error.Printf("no relayer address found: %v", err) + return "", err + } return strings.TrimSuffix(out.String(), "\n"), err } @@ -117,35 +47,6 @@ type AddressData struct { Addr string } -// TODO: refactor into options, with title -func PrintAddressesWithTitle(addresses []KeyInfo) { - pterm.DefaultSection.WithIndentCharacter("🔑").Println("Addresses") - for _, address := range addresses { - address.Print(WithMnemonic(), WithName()) - } -} - -// TODO: remove this function as it's redundant to PrintAddressesWithTitle -func PrintSecretAddressesWithTitle(addresses []SecretAddressData) { - fmt.Printf("🔑 Addresses:\n") - PrintSecretAddresses(addresses) -} - -// TODO: remove this struct as it's redundant to KeyInfo -type SecretAddressData struct { - AddressData - Mnemonic string -} - -// TODO: remove this function as it's redundant to *KeyInfo.Print -func PrintSecretAddresses(addresses []SecretAddressData) { - for _, address := range addresses { - fmt.Println(address.AddressData.Name) - fmt.Println(address.AddressData.Addr) - fmt.Println(address.Mnemonic) - } -} - func GetSequencerPubKey(rollappConfig config.RollappConfig) (string, error) { cmd := exec.Command( rollappConfig.RollappBinary, diff --git a/cmd/utils/output.go b/cmd/utils/output.go index 0a50ed3d..21e992d5 100644 --- a/cmd/utils/output.go +++ b/cmd/utils/output.go @@ -33,6 +33,7 @@ func PrintInsufficientBalancesIfAny( addressData.Network, } } + table := tablewriter.NewWriter(os.Stdout) table.SetHeader([]string{"Name", "Address", "Current", "Required", "Network"}) table.SetAlignment(tablewriter.ALIGN_LEFT) @@ -44,6 +45,7 @@ func PrintInsufficientBalancesIfAny( fmt.Println() fmt.Println("💈 Please fund these addresses and try again.") } + PrettifyErrorIfExists( errors.New("the following addresses have insufficient balance to perform this operation"), printAddresses, diff --git a/config/config.go b/config/config.go index 970d0b66..3be3b60b 100644 --- a/config/config.go +++ b/config/config.go @@ -28,7 +28,7 @@ var SupportedDas = []DAType{Celestia, Avail, Local} type RollappConfig struct { Home string `toml:"home"` RollappID string `toml:"rollapp_id"` - RollappBinary string + RollappBinary string `toml:"rollapp_binary"` VMType VMType `toml:"execution"` Denom string `toml:"denom"` // TokenSupply string @@ -47,16 +47,16 @@ type RollappConfig struct { } type HubData = struct { - API_URL string - ID string - RPC_URL string - ARCHIVE_RPC_URL string - GAS_PRICE string - SEQ_MIN_BOND string + API_URL string `toml:"api_url"` + ID string `toml:"id"` + RPC_URL string `toml:"rpc_url"` + ARCHIVE_RPC_URL string `toml:"archive_rpc_url"` + GAS_PRICE string `toml:"gas_price"` + SEQ_MIN_BOND string `toml:"seq_min_bond"` } func (c RollappConfig) Validate() error { - err := VerifyHubID(c.HubData) + err := VerifyHubData(c.HubData) if err != nil { return err } @@ -102,13 +102,17 @@ func IsValidVMType(t string) bool { return false } -func VerifyHubID(data HubData) error { +func VerifyHubData(data HubData) error { if data.ID == "mock" { return nil } + if data.ID == "" { + return fmt.Errorf("invalid hub id: %s. ID cannot be empty", data.ID) + } + if data.RPC_URL == "" { - return fmt.Errorf("invalid hub ID: %s. RPC URL cannot be empty", data.ID) + return fmt.Errorf("invalid RPC endoint: %s. RPC URL cannot be empty", data.ID) } return nil } diff --git a/relayer/channels.go b/relayer/channels.go index c22bb1fc..eb77af4e 100644 --- a/relayer/channels.go +++ b/relayer/channels.go @@ -47,8 +47,10 @@ func (r *Relayer) LoadActiveChannel() (string, string, error) { return "", "", fmt.Errorf("error while decoding JSON: %v", err) } if outputStruct.ConnectionHops[0] != activeConnectionID { - r.logger.Printf("skipping channel %s as it's not on the active connection %s", - outputStruct.ChannelID, activeConnectionID) + r.logger.Printf( + "skipping channel %s as it's not on the active connection %s", + outputStruct.ChannelID, activeConnectionID, + ) continue } @@ -91,7 +93,7 @@ func (r *Relayer) LoadActiveChannel() (string, string, error) { } func (r *Relayer) queryChannelsRollappCmd() *exec.Cmd { - args := []string{"q", "channels", r.RollappID} + args := []string{"q", "connection-channels", r.RollappID, "connection-0"} args = append(args, "--home", filepath.Join(r.Home, consts.ConfigDirName.Relayer)) return exec.Command(consts.Executables.Relayer, args...) } @@ -107,8 +109,11 @@ func (r *Relayer) ChannelReady() bool { } type Counterparty struct { - PortID string `json:"port_id"` - ChannelID string `json:"channel_id"` + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + ChainID string `json:"chain_id"` + ClientID string `json:"client_id"` + ConnectionID string `json:"connection_id"` } type Output struct { @@ -117,6 +122,9 @@ type Output struct { Counterparty Counterparty `json:"counterparty"` ConnectionHops []string `json:"connection_hops"` Version string `json:"version"` + ChainID string `json:"chain_id"` + ChannelID string `json:"channel_id"` + ClientID string `json:"client_id"` } type ProofHeight struct { diff --git a/relayer/config.go b/relayer/config.go index bf9762ee..0cec0404 100644 --- a/relayer/config.go +++ b/relayer/config.go @@ -6,7 +6,8 @@ import ( "os/exec" "path/filepath" - "gopkg.in/yaml.v2" + "github.com/pterm/pterm" + yaml "gopkg.in/yaml.v2" "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/config" @@ -15,6 +16,7 @@ import ( func CreatePath(rlpCfg config.RollappConfig) error { relayerHome := filepath.Join(rlpCfg.Home, consts.ConfigDirName.Relayer) + pterm.Info.Printf("creating new ibc path from %s to %s\n", rlpCfg.HubData.ID, rlpCfg.RollappID) newPathCmd := exec.Command( consts.Executables.Relayer, @@ -69,7 +71,7 @@ func UpdateRlyConfigValue( return fmt.Errorf("failed to marshal updated config: %v", err) } // nolint:gofumpt - return os.WriteFile(rlyConfigPath, newData, 0644) + return os.WriteFile(rlyConfigPath, newData, 0o644) } func ReadRlyConfig(homeDir string) (map[interface{}]interface{}, error) { @@ -93,5 +95,5 @@ func WriteRlyConfig(homeDir string, rlyCfg map[interface{}]interface{}) error { return fmt.Errorf("failed to marshal config: %v", err) } // nolint:gofumpt - return os.WriteFile(rlyConfigPath, data, 0644) + return os.WriteFile(rlyConfigPath, data, 0o644) } diff --git a/relayer/connections.go b/relayer/connections.go index a47ba033..edaa2d18 100644 --- a/relayer/connections.go +++ b/relayer/connections.go @@ -59,7 +59,7 @@ func (r *Relayer) GetActiveConnection() (string, error) { if err != nil { return "", err } - connectionIDRollapp_raw, err := roller_utils.GetNestedValue( + connectionIDRollappRaw, err := roller_utils.GetNestedValue( rlyCfg, []string{"paths", consts.DefaultRelayerPath, "dst", "connection-id"}, ) @@ -76,7 +76,7 @@ func (r *Relayer) GetActiveConnection() (string, error) { } //nolint:errcheck - connectionIDRollapp := connectionIDRollapp_raw.(string) + connectionIDRollapp := connectionIDRollappRaw.(string) //nolint:errcheck connectionIDHub := connectionIDHub_raw.(string) diff --git a/relayer/create_ibc_channel.go b/relayer/create_ibc_channel.go index ac27c036..76785d25 100644 --- a/relayer/create_ibc_channel.go +++ b/relayer/create_ibc_channel.go @@ -8,12 +8,15 @@ import ( "strconv" "time" + "github.com/pterm/pterm" + "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/cmd/utils" "github.com/dymensionxyz/roller/sequencer" ) -// CreateIBCChannel Creates an IBC channel between the hub and the client, and return the source channel ID. +// CreateIBCChannel Creates an IBC channel between the hub and the client, +// and return the source channel ID. func (r *Relayer) CreateIBCChannel( override bool, logFileOption utils.CommandOption, @@ -26,14 +29,16 @@ func (r *Relayer) CreateIBCChannel( // progressing for connection and channel creation. // replaced update clients to avoid account sequence mismatch and // premature heights updates e.g "TrustedHeight {1 x} must be less than header height {1 y}" - sequecerAddress, err := utils.GetAddressBinary(utils.KeyConfig{ - Dir: filepath.Join(seq.RlpCfg.Home, consts.ConfigDirName.Rollapp), - ID: consts.KeysIds.RollappSequencer, - }, seq.RlpCfg.RollappBinary) + sequencerAddress, err := utils.GetAddressBinary( + utils.KeyConfig{ + Dir: filepath.Join(seq.RlpCfg.Home, consts.ConfigDirName.Rollapp), + ID: consts.KeysIds.RollappSequencer, + }, consts.Executables.RollappEVM, + ) if err != nil { return ConnectionChannels{}, err } - sendFundsCmd := seq.GetSendCmd(sequecerAddress.Address) + sendFundsCmd := seq.GetSendCmd(sequencerAddress.Address) utils.RunCommandEvery( ctx, sendFundsCmd.Path, @@ -52,23 +57,25 @@ func (r *Relayer) CreateIBCChannel( } if !clientsExist { // wait for block to be created - status = "Validating rollapp height > 2 before creating clients..." - fmt.Printf("💈 %s\n", status) + pterm.Info.Println("💈 Validating rollapp height > 2 before creating clients...") if err := r.WriteRelayerStatus(status); err != nil { return ConnectionChannels{}, err } + if err := waitForValidRollappHeight(seq); err != nil { + fmt.Println(err) return ConnectionChannels{}, err } + // We always pass override otherwise this command hangs if there are too many clients - // in the hub as it iterates all to check if this client exists createClientsCmd := r.getCreateClientsCmd(true) - status = "Creating clients..." - fmt.Printf("💈 %s\n", status) + pterm.Info.Println("💈 Creating clients...") if err := r.WriteRelayerStatus(status); err != nil { return ConnectionChannels{}, err } + if err := utils.ExecBashCmd(createClientsCmd, logFileOption); err != nil { + fmt.Println(err) return ConnectionChannels{}, err } } @@ -79,8 +86,7 @@ func (r *Relayer) CreateIBCChannel( connectionID, _ := r.GetActiveConnection() if connectionID == "" || override { - status = "Creating connection..." - fmt.Printf("💈 %s\n", status) + pterm.Info.Println("💈 Creating connection...") if err := r.WriteRelayerStatus(status); err != nil { return ConnectionChannels{}, err } @@ -96,25 +102,24 @@ func (r *Relayer) CreateIBCChannel( time.Sleep(15 * time.Second) // we ran create channel with override, as it not recovarable anyway createChannelCmd := r.getCreateChannelCmd(true) - status = "Creating channel..." - fmt.Printf("💈 %s\n", status) + pterm.Info.Println("💈 Creating channel...") if err := r.WriteRelayerStatus(status); err != nil { return ConnectionChannels{}, err } if err := utils.ExecBashCmd(createChannelCmd, logFileOption); err != nil { return ConnectionChannels{}, err } - status = "Validating channel established..." - fmt.Printf("💈 %s\n", status) + status = "" + pterm.Info.Println("💈 Validating channel established...") if err := r.WriteRelayerStatus(status); err != nil { return ConnectionChannels{}, err } - src, dst, err = r.LoadActiveChannel() + _, _, err = r.LoadActiveChannel() if err != nil { return ConnectionChannels{}, err } - if src == "" || dst == "" { + if r.SrcChannel == "" || r.DstChannel == "" { return ConnectionChannels{}, fmt.Errorf("could not load channels") } @@ -133,7 +138,6 @@ func (r *Relayer) CreateIBCChannel( func waitForValidRollappHeight(seq *sequencer.Sequencer) error { logger := utils.GetRollerLogger(seq.RlpCfg.Home) for { - time.Sleep(10 * time.Second) rollappHeightStr, err := seq.GetRollappHeight() if err != nil { logger.Printf("💈 Error getting rollapp height, %s", err.Error()) @@ -155,10 +159,12 @@ func waitForValidRollappHeight(seq *sequencer.Sequencer) error { func (r *Relayer) getCreateClientsCmd(override bool) *exec.Cmd { args := []string{"tx", "clients"} args = append(args, r.getRelayerDefaultArgs()...) + args = append(args, "--log-level", "debug") if override { args = append(args, "--override") } - return exec.Command(consts.Executables.Relayer, args...) + cmd := exec.Command(consts.Executables.Relayer, args...) + return cmd } func (r *Relayer) getCreateConnectionCmd(override bool) *exec.Cmd { diff --git a/relayer/query.go b/relayer/query.go index 1f43efa4..2766cfc3 100644 --- a/relayer/query.go +++ b/relayer/query.go @@ -13,14 +13,18 @@ func GetRolRlyAccData(cfg config.RollappConfig) (*utils.AccountData, error) { if err != nil { return nil, err } - RollappRlyBalance, err := utils.QueryBalance(utils.ChainQueryConfig{ - RPC: seq.GetRPCEndpoint(), - Denom: cfg.Denom, - Binary: cfg.RollappBinary, - }, RollappRlyAddr) + + RollappRlyBalance, err := utils.QueryBalance( + utils.ChainQueryConfig{ + RPC: seq.GetRPCEndpoint(), + Denom: cfg.BaseDenom, + Binary: cfg.RollappBinary, + }, RollappRlyAddr, + ) if err != nil { return nil, err } + return &utils.AccountData{ Address: RollappRlyAddr, Balance: RollappRlyBalance, @@ -29,15 +33,18 @@ func GetRolRlyAccData(cfg config.RollappConfig) (*utils.AccountData, error) { func GetRelayerAccountsData(cfg config.RollappConfig) ([]utils.AccountData, error) { data := []utils.AccountData{} + rollappRlyAcc, err := GetRolRlyAccData(cfg) if err != nil { return nil, err } + data = append(data, *rollappRlyAcc) hubRlyAcc, err := GetHubRlyAccData(cfg) if err != nil { return nil, err } + data = append(data, *hubRlyAcc) return data, nil } @@ -47,14 +54,18 @@ func GetHubRlyAccData(cfg config.RollappConfig) (*utils.AccountData, error) { if err != nil { return nil, err } - HubRlyBalance, err := utils.QueryBalance(utils.ChainQueryConfig{ - RPC: cfg.HubData.RPC_URL, - Denom: consts.Denoms.Hub, - Binary: consts.Executables.Dymension, - }, HubRlyAddr) + + HubRlyBalance, err := utils.QueryBalance( + utils.ChainQueryConfig{ + RPC: cfg.HubData.RPC_URL, + Denom: consts.Denoms.Hub, + Binary: consts.Executables.Dymension, + }, HubRlyAddr, + ) if err != nil { return nil, err } + return &utils.AccountData{ Address: HubRlyAddr, Balance: HubRlyBalance, diff --git a/relayer/relayer_manager.go b/relayer/relayer_manager.go index 6f7fb531..35af9ee3 100644 --- a/relayer/relayer_manager.go +++ b/relayer/relayer_manager.go @@ -34,6 +34,7 @@ func (r *Relayer) SetLogger(logger *log.Logger) { r.logger = logger } +// TODO: review the servicemanager.Service implementation func (r *Relayer) GetRelayerStatus(config.RollappConfig) string { if r.ChannelReady() { return fmt.Sprintf("Active src, %s <-> %s, dst", r.SrcChannel, r.DstChannel) diff --git a/sequencer/config.go b/sequencer/config.go index 85f5643e..0e928707 100644 --- a/sequencer/config.go +++ b/sequencer/config.go @@ -6,7 +6,7 @@ import ( "path/filepath" "strings" - "github.com/pelletier/go-toml" + toml "github.com/pelletier/go-toml" "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/config" diff --git a/sequencer/sequencer_manager.go b/sequencer/sequencer_manager.go index 68f416ef..b1adc236 100644 --- a/sequencer/sequencer_manager.go +++ b/sequencer/sequencer_manager.go @@ -7,6 +7,8 @@ import ( "path/filepath" "sync" + "github.com/pterm/pterm" + "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/config" ) @@ -25,6 +27,7 @@ var ( ) func GetInstance(rlpCfg config.RollappConfig) *Sequencer { + pterm.Info.Println("retrieving sequencer instance") once.Do(func() { seq := &Sequencer{ logger: log.New(io.Discard, "", 0), diff --git a/utils/filesystem.go b/utils/filesystem.go index b1b76b70..30fc3127 100644 --- a/utils/filesystem.go +++ b/utils/filesystem.go @@ -31,7 +31,7 @@ func MoveFile(src, dst string) error { } defer func() { _ = srcFile.Close() }() // nolint:gofumpt - err = os.MkdirAll(filepath.Dir(dst), 0750) + err = os.MkdirAll(filepath.Dir(dst), 0o750) if err != nil { return fmt.Errorf("failed to create parent directories: %w", err) }