From 207b17a025c0afb1283a4543ffe1a5d13eaff0ba Mon Sep 17 00:00:00 2001 From: artpav <19916123+artemijspavlovs@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:15:01 +0300 Subject: [PATCH] fix(relayer run): wait for rollapp to be healthy after block time change (#861) --- cmd/relayer/run/run.go | 6 +-- relayer/create_ibc_channel.go | 45 +++++++++++---------- utils/dymint/dymint.go | 73 +++++++++++++++++++++++++++++++---- 3 files changed, 91 insertions(+), 33 deletions(-) diff --git a/cmd/relayer/run/run.go b/cmd/relayer/run/run.go index 9ef03c9e..61e3c4ba 100644 --- a/cmd/relayer/run/run.go +++ b/cmd/relayer/run/run.go @@ -134,7 +134,7 @@ func Cmd() *cobra.Command { if currentHeight <= 2 { pterm.Warning.Println("current height is too low, updating dymint config") - err = dymintutils.UpdateDymintConfigForIBC(home, "5s") + err = dymintutils.UpdateDymintConfigForIBC(home, "5s", false) if err != nil { pterm.Error.Println("failed to update dymint config") return @@ -220,7 +220,7 @@ func Cmd() *cobra.Command { pterm.Info.Println( "updating dymint config to 5s block time for relayer configuration", ) - err = dymintutils.UpdateDymintConfigForIBC(home, "5s") + err = dymintutils.UpdateDymintConfigForIBC(home, "5s", false) if err != nil { pterm.Error.Println( "failed to update dymint config for ibc creation", @@ -340,7 +340,7 @@ func Cmd() *cobra.Command { ) pterm.Info.Println("reverting dymint config to 1h") - err = dymintutils.UpdateDymintConfigForIBC(home, "1h0m0s") + err = dymintutils.UpdateDymintConfigForIBC(home, "1h0m0s", true) if err != nil { pterm.Error.Println("failed to update dymint config") return diff --git a/relayer/create_ibc_channel.go b/relayer/create_ibc_channel.go index cf881dd8..b9ac8615 100644 --- a/relayer/create_ibc_channel.go +++ b/relayer/create_ibc_channel.go @@ -1,7 +1,6 @@ package relayer import ( - "context" "fmt" "os/exec" "path/filepath" @@ -23,32 +22,32 @@ func (r *Relayer) CreateIBCChannel( logFileOption bash.CommandOption, seq *sequencer.Sequencer, ) (ConnectionChannels, error) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + // ctx, cancel := context.WithCancel(context.Background()) + // defer cancel() // Run send funds command from sequencer to itself to make sure the chain is // 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}" - 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(sequencerAddress) - bash.RunCommandEvery( - ctx, - sendFundsCmd.Path, - sendFundsCmd.Args[1:], - 5, - utils.WithDiscardLogging(), - ) - + // 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(sequencerAddress) + // bash.RunCommandEvery( + // ctx, + // sendFundsCmd.Path, + // sendFundsCmd.Args[1:], + // 5, + // utils.WithDiscardLogging(), + // ) + // var status string // Create client if it doesn't exist or override is true @@ -117,7 +116,7 @@ func (r *Relayer) CreateIBCChannel( return ConnectionChannels{}, err } - _, _, err = r.LoadActiveChannel() + _, _, err := r.LoadActiveChannel() if err != nil { return ConnectionChannels{}, err } diff --git a/utils/dymint/dymint.go b/utils/dymint/dymint.go index eb387a8d..6605801e 100644 --- a/utils/dymint/dymint.go +++ b/utils/dymint/dymint.go @@ -1,6 +1,10 @@ package dymint import ( + "encoding/json" + "fmt" + "io" + "net/http" "os/exec" "time" @@ -61,7 +65,16 @@ type dymintInstrumentationConfig struct { PrometheusListenAddr string `toml:"prometheus_listen_addr"` } -func UpdateDymintConfigForIBC(home string, t string) error { +type RollappHealthResponse struct { + JSONRPC string `json:"jsonrpc"` + Result struct { + IsHealthy bool `json:"isHealthy"` + Error string `json:"error"` + } `json:"result"` + ID int `json:"id"` +} + +func UpdateDymintConfigForIBC(home string, t string, forceUpdate bool) error { pterm.Info.Println("checking dymint block time settings") dymintPath := sequencer.GetDymintFilePath(home) dymintCfg, err := tomlconfig.Load(dymintPath) @@ -86,11 +99,13 @@ func UpdateDymintConfigForIBC(home string, t string) error { return err } - if want < have { - pterm.Info.Println( - "block time is higher then recommended when creating ibc channels: ", - have, - ) + if want < have || forceUpdate { + if want < have { + pterm.Info.Println( + "block time is higher then recommended when creating ibc channels: ", + have, + ) + } pterm.Info.Println("updating dymint config") err = utils.UpdateFieldInToml(dymintPath, "max_idle_time", want.String()) @@ -117,8 +132,8 @@ func UpdateDymintConfigForIBC(home string, t string) error { "sudo", "systemctl", "restart", "rollapp", ) - // TODO: check for the systemd service status and /health endpoint instead time.Sleep(time.Second * 2) + waitForHealthyRollApp("http://localhost:26657") _, err = bash.ExecCommandWithStdout(cmd) if err != nil { return err @@ -129,3 +144,47 @@ func UpdateDymintConfigForIBC(home string, t string) error { return nil } + +func waitForHealthyRollApp(url string) { + timeout := time.After(20 * time.Second) + ticker := time.NewTicker(2 * time.Second) + defer ticker.Stop() + + spinner, _ := pterm.DefaultSpinner.Start("waiting for rollapp to become healthy") + + for { + select { + case <-timeout: + spinner.Fail("Timeout: Failed to receive expected response within 20 seconds") + return + case <-ticker.C: + // nolint:gosec + resp, err := http.Get(url) + if err != nil { + fmt.Printf("Error making request: %v\n", err) + continue + } + // nolint:errcheck + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Printf("Error reading response body: %v\n", err) + continue + } + + var response RollappHealthResponse + err = json.Unmarshal(body, &response) + if err != nil { + fmt.Printf("Error unmarshaling JSON: %v\n", err) + continue + } + + if response.Result.IsHealthy { + spinner.Success("RollApp is healthy") + fmt.Printf("%+v\n", response) + return + } + } + } +}