diff --git a/.gitignore b/.gitignore index 3d416731..f7b57d84 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,7 @@ doc/tags # go work sum -*.sum \ No newline at end of file +*.sum + +# log dir +logs/ \ No newline at end of file diff --git a/cli/cmd/chains/chain/icon.go b/cli/cmd/chains/chain/icon.go deleted file mode 100644 index 4caf06b7..00000000 --- a/cli/cmd/chains/chain/icon.go +++ /dev/null @@ -1,16 +0,0 @@ -package chain - -import ( - "github.com/hugobyte/dive-core/cli/common" - "github.com/spf13/cobra" -) - -var IconCmd = common.NewDiveCommandBuilder(). - SetUse("icon"). - SetShort("Build, initialize and start a icon node."). - SetLong(`The command starts an Icon node, initiating the process of setting up and launching a local Icon network. -It establishes a connection to the Icon network and allows the node in executing smart contracts and maintaining the decentralized ledger.`). - SetRun(icon). - Build() - -func icon(cmd *cobra.Command, args []string) {} diff --git a/cli/cmd/chains/chain/icon/cmd.go b/cli/cmd/chains/chain/icon/cmd.go new file mode 100644 index 00000000..15ed0009 --- /dev/null +++ b/cli/cmd/chains/chain/icon/cmd.go @@ -0,0 +1,98 @@ +package icon + +import ( + "github.com/hugobyte/dive-core/cli/common" + "github.com/spf13/cobra" +) + +const DefaultIconGenesisFile = "../../static-files/config/genesis-icon-0.zip" + +var ( + serviceName = "" + ksPath = "" + ksPassword = "" + networkID = "" + nodeEndpoint = "" + genesis = "" + configFilePath = "" +) + +var IconCmd = common.NewDiveCommandBuilder(). + SetUse("icon"). + SetShort("Build, initialize and start a icon node."). + SetLong(`The command starts an Icon node, initiating the process of setting up and launching a local Icon network. +It establishes a connection to the Icon network and allows the node in executing smart contracts and maintaining the decentralized ledger.`). + AddCommand(IconDecentralizeCmd). + AddStringFlagWithShortHand(&genesis, "genesis", "g", "", "path to custom genesis file"). + AddStringFlagWithShortHand(&configFilePath, "config", "c", "", "path to custom config json file"). + AddBoolFlagP("decentralization", "d", false, "decentralize Icon Node"). + SetRun(icon). + Build() + +var IconDecentralizeCmd = common.NewDiveCommandBuilder(). + SetUse("decentralize"). + SetShort("Decentralize already running Icon Node"). + SetLong(`Decentralize Icon Node is necessary if you want to connect your local icon node to BTP network`). + AddStringFlagWithShortHand(&serviceName, "serviceName", "s", "", "service name"). + AddStringFlagWithShortHand(&nodeEndpoint, "nodeEndpoint", "e", "", "endpoint address"). + AddStringFlagWithShortHand(&ksPath, "keystorePath", "k", "", "keystore path"). + AddStringFlagWithShortHand(&ksPassword, "keyPassword", "p", "", "keypassword"). + AddStringFlagWithShortHand(&networkID, "nid", "n", "", "NetworkId of Icon Node"). + MarkFlagsAsRequired([]string{"serviceName", "nodeEndpoint", "keystorePath", "keyPassword", "nid"}). + SetRun(iconDecentralization). + Build() + +func icon(cmd *cobra.Command, args []string) { + cliContext, err := common.GetCli() + if err != nil { + cliContext.Logger().Fatal(common.CodeOf(err), err.Error()) + } + err = common.ValidateArgs(args) + + if err != nil { + cliContext.Logger().Fatal(common.CodeOf(err), err.Error()) + } + + decentralization, err := cmd.Flags().GetBool("decentralization") + if err != nil { + cliContext.Logger().Error(common.InvalidCommandError, err.Error()) + } + var response = &common.DiveServiceResponse{} + if decentralization { + response, err = RunIconNode(cliContext) + + if err != nil { + cliContext.Logger().Error(common.CodeOf(err), err.Error()) + cliContext.Spinner().Stop() + } + params := GetDecentralizeParams(response.ServiceName, response.PrivateEndpoint, response.KeystorePath, response.KeyPassword, response.NetworkId) + + err = RunDecentralization(cliContext, params) + + if err != nil { + cliContext.Logger().Error(common.CodeOf(err), err.Error()) + cliContext.Spinner().Stop() + } + + } else { + response, err = RunIconNode(cliContext) + + if err != nil { + cliContext.Logger().Error(common.CodeOf(err), err.Error()) + cliContext.Spinner().Stop() + } + + } + + err = common.WriteServiceResponseData(response.ServiceName, *response, cliContext) + if err != nil { + cliContext.Spinner().Stop() + cliContext.Logger().SetErrorToStderr() + cliContext.Logger().Error(common.CodeOf(err), err.Error()) + + } + + cliContext.Spinner().StopWithMessage("Icon Node Started. Please find service details in current working directory(services.json)") +} + +func iconDecentralization(cmd *cobra.Command, args []string) {} diff --git a/cli/cmd/chains/chain/icon/run.go b/cli/cmd/chains/chain/icon/run.go new file mode 100644 index 00000000..b26d438d --- /dev/null +++ b/cli/cmd/chains/chain/icon/run.go @@ -0,0 +1,103 @@ +package icon + +import ( + "fmt" + + "github.com/hugobyte/dive-core/cli/common" +) + +func RunIconNode(cli *common.Cli) (*common.DiveServiceResponse, error) { + + _, err := cli.Context().GetKurtosisContext() + + if err != nil { + return nil, common.Errorc(common.KurtosisContextError, err.Error()) + + } + + enclaveContext, err := cli.Context().GetEnclaveContext(common.DiveEnclave) + + if err != nil { + return nil, err + } + var serviceConfig = &IconServiceConfig{} + err = LoadConfig(cli, serviceConfig, configFilePath) + if err != nil { + return nil, err + } + cli.Spinner().StartWithMessage("Starting Icon Node", "green") + + genesisHandler, err := genesismanager(enclaveContext) + if err != nil { + return nil, common.Errorc(common.FileError, err.Error()) + } + params := fmt.Sprintf(`{"private_port":%d, "public_port":%d, "p2p_listen_address": %s, "p2p_address":%s, "cid": "%s","uploaded_genesis":%s,"genesis_file_path":"%s","genesis_file_name":"%s"}`, serviceConfig.Port, serviceConfig.PublicPort, serviceConfig.P2PListenAddress, serviceConfig.P2PAddress, serviceConfig.Cid, genesisHandler.uploadedFiles, genesisHandler.genesisPath, genesisHandler.genesisFile) + starlarkConfig := common.GetStarlarkRunConfig(params, common.DiveIconNodeScript, "start_icon_node") + + iconData, _, err := enclaveContext.RunStarlarkRemotePackage(cli.Context().GetContext(), common.DiveRemotePackagePath, starlarkConfig) + + if err != nil { + return nil, common.Errorc(common.FileError, err.Error()) + } + + response, services, skippedInstructions, err := common.GetSerializedData(cli, iconData) + + if err != nil { + for service := range services { + err = cli.Context().RemoveService(service, common.DiveEnclave) + if err != nil { + return nil, common.Errorc(common.InvalidEnclaveContextError, err.Error()) + } + } + return nil, common.Errorc(common.KurtosisContextError, err.Error()) + } + + if cli.Context().CheckSkippedInstructions(skippedInstructions) { + return nil, common.Errorc(common.KurtosisContextError, "Already Running") + } + + iconResponseData := &common.DiveServiceResponse{} + + result, err := iconResponseData.Decode([]byte(response)) + + if err != nil { + + return nil, common.Errorc(common.KurtosisContextError, err.Error()) + } + + return result, nil +} + +func RunDecentralization(cli *common.Cli, params string) error { + + cli.Spinner().SetSuffixMessage(" Starting Icon Node Decentralization", "green") + + kurtosisEnclaveContext, err := cli.Context().GetEnclaveContext(common.DiveEnclave) + + if err != nil { + return common.Errorc(common.KurtosisContextError, err.Error()) + } + starlarkConfig := common.GetStarlarkRunConfig(params, common.DiveIconDecentraliseScript, "configure_node") + data, _, err := kurtosisEnclaveContext.RunStarlarkRemotePackage(cli.Context().GetContext(), common.DiveRemotePackagePath, starlarkConfig) + + if err != nil { + return common.Errorc(common.KurtosisContextError, err.Error()) + } + + _, services, skippedInstructions, err := common.GetSerializedData(cli, data) + if err != nil { + + for service := range services { + err = cli.Context().RemoveService(service, common.DiveEnclave) + if err != nil { + return common.Errorc(common.InvalidEnclaveContextError, err.Error()) + } + } + } + if cli.Context().CheckSkippedInstructions(skippedInstructions) { + return common.Errorc(common.KurtosisContextError, "Decentralization Already Completed ") + } + + return nil + +} diff --git a/cli/cmd/chains/chain/icon/types.go b/cli/cmd/chains/chain/icon/types.go new file mode 100644 index 00000000..b0aa302c --- /dev/null +++ b/cli/cmd/chains/chain/icon/types.go @@ -0,0 +1,52 @@ +package icon + +import ( + "encoding/json" + + "github.com/hugobyte/dive-core/cli/common" +) + +type ConfigLoader interface { + LoadDefaultConfig() + LoadConfigFromFile(cliContext *common.Cli, filePath string) error +} + +type IconServiceConfig struct { + Port int `json:"private_port"` + PublicPort int `json:"public_port"` + P2PListenAddress string `json:"p2p_listen_address"` + P2PAddress string `json:"p2p_address"` + Cid string `json:"cid"` +} + +func (sc *IconServiceConfig) LoadDefaultConfig() { + sc.Port = 9080 + sc.PublicPort = 8090 + sc.P2PListenAddress = "7080" + sc.P2PAddress = "8080" + sc.Cid = "0xacbc4e" + +} + +func (sc *IconServiceConfig) EncodeToString() (string, error) { + encodedBytes, err := json.Marshal(sc) + if err != nil { + return "", nil + } + + return string(encodedBytes), nil +} + +func (sc *IconServiceConfig) LoadConfigFromFile(cliContext *common.Cli, filePath string) error { + err := cliContext.FileHandler().ReadJson(configFilePath, sc) + if err != nil { + return err + } + return nil +} + +type genesisHandler struct { + genesisFile string + uploadedFiles string + genesisPath string +} diff --git a/cli/cmd/chains/chain/icon/utils.go b/cli/cmd/chains/chain/icon/utils.go new file mode 100644 index 00000000..d6939d47 --- /dev/null +++ b/cli/cmd/chains/chain/icon/utils.go @@ -0,0 +1,54 @@ +package icon + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/hugobyte/dive-core/cli/common" + "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves" +) + +func genesismanager(enclaveContext *enclaves.EnclaveContext) (*genesisHandler, error) { + + gm := genesisHandler{} + + var genesisFilePath = genesis + + if genesisFilePath != "" { + genesisFileName := filepath.Base(genesisFilePath) + if _, err := os.Stat(genesisFilePath); err != nil { + return nil, err + } + + _, d, err := enclaveContext.UploadFiles(genesisFilePath, genesisFileName) + if err != nil { + return nil, err + } + + gm.uploadedFiles = fmt.Sprintf(`{"file_path":"%s","file_name":"%s"}`, d, genesisFileName) + } else { + gm.genesisFile = filepath.Base(DefaultIconGenesisFile) + gm.genesisPath = DefaultIconGenesisFile + gm.uploadedFiles = `{}` + + } + + return &gm, nil +} + +func LoadConfig(cliContext *common.Cli, config ConfigLoader, filePath string) error { + if filePath == "" { + config.LoadDefaultConfig() + } else { + err := config.LoadConfigFromFile(cliContext, filePath) + if err != nil { + return err + } + } + return nil +} + +func GetDecentralizeParams(serviceName, nodeEndpoint, keystorePath, keystorepassword, networkID string) string { + return fmt.Sprintf(`{"service_name":"%s","uri":"%s","keystorepath":"%s","keypassword":"%s","nid":"%s"}`, serviceName, nodeEndpoint, keystorePath, keystorepassword, networkID) +} diff --git a/cli/cmd/chains/chains.go b/cli/cmd/chains/chains.go index 489fb9e3..4c803d99 100644 --- a/cli/cmd/chains/chains.go +++ b/cli/cmd/chains/chains.go @@ -5,6 +5,7 @@ import ( "slices" "github.com/hugobyte/dive-core/cli/cmd/chains/chain" + "github.com/hugobyte/dive-core/cli/cmd/chains/chain/icon" "github.com/hugobyte/dive-core/cli/common" "github.com/spf13/cobra" ) @@ -17,7 +18,7 @@ It encompasses compiling and configuring the necessary dependencies and componen By executing this command, the node is launched, enabling network participation, transaction processing, and ledger maintenance within the specified blockchain ecosystem.`, ). - AddCommand(chain.IconCmd). + AddCommand(icon.IconCmd). AddCommand(chain.EthCmd). AddCommand(chain.HardhatCmd). AddCommand(chain.ArchwayCmd). diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 871d4745..51e5e909 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -1,6 +1,7 @@ package cmd import ( + "fmt" "os" "github.com/hugobyte/dive-core/cli/cmd/bridge" @@ -35,7 +36,11 @@ func run(cmd *cobra.Command, args []string) error { } func init() { - common.GetDiveContext() + _, err := common.GetCli() + if err != nil { + fmt.Println(err) + os.Exit(1) + } } func Execute() { diff --git a/cli/go.mod b/cli/go.mod index 149c9ca1..84658c58 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -1,4 +1,4 @@ -module github.com/hugobyte/dive/cli +module github.com/hugobyte/dive-core/cli go 1.21 diff --git a/cli/main.go b/cli/main.go index 9ae545e9..fc3287cb 100644 --- a/cli/main.go +++ b/cli/main.go @@ -3,12 +3,10 @@ Copyright © 2023 Hugobyte AI Labs */ package main -import ( - "github.com/hugobyte/dive/cli/commands" -) +import "github.com/hugobyte/dive-core/cli/cmd" func main() { - commands.Execute() + cmd.Execute() }