From 709500e5df5d3dbe540e260de5e3c00863cfcdbc Mon Sep 17 00:00:00 2001 From: Itay Levy Date: Thu, 6 Jul 2023 10:40:02 +0300 Subject: [PATCH 1/6] Implemented relayer and sequencer status fetching --- cmd/relayer/start/create_ibc_channel.go | 28 ++++---- cmd/relayer/start/get_dst_connection_id.go | 37 ----------- cmd/relayer/start/start.go | 7 +- cmd/run/run.go | 29 +++++---- cmd/utils/fetch_accounts_data.go | 2 +- .../get_active_channel.go | 36 ++++++----- relayer/query_relayer_data.go | 64 +++++++++++++++++++ sequencer/status.go | 47 ++++++++++++++ utils/service_manager/service.go | 38 ++++------- 9 files changed, 182 insertions(+), 106 deletions(-) delete mode 100644 cmd/relayer/start/get_dst_connection_id.go rename cmd/relayer/start/get_active_src_channel.go => relayer/get_active_channel.go (57%) create mode 100644 relayer/query_relayer_data.go create mode 100644 sequencer/status.go diff --git a/cmd/relayer/start/create_ibc_channel.go b/cmd/relayer/start/create_ibc_channel.go index d7e5a907..642014aa 100644 --- a/cmd/relayer/start/create_ibc_channel.go +++ b/cmd/relayer/start/create_ibc_channel.go @@ -2,6 +2,7 @@ package start import ( "fmt" + "github.com/dymensionxyz/roller/relayer" "os/exec" "path/filepath" @@ -11,47 +12,48 @@ import ( ) // Creates an IBC channel between the hub and the client, and return the source channel ID. -func createIBCChannelIfNeeded(rollappConfig config.RollappConfig, logFileOption utils.CommandOption) (string, error) { +func createIBCChannelIfNeeded(rollappConfig config.RollappConfig, logFileOption utils.CommandOption) ( + relayer.ConnectionChannels, error) { createClientsCmd := getCreateClientsCmd(rollappConfig, rollappConfig.RollappID, rollappConfig.HubData.ID) fmt.Println("Creating clients...") if err := utils.ExecBashCmdWithOSOutput(createClientsCmd, logFileOption); err != nil { - return "", err + return relayer.ConnectionChannels{}, err } - dstConnectionId, err := GetDstConnectionIDFromYAMLFile(filepath.Join(rollappConfig.Home, consts.ConfigDirName.Relayer, + dstConnectionId, err := relayer.GetDstConnectionIDFromYAMLFile(filepath.Join(rollappConfig.Home, consts.ConfigDirName.Relayer, "config", "config.yaml")) if err != nil { - return "", err + return relayer.ConnectionChannels{}, err } if dstConnectionId == "" { // Before setting up the connection, we need to call update clients updateClientsCmd := getUpdateClientsCmd(rollappConfig) fmt.Println("Updating clients...") if err := utils.ExecBashCmdWithOSOutput(updateClientsCmd, logFileOption); err != nil { - return "", err + return relayer.ConnectionChannels{}, err } createConnectionCmd := getCreateConnectionCmd(rollappConfig) fmt.Println("Creating connection...") if err := utils.ExecBashCmdWithOSOutput(createConnectionCmd, logFileOption); err != nil { - return "", err + return relayer.ConnectionChannels{}, err } } - srcChannelId, err := GetSourceChannelForConnection(dstConnectionId, rollappConfig) + connectionChannels, err := relayer.GetConnectionChannels(dstConnectionId, rollappConfig) if err != nil { - return "", err + return relayer.ConnectionChannels{}, err } - if srcChannelId == "" { + if connectionChannels.Src == "" { createChannelCmd := getCreateChannelCmd(rollappConfig) fmt.Println("Creating channel...") if err := utils.ExecBashCmdWithOSOutput(createChannelCmd, logFileOption); err != nil { - return "", err + return relayer.ConnectionChannels{}, err } - srcChannelId, err = GetSourceChannelForConnection(dstConnectionId, rollappConfig) + connectionChannels, err = relayer.GetConnectionChannels(dstConnectionId, rollappConfig) if err != nil { - return "", err + return relayer.ConnectionChannels{}, err } } - return srcChannelId, nil + return connectionChannels, nil } func getCreateChannelCmd(config config.RollappConfig) *exec.Cmd { diff --git a/cmd/relayer/start/get_dst_connection_id.go b/cmd/relayer/start/get_dst_connection_id.go deleted file mode 100644 index 7bee7025..00000000 --- a/cmd/relayer/start/get_dst_connection_id.go +++ /dev/null @@ -1,37 +0,0 @@ -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 46b6778f..acc912ec 100644 --- a/cmd/relayer/start/start.go +++ b/cmd/relayer/start/start.go @@ -31,13 +31,14 @@ func Start() *cobra.Command { utils.PrettifyErrorIfExists(err) relayerLogFilePath := utils.GetRelayerLogPath(rollappConfig) logFileOption := utils.WithLogging(relayerLogFilePath) - srcChannelId, err := createIBCChannelIfNeeded(rollappConfig, logFileOption) + connectionChannels, err := createIBCChannelIfNeeded(rollappConfig, logFileOption) utils.PrettifyErrorIfExists(err) updateClientsCmd := getUpdateClientsCmd(rollappConfig) utils.RunCommandEvery(updateClientsCmd.Path, updateClientsCmd.Args[1:], 60, logFileOption) - relayPacketsCmd := getRelayPacketsCmd(rollappConfig, srcChannelId) + relayPacketsCmd := getRelayPacketsCmd(rollappConfig, connectionChannels.Src) utils.RunCommandEvery(relayPacketsCmd.Path, relayPacketsCmd.Args[1:], 30, logFileOption) - fmt.Printf("💈 The relayer is running successfully on you local machine on channel %s!", srcChannelId) + fmt.Printf("💈 The relayer is running successfully on you local machine! Channels: %s <-> %s", + connectionChannels.Src, connectionChannels.Dst) select {} }, } diff --git a/cmd/run/run.go b/cmd/run/run.go index f5d2f792..7ffd4236 100644 --- a/cmd/run/run.go +++ b/cmd/run/run.go @@ -2,6 +2,8 @@ package run import ( "context" + "github.com/dymensionxyz/roller/relayer" + "github.com/dymensionxyz/roller/sequencer" "os" "os/exec" "sync" @@ -53,10 +55,11 @@ func Cmd() *cobra.Command { func runRelayerWithRestarts(cfg config.RollappConfig, serviceConfig *servicemanager.ServiceConfig) { startRelayerCmd := getStartRelayerCmd(cfg) - service := servicemanager.ServiceData{ - Command: startRelayerCmd, - FetchFn: utils.GetRelayerAddresses, - UIData: servicemanager.UIData{Name: "Relayer"}, + service := servicemanager.Service{ + Command: startRelayerCmd, + FetchFn: utils.GetRelayerAccountsData, + UIData: servicemanager.UIData{Name: "Relayer"}, + StatusFn: relayer.GetRelayerStatus, } serviceConfig.AddService("Relayer", service) serviceConfig.RunServiceWithRestart("Relayer") @@ -78,10 +81,11 @@ func runDaWithRestarts(rollappConfig config.RollappConfig, serviceConfig *servic return } - service := servicemanager.ServiceData{ - Command: startDALCCmd, - FetchFn: damanager.GetDAAccData, - UIData: servicemanager.UIData{Name: "DA Light Client"}, + service := servicemanager.Service{ + Command: startDALCCmd, + FetchFn: damanager.GetDAAccData, + StatusFn: damanager.GetStatus, + UIData: servicemanager.UIData{Name: "DA Light Client"}, } serviceConfig.AddService("DA Light Client", service) serviceConfig.RunServiceWithRestart("DA Light Client", utils.WithLogging(daLogFilePath)) @@ -89,10 +93,11 @@ func runDaWithRestarts(rollappConfig config.RollappConfig, serviceConfig *servic func runSequencerWithRestarts(rollappConfig config.RollappConfig, serviceConfig *servicemanager.ServiceConfig) { startRollappCmd := sequnecer_start.GetStartRollappCmd(rollappConfig, consts.DefaultDALCRPC) - service := servicemanager.ServiceData{ - Command: startRollappCmd, - FetchFn: utils.GetSequencerData, - UIData: servicemanager.UIData{Name: "Sequencer"}, + service := servicemanager.Service{ + Command: startRollappCmd, + FetchFn: utils.GetSequencerData, + StatusFn: sequencer.GetSequencerStatus, + UIData: servicemanager.UIData{Name: "Sequencer"}, } serviceConfig.AddService("Sequencer", service) serviceConfig.RunServiceWithRestart("Sequencer", utils.WithLogging(utils.GetSequencerLogPath(rollappConfig))) diff --git a/cmd/utils/fetch_accounts_data.go b/cmd/utils/fetch_accounts_data.go index 9f3d8de9..de97878f 100644 --- a/cmd/utils/fetch_accounts_data.go +++ b/cmd/utils/fetch_accounts_data.go @@ -7,7 +7,7 @@ import ( "github.com/dymensionxyz/roller/config" ) -func GetRelayerAddresses(cfg config.RollappConfig) ([]AccountData, error) { +func GetRelayerAccountsData(cfg config.RollappConfig) ([]AccountData, error) { data := []AccountData{} rollappRlyAcc, err := GetRolRlyAccData(cfg) if err != nil { diff --git a/cmd/relayer/start/get_active_src_channel.go b/relayer/get_active_channel.go similarity index 57% rename from cmd/relayer/start/get_active_src_channel.go rename to relayer/get_active_channel.go index 19e12453..212df605 100644 --- a/cmd/relayer/start/get_active_src_channel.go +++ b/relayer/get_active_channel.go @@ -1,34 +1,33 @@ -package start +package relayer import ( "encoding/json" - "os/exec" - "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/cmd/utils" "github.com/dymensionxyz/roller/config" + "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 config.RollappConfig) (string, error) { +func GetConnectionChannels(dstConnectionID string, rollappConfig config.RollappConfig) ( + ConnectionChannels, 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 + return ConnectionChannels{}, err } - channelId, err := GetOpenStateChannelID(out) + channels, err := extractChannelsFromResponse(out) if err != nil { - return "", err + return ConnectionChannels{}, err } - return channelId, nil + return channels, nil } type Channel struct { State string `json:"state"` + ChannelID string `json:"channel_id"` Counterparty struct { ChannelID string `json:"channel_id"` } `json:"counterparty"` @@ -38,16 +37,23 @@ type ChannelList struct { Channels []Channel `json:"channels"` } -func GetOpenStateChannelID(jsonData []byte) (string, error) { +type ConnectionChannels struct { + Src string + Dst string +} + +func extractChannelsFromResponse(jsonData []byte) (ConnectionChannels, error) { var channels ChannelList if err := json.Unmarshal(jsonData, &channels); err != nil { - return "", err + return ConnectionChannels{}, err } - for _, channel := range channels.Channels { if channel.State == "STATE_OPEN" { - return channel.Counterparty.ChannelID, nil + return ConnectionChannels{ + Src: channel.Counterparty.ChannelID, + Dst: channel.ChannelID, + }, nil } } - return "", nil + return ConnectionChannels{}, nil } diff --git a/relayer/query_relayer_data.go b/relayer/query_relayer_data.go new file mode 100644 index 00000000..2e33c487 --- /dev/null +++ b/relayer/query_relayer_data.go @@ -0,0 +1,64 @@ +package relayer + +import ( + "fmt" + "github.com/dymensionxyz/roller/cmd/consts" + "github.com/dymensionxyz/roller/config" + "gopkg.in/yaml.v2" + "io/ioutil" + "path/filepath" +) + +func GetRelayerStatus(config config.RollappConfig) string { + channels, err := GetChannels(config) + if err != nil || channels.Src == "" { + return fmt.Sprintf("Starting...") + } + return fmt.Sprintf("Active %s <-> %s", channels.Src, channels.Dst) +} + +func GetChannels(rollappConfig config.RollappConfig) (ConnectionChannels, error) { + dstConnectionId, err := GetDstConnectionIDFromYAMLFile(filepath.Join(rollappConfig.Home, consts.ConfigDirName.Relayer, + "config", "config.yaml")) + if err != nil { + return ConnectionChannels{}, err + } + if dstConnectionId == "" { + return ConnectionChannels{}, nil + } + connectionChannels, err := GetConnectionChannels(dstConnectionId, rollappConfig) + if err != nil { + return ConnectionChannels{}, err + } + return connectionChannels, nil +} + +// 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") +} + +type RelayerConfigFile struct { + Paths map[string]Path `yaml:"paths"` +} + +type Path struct { + Dst Destination `yaml:"dst"` +} + +type Destination struct { + ConnectionID string `yaml:"connection-id"` +} diff --git a/sequencer/status.go b/sequencer/status.go new file mode 100644 index 00000000..09a730c5 --- /dev/null +++ b/sequencer/status.go @@ -0,0 +1,47 @@ +package sequencer + +import ( + "encoding/json" + "fmt" + "github.com/dymensionxyz/roller/cmd/consts" + "github.com/dymensionxyz/roller/config" + "io/ioutil" + "net/http" +) + +type NodeInfo struct { + Network string `json:"network"` +} + +type Result struct { + NodeInfo NodeInfo `json:"node_info"` +} + +type Response struct { + Result Result `json:"result"` +} + +func IsSeqListen(rollappID string) bool { + resp, err := http.Get(fmt.Sprintf("%s/status", consts.DefaultRollappRPC)) + if err != nil { + return false + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return false + } + var response Response + if err := json.Unmarshal(body, &response); err != nil { + return false + } + return response.Result.NodeInfo.Network == rollappID +} + +func GetSequencerStatus(cfg config.RollappConfig) string { + // TODO: Make sure the sequencer status endpoint is being changed after block production is paused. + if IsSeqListen(cfg.RollappID) { + return "Active" + } + return "Stopped, Restarting..." +} diff --git a/utils/service_manager/service.go b/utils/service_manager/service.go index f95af150..cd7b6e4c 100644 --- a/utils/service_manager/service.go +++ b/utils/service_manager/service.go @@ -3,7 +3,6 @@ package servicemanager import ( "context" "log" - "math/big" "os/exec" "sync" "time" @@ -16,7 +15,7 @@ type ServiceConfig struct { Context context.Context WaitGroup *sync.WaitGroup Logger *log.Logger - Services map[string]ServiceData + Services map[string]Service } type UIData struct { @@ -27,20 +26,11 @@ type UIData struct { Status string } -type ServiceData struct { - Command *exec.Cmd - FetchFn func(config.RollappConfig) ([]utils.AccountData, error) - UIData UIData -} - -// TODO: move this to a separate file -// TODO: status should be Enum -func activeIfSufficientBalance(currentBalance, threshold *big.Int) string { - if currentBalance.Cmp(threshold) >= 0 { - return "Active" - } else { - return "Stopped" - } +type Service struct { + Command *exec.Cmd + FetchFn func(config.RollappConfig) ([]utils.AccountData, error) + StatusFn func(config.RollappConfig) string + UIData UIData } // TODO: fetch all data and populate UIData @@ -54,14 +44,12 @@ func (s *ServiceConfig) FetchServicesData(cfg config.RollappConfig) { return } service.UIData.Accounts = accountData - - //FIXME: the status function should be part of the service - for _, account := range accountData { - service.UIData.Status = activeIfSufficientBalance(account.Balance.Amount, big.NewInt(1)) - } - if k == "Relayer" { - service.UIData.Status = "Starting..." + if service.StatusFn != nil { + service.UIData.Status = service.StatusFn(cfg) } + //if k == "Relayer" { + // service.UIData.Status = "Starting..." + //} s.Services[k] = service } @@ -76,9 +64,9 @@ func (s *ServiceConfig) GetUIData() []UIData { return uiData } -func (s *ServiceConfig) AddService(name string, data ServiceData) { +func (s *ServiceConfig) AddService(name string, data Service) { if s.Services == nil { - s.Services = make(map[string]ServiceData) + s.Services = make(map[string]Service) } s.Services[name] = data From 0a995f35259143139c5d89d128fc44b8068af4fa Mon Sep 17 00:00:00 2001 From: Itay Levy Date: Thu, 6 Jul 2023 10:44:30 +0300 Subject: [PATCH 2/6] removed comments --- utils/service_manager/service.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/utils/service_manager/service.go b/utils/service_manager/service.go index cd7b6e4c..bf0086a5 100644 --- a/utils/service_manager/service.go +++ b/utils/service_manager/service.go @@ -47,9 +47,6 @@ func (s *ServiceConfig) FetchServicesData(cfg config.RollappConfig) { if service.StatusFn != nil { service.UIData.Status = service.StatusFn(cfg) } - //if k == "Relayer" { - // service.UIData.Status = "Starting..." - //} s.Services[k] = service } From ef50567ec593190eebb51a3250c50965be41bb08 Mon Sep 17 00:00:00 2001 From: Itay Levy Date: Thu, 6 Jul 2023 11:07:10 +0300 Subject: [PATCH 3/6] Added status func to DA --- data_layer/celestia/celestia.go | 5 +++++ data_layer/da_layer.go | 1 + data_layer/damock/damock.go | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/data_layer/celestia/celestia.go b/data_layer/celestia/celestia.go index d59e2172..86b5292c 100644 --- a/data_layer/celestia/celestia.go +++ b/data_layer/celestia/celestia.go @@ -30,6 +30,11 @@ type Celestia struct { rpcEndpoint string } +func (c2 *Celestia) GetStatus(c config.RollappConfig) string { + //TODO implement me + return "" +} + func (c *Celestia) GetLightNodeEndpoint() string { return LCEndpoint } diff --git a/data_layer/da_layer.go b/data_layer/da_layer.go index bf3d8754..f503dbf8 100644 --- a/data_layer/da_layer.go +++ b/data_layer/da_layer.go @@ -18,6 +18,7 @@ type DataLayer interface { GetLightNodeEndpoint() string SetRPCEndpoint(string) GetNetworkName() string + GetStatus(c config.RollappConfig) string } type DAManager struct { diff --git a/data_layer/damock/damock.go b/data_layer/damock/damock.go index df74e6cf..b4b2bcab 100644 --- a/data_layer/damock/damock.go +++ b/data_layer/damock/damock.go @@ -12,6 +12,11 @@ import ( type DAMock struct { } +func (d *DAMock) GetStatus(c config.RollappConfig) string { + //TODO implement me + return "" +} + func NewDAMock() *DAMock { return &DAMock{} } From ce71901eaf32b29182daf695130a404fede87401 Mon Sep 17 00:00:00 2001 From: Itay Levy Date: Thu, 6 Jul 2023 12:27:17 +0300 Subject: [PATCH 4/6] Added indication for the source and destination channels --- cmd/relayer/start/start.go | 2 +- relayer/query_relayer_data.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/relayer/start/start.go b/cmd/relayer/start/start.go index acc912ec..30300307 100644 --- a/cmd/relayer/start/start.go +++ b/cmd/relayer/start/start.go @@ -37,7 +37,7 @@ func Start() *cobra.Command { utils.RunCommandEvery(updateClientsCmd.Path, updateClientsCmd.Args[1:], 60, logFileOption) relayPacketsCmd := getRelayPacketsCmd(rollappConfig, connectionChannels.Src) utils.RunCommandEvery(relayPacketsCmd.Path, relayPacketsCmd.Args[1:], 30, logFileOption) - fmt.Printf("💈 The relayer is running successfully on you local machine! Channels: %s <-> %s", + fmt.Printf("💈 The relayer is running successfully on you local machine! Channels: src, %s <-> %s, dst", connectionChannels.Src, connectionChannels.Dst) select {} }, diff --git a/relayer/query_relayer_data.go b/relayer/query_relayer_data.go index 2e33c487..9acbb321 100644 --- a/relayer/query_relayer_data.go +++ b/relayer/query_relayer_data.go @@ -14,7 +14,7 @@ func GetRelayerStatus(config config.RollappConfig) string { if err != nil || channels.Src == "" { return fmt.Sprintf("Starting...") } - return fmt.Sprintf("Active %s <-> %s", channels.Src, channels.Dst) + return fmt.Sprintf("Active src, %s <-> %s, dst", channels.Src, channels.Dst) } func GetChannels(rollappConfig config.RollappConfig) (ConnectionChannels, error) { From 81025b715c9331c0fc3d83f92bc02e71279acb52 Mon Sep 17 00:00:00 2001 From: Itay Levy Date: Thu, 6 Jul 2023 14:15:14 +0300 Subject: [PATCH 5/6] Added service interface todo --- utils/service_manager/service.go | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/service_manager/service.go b/utils/service_manager/service.go index bf0086a5..dd9620e2 100644 --- a/utils/service_manager/service.go +++ b/utils/service_manager/service.go @@ -26,6 +26,7 @@ type UIData struct { Status string } +// Service TODO: The relayer, sequencer and data layer should implement the Service interface (#208) type Service struct { Command *exec.Cmd FetchFn func(config.RollappConfig) ([]utils.AccountData, error) From 0d63ac47fcaf25fba3641659c956de1cb8fc6ad5 Mon Sep 17 00:00:00 2001 From: Itay Levy Date: Thu, 6 Jul 2023 14:15:58 +0300 Subject: [PATCH 6/6] removed redundant todo from mock --- data_layer/damock/damock.go | 1 - 1 file changed, 1 deletion(-) diff --git a/data_layer/damock/damock.go b/data_layer/damock/damock.go index b4b2bcab..74676217 100644 --- a/data_layer/damock/damock.go +++ b/data_layer/damock/damock.go @@ -13,7 +13,6 @@ type DAMock struct { } func (d *DAMock) GetStatus(c config.RollappConfig) string { - //TODO implement me return "" }