From f1c316c712cd2fc459fd19548c4f0433c0ce4ed3 Mon Sep 17 00:00:00 2001 From: shreyasbhat0 Date: Tue, 12 Dec 2023 12:54:31 +0530 Subject: [PATCH] fix: service public port allocation error --- cli/cmd/bridge/btp/cmd.go | 4 ++- cli/cmd/bridge/btp/run.go | 3 ++- cli/cmd/bridge/ibc/cmd.go | 4 ++- cli/cmd/bridge/utils/types.go | 4 ++- cli/cmd/chains/archway/cmd.go | 6 ++++- cli/cmd/chains/eth/cmd.go | 5 ++-- cli/cmd/chains/hardhat/cmd.go | 5 ++-- cli/cmd/chains/hardhat/run.go | 6 ++--- cli/cmd/chains/icon/cmd.go | 5 +++- cli/cmd/chains/neutron/cmd.go | 5 +++- cli/cmd/chains/utils/types.go | 47 +++++++++++++++++++++++++++++------ cli/cmd/root.go | 5 ++++ cli/cmd/utility/clean.go | 18 +++++++++----- cli/common/cli.go | 6 +++-- cli/common/constants.go | 7 +++--- cli/common/errors.go | 1 + cli/common/types.go | 2 +- cli/common/utils.go | 41 +++++++++++++++++++++++++----- 18 files changed, 134 insertions(+), 40 deletions(-) diff --git a/cli/cmd/bridge/btp/cmd.go b/cli/cmd/bridge/btp/cmd.go index 5c47ab2c..343b659d 100644 --- a/cli/cmd/bridge/btp/cmd.go +++ b/cli/cmd/bridge/btp/cmd.go @@ -56,7 +56,9 @@ func btpRelay(cmd *cobra.Command, args []string) { cliContext.Fatal(err) } - err = cliContext.FileHandler().WriteFile("dive.json", []byte(result)) + serviceFileName := fmt.Sprintf(common.DiveOutFile, common.EnclaveName) + + err = cliContext.FileHandler().WriteFile(serviceFileName, []byte(result)) if err != nil { cliContext.Fatal(err) } diff --git a/cli/cmd/bridge/btp/run.go b/cli/cmd/bridge/btp/run.go index 87c61d60..e0e93459 100644 --- a/cli/cmd/bridge/btp/run.go +++ b/cli/cmd/bridge/btp/run.go @@ -128,7 +128,8 @@ func runBtpSetupWhenChainsAreNotIcon(cli *common.Cli, enclaveContext *enclaves.E func runBtpSetupWhenSingleChainRunning(cli *common.Cli, enclaveContext *enclaves.EnclaveContext, chains *utils.Chains, bridge bool) (string, error) { var chainAServiceResponse, chainBServiceResponse, chainAServiceName, chainBServiceName, response string var services = common.Services{} - err := cli.FileHandler().ReadJson("services.json", &services) + serviceFileName := fmt.Sprintf(common.ServiceFilePath, common.EnclaveName) + err := cli.FileHandler().ReadJson(serviceFileName, &services) if err != nil { return "", common.WrapMessageToError(err, fmt.Sprintf("BTP Setup Failed For ChainA %s and ChainB %s", chains.ChainA, chains.ChainB)) diff --git a/cli/cmd/bridge/ibc/cmd.go b/cli/cmd/bridge/ibc/cmd.go index 43abbadf..97a37441 100644 --- a/cli/cmd/bridge/ibc/cmd.go +++ b/cli/cmd/bridge/ibc/cmd.go @@ -43,7 +43,9 @@ func ibcRelay(cmd *cobra.Command, args []string) { cliContext.Fatal(err) } - err = cliContext.FileHandler().WriteFile("dive.json", []byte(result)) + serviceFileName := fmt.Sprintf(common.DiveOutFile, common.EnclaveName) + + err = cliContext.FileHandler().WriteFile(serviceFileName, []byte(result)) if err != nil { cliContext.Fatal(err) } diff --git a/cli/cmd/bridge/utils/types.go b/cli/cmd/bridge/utils/types.go index ed860391..b4dab2ae 100644 --- a/cli/cmd/bridge/utils/types.go +++ b/cli/cmd/bridge/utils/types.go @@ -55,7 +55,9 @@ func (chains *Chains) GetServicesResponse(cli *common.Cli) (string, string, erro var serviceConfig = common.Services{} - err := cli.FileHandler().ReadJson("services.json", &serviceConfig) + serviceFileName := fmt.Sprintf(common.ServiceFilePath, common.EnclaveName) + + err := cli.FileHandler().ReadJson(serviceFileName, &serviceConfig) if err != nil { return "", "", err diff --git a/cli/cmd/chains/archway/cmd.go b/cli/cmd/chains/archway/cmd.go index 41db6e7b..751d3c1b 100644 --- a/cli/cmd/chains/archway/cmd.go +++ b/cli/cmd/chains/archway/cmd.go @@ -1,6 +1,8 @@ package archway import ( + "fmt" + "github.com/hugobyte/dive-core/cli/common" "github.com/spf13/cobra" ) @@ -40,7 +42,9 @@ func archway(cmd *cobra.Command, args []string) { cliContext.Fatal(err) } - err = common.WriteServiceResponseData(response.ServiceName, *response, cliContext) + serviceFileName := fmt.Sprintf(common.ServiceFilePath, common.EnclaveName) + + err = common.WriteServiceResponseData(response.ServiceName, *response, cliContext, serviceFileName) if err != nil { cliContext.Fatal(err) diff --git a/cli/cmd/chains/eth/cmd.go b/cli/cmd/chains/eth/cmd.go index 965bb939..743068ab 100644 --- a/cli/cmd/chains/eth/cmd.go +++ b/cli/cmd/chains/eth/cmd.go @@ -1,6 +1,7 @@ package eth import ( + "fmt" "strings" "github.com/hugobyte/dive-core/cli/common" @@ -36,8 +37,8 @@ func eth(cmd *cobra.Command, args []string) { cliContext.Fatal(err) } } - - err = common.WriteServiceResponseData(responseData.ServiceName, *responseData, cliContext) + serviceFileName := fmt.Sprintf(common.ServiceFilePath, common.EnclaveName) + err = common.WriteServiceResponseData(responseData.ServiceName, *responseData, cliContext, serviceFileName) if err != nil { cliContext.Fatal(err) diff --git a/cli/cmd/chains/hardhat/cmd.go b/cli/cmd/chains/hardhat/cmd.go index e4f19fdc..bf707301 100644 --- a/cli/cmd/chains/hardhat/cmd.go +++ b/cli/cmd/chains/hardhat/cmd.go @@ -1,6 +1,7 @@ package hardhat import ( + "fmt" "strings" "github.com/hugobyte/dive-core/cli/common" @@ -35,8 +36,8 @@ func hardhat(cmd *cobra.Command, args []string) { cliContext.Fatal(err) } } - - err = common.WriteServiceResponseData(responseData.ServiceName, *responseData, cliContext) + serviceFileName := fmt.Sprintf(common.ServiceFilePath, common.EnclaveName) + err = common.WriteServiceResponseData(responseData.ServiceName, *responseData, cliContext, serviceFileName) if err != nil { cliContext.Fatal(err) diff --git a/cli/cmd/chains/hardhat/run.go b/cli/cmd/chains/hardhat/run.go index 4997c46b..7fa65f84 100644 --- a/cli/cmd/chains/hardhat/run.go +++ b/cli/cmd/chains/hardhat/run.go @@ -7,7 +7,7 @@ func RunHardhat(cli *common.Cli) (*common.DiveServiceResponse, error) { enclaveContext, err := cli.Context().GetEnclaveContext(common.EnclaveName) if err != nil { - return nil, common.WrapMessageToError(err, "Hardhat Run Failed") + return nil, common.WrapMessageToError(err, "Hardhat Run Failed While Getting Enclave Context") } runConfig := common.GetStarlarkRunConfig(`{}`, common.DiveEthHardhatNodeScript, "start_hardhat_node") @@ -15,14 +15,14 @@ func RunHardhat(cli *common.Cli) (*common.DiveServiceResponse, error) { response, _, err := enclaveContext.RunStarlarkRemotePackage(cli.Context().GetContext(), common.DiveRemotePackagePath, runConfig) if err != nil { - return nil, common.WrapMessageToErrorf(common.ErrStarlarkRunFailed, "%s. %s", err, "Hardhat Run Failed") + return nil, common.WrapMessageToErrorf(common.ErrStarlarkRunFailed, "%s. %s", err, "Hardhat Run Failed While Executing Starlark Package.") } responseData, services, skippedInstructions, err := common.GetSerializedData(cli, response) if err != nil { errRemove := cli.Context().RemoveServicesByServiceNames(services, common.EnclaveName) if errRemove != nil { - return nil, common.WrapMessageToError(errRemove, "Hardhat Run Failed ") + return nil, common.WrapMessageToError(errRemove, "Hardhat Run Failed .Services Removed") } return nil, common.WrapMessageToError(err, "Hardhat Run Failed ") diff --git a/cli/cmd/chains/icon/cmd.go b/cli/cmd/chains/icon/cmd.go index ada7c373..b3f95537 100644 --- a/cli/cmd/chains/icon/cmd.go +++ b/cli/cmd/chains/icon/cmd.go @@ -1,6 +1,8 @@ package icon import ( + "fmt" + "github.com/hugobyte/dive-core/cli/common" "github.com/spf13/cobra" ) @@ -81,8 +83,9 @@ func icon(cmd *cobra.Command, args []string) { } } + serviceFileName := fmt.Sprintf(common.ServiceFilePath, common.EnclaveName) - err = common.WriteServiceResponseData(response.ServiceName, *response, cliContext) + err = common.WriteServiceResponseData(response.ServiceName, *response, cliContext, serviceFileName) if err != nil { cliContext.Error(err) cliContext.Context().Exit(1) diff --git a/cli/cmd/chains/neutron/cmd.go b/cli/cmd/chains/neutron/cmd.go index a1ebe185..993d457d 100644 --- a/cli/cmd/chains/neutron/cmd.go +++ b/cli/cmd/chains/neutron/cmd.go @@ -1,6 +1,8 @@ package neutron import ( + "fmt" + "github.com/hugobyte/dive-core/cli/common" "github.com/spf13/cobra" ) @@ -37,8 +39,9 @@ func neutron(cmd *cobra.Command, args []string) { if err != nil { cliContext.Fatal(err) } + serviceFileName := fmt.Sprintf(common.ServiceFilePath, common.EnclaveName) - err = common.WriteServiceResponseData(response.ServiceName, *response, cliContext) + err = common.WriteServiceResponseData(response.ServiceName, *response, cliContext, serviceFileName) if err != nil { cliContext.Fatal(err) } diff --git a/cli/cmd/chains/utils/types.go b/cli/cmd/chains/utils/types.go index 8fa0fdca..64059ffe 100644 --- a/cli/cmd/chains/utils/types.go +++ b/cli/cmd/chains/utils/types.go @@ -17,15 +17,35 @@ type CosmosServiceConfig struct { PublicRPC *int `json:"public_rpc"` } -func (cs *CosmosServiceConfig) LoadDefaultConfig() { +func (cs *CosmosServiceConfig) LoadDefaultConfig() error { cs.ChainID = nil cs.Key = nil cs.Password = nil - cs.PublicGrpc = nil - cs.PublicHTTP = nil - cs.PublicRPC = nil - cs.PublicTCP = nil - cs.Password = nil + publicGrpc, err := common.GetAvailablePort() + if err != nil { + return common.WrapMessageToError(err, "error getting available gRPC port") + } + cs.PublicGrpc = &publicGrpc + + publicHTTP, err := common.GetAvailablePort() + if err != nil { + return common.WrapMessageToError(err, "error getting available HTTP port") + } + cs.PublicHTTP = &publicHTTP + + publicRPC, err := common.GetAvailablePort() + if err != nil { + return common.WrapMessageToError(err, "error getting available Rpc port") + } + cs.PublicRPC = &publicRPC + + publicTCP, err := common.GetAvailablePort() + if err != nil { + return common.WrapMessageToError(err, "error getting available Tcp port") + } + cs.PublicTCP = &publicTCP + + return nil } func (cs *CosmosServiceConfig) EncodeToString() (string, error) { @@ -55,13 +75,24 @@ type IconServiceConfig struct { Cid string `json:"cid"` } -func (sc *IconServiceConfig) LoadDefaultConfig() { +func (sc *IconServiceConfig) LoadDefaultConfig() error { sc.Port = 9080 - sc.PublicPort = 8090 sc.P2PListenAddress = "7080" sc.P2PAddress = "8080" sc.Cid = "0xacbc4e" + if common.CheckPort(8090) { + sc.PublicPort = 8090 + } else { + availablePort, err := common.GetAvailablePort() + if err != nil { + return err + } + sc.PublicPort = availablePort + } + + return nil + } func (sc *IconServiceConfig) EncodeToString() (string, error) { diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 1fa12c5f..45781aea 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -32,6 +32,11 @@ func run(cmd *cobra.Command, args []string) error { styles.RenderBanner() cmd.Help() + err := cmd.ParseFlags(args) + if err != nil { + return err + } + return nil } diff --git a/cli/cmd/utility/clean.go b/cli/cmd/utility/clean.go index 8c92954e..64d8774f 100644 --- a/cli/cmd/utility/clean.go +++ b/cli/cmd/utility/clean.go @@ -34,12 +34,6 @@ func clean(cmd *cobra.Command, args []string) { cliContext.Logger().Fatal(common.CodeOf(err), err.Error()) } - err = cliContext.FileHandler().RemoveFiles([]string{common.DiveOutFile, common.ServiceFilePath}) - if err != nil { - cliContext.Logger().SetErrorToStderr() - cliContext.Logger().Fatal(common.CodeOf(err), err.Error()) - } - enclaves, err := cliContext.Context().GetEnclaves() if err != nil { cliContext.Logger().SetErrorToStderr() @@ -60,6 +54,13 @@ func clean(cmd *cobra.Command, args []string) { cliContext.Logger().SetErrorToStderr() cliContext.Logger().Fatal(common.CodeOf(err), err.Error()) } + for _, enclave := range enclaves { + err = cliContext.FileHandler().RemoveFiles([]string{fmt.Sprintf(common.DiveOutFile, enclave.Name), fmt.Sprintf(common.ServiceFilePath, enclave.Name)}) + if err != nil { + cliContext.Logger().SetErrorToStderr() + cliContext.Logger().Fatal(common.CodeOf(err), err.Error()) + } + } cliContext.Logger().Info(fmt.Sprintf("Enclaves Cleaned %v", enclavesInfo)) @@ -70,6 +71,11 @@ func clean(cmd *cobra.Command, args []string) { cliContext.Logger().SetErrorToStderr() cliContext.Logger().Fatal(common.CodeOf(err), err.Error()) } + err = cliContext.FileHandler().RemoveFiles([]string{fmt.Sprintf(common.DiveOutFile, common.EnclaveName), fmt.Sprintf(common.ServiceFilePath, common.EnclaveName)}) + if err != nil { + cliContext.Logger().SetErrorToStderr() + cliContext.Logger().Fatal(common.CodeOf(err), err.Error()) + } } cliContext.StopSpinnerIfNotVerbose("Clean Completed", common.DiveLogs) diff --git a/cli/common/cli.go b/cli/common/cli.go index 04d05897..681bd101 100644 --- a/cli/common/cli.go +++ b/cli/common/cli.go @@ -85,13 +85,15 @@ func (c *Cli) Errorf(format string, err error, args ...interface{}) { c.spinner.Stop() c.log.SetErrorToStderr() - c.log.Errorf(CodeOf(err), format, args) + actualError, _ := CoderOf(err) + c.log.Errorf(actualError.ErrorCode(), "%s. message: %s", actualError.Error(), err.Error()) } func (c *Cli) Fatalf(format string, err error, args ...interface{}) { c.spinner.Stop() c.log.SetErrorToStderr() - c.log.Fatalf(CodeOf(err), format, args) + actualError, _ := CoderOf(err) + c.log.Fatalf(actualError.ErrorCode(), "%s. message: %s", actualError.Error(), err.Error()) } func (c *Cli) Error(err error) { diff --git a/cli/common/constants.go b/cli/common/constants.go index 5f2741de..7c68e4ea 100644 --- a/cli/common/constants.go +++ b/cli/common/constants.go @@ -25,10 +25,10 @@ const ( DiveHardhatNodeAlreadyRuning = "Hardhat Node Already Running" DiveIconNodeAlreadyRunning = "Icon Node Already Running" DiveLogDirectory = "/logs/" - DiveDitLogFile = "divelog.log" + DiveDitLogFile = "dive.log" DiveErrorLogFile = "error.log" - DiveOutFile = "dive.json" - ServiceFilePath = "services.json" + DiveOutFile = "dive_%s.json" + ServiceFilePath = "services_%s.json" starlarkScript = ` def run(plan, args): plan.stop_service(name=args["service_name"]) @@ -78,4 +78,5 @@ const ( InvalidFileError KurtosisServiceError InvalidChain + PortError ) diff --git a/cli/common/errors.go b/cli/common/errors.go index e4c24651..dbb25745 100644 --- a/cli/common/errors.go +++ b/cli/common/errors.go @@ -34,6 +34,7 @@ var ( ErrInvalidFile = NewBase(InvalidFileError, "Failed To Resolve to File") ErrKurtosisService = NewBase(KurtosisServiceError, "Kurtosis Service Error") ErrInvalidChain = NewBase(InvalidChain, "Not A Valid Chain") + ErrPortAllocation = NewBase(PortError, "Failed To Allocate Port") ) func (c ErrorCode) New(msg string) error { diff --git a/cli/common/types.go b/cli/common/types.go index 3d3c6494..921543ad 100644 --- a/cli/common/types.go +++ b/cli/common/types.go @@ -44,6 +44,6 @@ type EnclaveInfo struct { } type ConfigLoader interface { - LoadDefaultConfig() + LoadDefaultConfig() error LoadConfigFromFile(cliContext *Cli, filePath string) error } diff --git a/cli/common/utils.go b/cli/common/utils.go index bd13f2eb..50ce0350 100644 --- a/cli/common/utils.go +++ b/cli/common/utils.go @@ -1,6 +1,9 @@ package common import ( + "fmt" + "math/rand" + "net" "os/exec" "runtime" "strings" @@ -19,12 +22,12 @@ func ValidateArgs(args []string) error { return nil } -func WriteServiceResponseData(serviceName string, data DiveServiceResponse, cliContext *Cli) error { +func WriteServiceResponseData(serviceName string, data DiveServiceResponse, cliContext *Cli, fileName string) error { var jsonDataFromFile = Services{} - err := cliContext.FileHandler().ReadJson("services.json", &jsonDataFromFile) + err := cliContext.FileHandler().ReadJson(fileName, &jsonDataFromFile) if err != nil { - return WrapMessageToErrorf(err, "Failed To Read %s", "services.json") + return WrapMessageToErrorf(err, "Failed To Read %s", fileName) } _, ok := jsonDataFromFile[serviceName] @@ -32,9 +35,9 @@ func WriteServiceResponseData(serviceName string, data DiveServiceResponse, cliC jsonDataFromFile[serviceName] = &data } - err = cliContext.FileHandler().WriteJson("services.json", jsonDataFromFile) + err = cliContext.FileHandler().WriteJson(fileName, jsonDataFromFile) if err != nil { - return WrapMessageToErrorf(err, "Failed To Write %s", "services.json") + return WrapMessageToErrorf(err, "Failed To Write %s", fileName) } return nil @@ -61,7 +64,9 @@ func OpenFile(URL string) error { func LoadConfig(cliContext *Cli, config ConfigLoader, filePath string) error { if filePath == "" { - config.LoadDefaultConfig() + if err := config.LoadDefaultConfig(); err != nil { + return err + } } else { err := config.LoadConfigFromFile(cliContext, filePath) if err != nil { @@ -136,3 +141,27 @@ func GetSerializedData(cliContext *Cli, response chan *kurtosis_core_rpc_api_bin return serializedOutputObj, services, skippedInstruction, nil } + +// Check if a port is available +func CheckPort(port int) bool { + + ln, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) + if err != nil { + return false + } + defer ln.Close() + return true +} + +func GetAvailablePort() (int, error) { + + // Check random ports in the range 1024-65535 + for i := 0; i < 1000; i++ { + port := rand.Intn(64511) + 1024 + if CheckPort(port) { + return port, nil + } + } + + return 0, ErrPortAllocation +}