diff --git a/src/shidai/internal/commands/commands.go b/src/shidai/internal/commands/commands.go index abba1c5..82d8e5e 100644 --- a/src/shidai/internal/commands/commands.go +++ b/src/shidai/internal/commands/commands.go @@ -49,6 +49,7 @@ var ( "tx": handleTxCommand, "sekaid": handleSekaidCommand, "stop": handleStopCommand, + "new": handleInitNewCommand, } ) @@ -242,6 +243,89 @@ func handleJoinCommand(args map[string]interface{}) (string, error) { return fmt.Sprintf("Join command processed for IP: %s", ip), nil } +func handleInitNewCommand(args map[string]interface{}) (string, error) { + moniker, ok := args["moniker"].(string) + if !ok { + return "", types.ErrInvalidOrMissingMoniker + } + networkName, ok := args["network_name"].(string) + if !ok { + return "", types.ErrInvalidOrMissingNetworkName + } + m, ok := args["mnemonic"].(string) + if !utils.ValidateMnemonic(m) || !ok { + return "", types.ErrInvalidOrMissingMnemonic + } + coins, err := parseCoins(args) + if err != nil { + return "", err + } + + pathsToDel := []string{"/sekai/", "/interx/"} + for _, path := range pathsToDel { + err := os.RemoveAll(path) + if err != nil { + log.Error("Failed to delele ", zap.String("path", path), zap.Error(err)) + } + } + + masterMnemonic, err := mnemonicmanager.GenerateMnemonicsFromMaster(m) + if err != nil { + return "", err + } + + ctx := context.Background() + + err = sekaihandler.InitSekaiNew(ctx, masterMnemonic, networkName, moniker, coins) + if err != nil { + return "", err + } + err = sekaihandler.StartSekai() + if err != nil { + return "", fmt.Errorf("unable to start sekai: %w", err) + } + err = sekaihelper.CheckSekaiStart(ctx) + if err != nil { + return "", err + } + err = interxhandler.InitInterx(ctx, masterMnemonic) + if err != nil { + return "", fmt.Errorf("unable to init interx: %w", err) + } + err = interxhandler.StartInterx() + if err != nil { + return "", fmt.Errorf("unable to start interx: %w", err) + } + err = interxhelper.CheckInterxStart(ctx) + if err != nil { + return "", err + + } + return "Successes", nil +} + +func parseCoins(args map[string]interface{}) ([]string, error) { + rawCoins, exists := args["coins"] + if !exists { + return []string{}, types.ErrInvalidOrMissingCoins + } + + coinsInterface, ok := rawCoins.([]interface{}) + if !ok { + return []string{}, types.ErrInvalidOrMissingCoins + } + + var coins []string + for _, c := range coinsInterface { + if str, ok := c.(string); ok { + coins = append(coins, str) + } else { + return []string{}, types.ErrInvalidOrMissingCoins + } + } + return coins, nil +} + func handleStatusCommand(args map[string]interface{}) (string, error) { // TODO: // 1. Return publicIP diff --git a/src/shidai/internal/sekai_handler/config_constructor/config_constructor.go b/src/shidai/internal/sekai_handler/config_constructor/config_constructor.go index ae5b480..f805fc1 100644 --- a/src/shidai/internal/sekai_handler/config_constructor/config_constructor.go +++ b/src/shidai/internal/sekai_handler/config_constructor/config_constructor.go @@ -61,6 +61,25 @@ type ResponseBlock struct { } `json:"result"` } +func FormSekaiGenesisConfigs() error { + configTomlSavePath := path.Join(types.SEKAI_HOME, "config", "config.toml") + configToml := types.NewDefaultConfig() + appToml := types.NewDefaultAppConfig() + + err := utils.SaveConfig(configTomlSavePath, *configToml) + if err != nil { + return err + } + + appTomlSavePath := path.Join(types.SEKAI_HOME, "config", "app.toml") + appToml = GetGenesisAppConfig(appToml) + err = utils.SaveAppConfig(appTomlSavePath, *appToml) + if err != nil { + return err + } + return nil +} + func FormSekaiJoinerConfigs(tc *TargetSeedKiraConfig) error { ctx := context.Background() @@ -226,6 +245,17 @@ func getConfigsBasedOnSeed(ctx context.Context, netInfo *networkInfo, tc *Target return cfgToUpdate, nil } +func GetGenesisAppConfig(config *types.AppConfig) *types.AppConfig { + config.StateSync.SnapshotInterval = 1000 + config.StateSync.SnapshotKeepRecent = 2 + config.Pruning = "nothing" + config.PruningKeepRecent = 2 + config.PruningKeepEvery = 100 + config.PruningInterval = 10 + config.GRPC.Address = fmt.Sprintf("0.0.0.0:%v", types.DEFAULT_GRPC_PORT) + + return config +} func GetJoinerAppConfig(config *types.AppConfig) *types.AppConfig { // return []utilsTypes.TomlValue{ // {Tag: "state-sync", Name: "snapshot-interval", Value: "200"}, diff --git a/src/shidai/internal/sekai_handler/sekaiHandler.go b/src/shidai/internal/sekai_handler/sekaiHandler.go index 37b242d..64116b1 100644 --- a/src/shidai/internal/sekai_handler/sekaiHandler.go +++ b/src/shidai/internal/sekai_handler/sekaiHandler.go @@ -15,6 +15,7 @@ import ( configconstructor "github.com/kiracore/sekin/src/shidai/internal/sekai_handler/config_constructor" genesishandler "github.com/kiracore/sekin/src/shidai/internal/sekai_handler/genesis_handler" + scaller "github.com/kiracore/sekin/src/shidai/internal/sekai_handler/sekai_helper/s_caller" "github.com/kiracore/sekin/src/shidai/internal/types" "github.com/kiracore/sekin/src/shidai/internal/utils" ) @@ -70,6 +71,37 @@ func InitSekaiJoiner(ctx context.Context, tc *configconstructor.TargetSeedKiraCo return nil } +// TODO: +func InitSekaiNew(ctx context.Context, masterMnemonicSet *mnemonicsgenerator.MasterMnemonicSet, networkName, moniker string, coins []string) error { + log.Debug("Initializing Sekai Joiner", zap.String("home", types.SEKAI_HOME), zap.String("chain-id", networkName)) + + err := scaller.InitCmd(networkName, moniker) + if err != nil { + return err + } + + err = setSekaidKeys(masterMnemonicSet) + if err != nil { + log.Error("Failed to set Sekai keys", zap.Error(err)) + return fmt.Errorf("unable to set sekai keys: %w", err) + } + + err = scaller.AddGenesisAccount(networkName, moniker, types.ValidatorAccountName, coins) + if err != nil { + return err + } + err = scaller.GentxClaimCmd(networkName, moniker, types.ValidatorAccountName) + if err != nil { + return err + } + + err = configconstructor.FormSekaiGenesisConfigs() + if err != nil { + return err + } + return nil +} + func setSekaidKeys(masterMnemonicSet *mnemonicsgenerator.MasterMnemonicSet) error { log.Debug("Setting Sekaid keys", zap.String("home", types.SEKAI_HOME)) @@ -87,7 +119,7 @@ func setSekaidKeys(masterMnemonicSet *mnemonicsgenerator.MasterMnemonicSet) erro } log.Debug("Empty validator state set successfully") - _, err = utils.AddKeyToKeyring("validator", string(masterMnemonicSet.ValidatorAddrMnemonic), types.SEKAI_HOME, "test") + _, err = utils.AddKeyToKeyring(types.ValidatorAccountName, string(masterMnemonicSet.ValidatorAddrMnemonic), types.SEKAI_HOME, types.DefaultKeyring) if err != nil { log.Error("Failed to add validator key to keyring", zap.Error(err)) return fmt.Errorf("unable to add validator key to keyring: %w", err) diff --git a/src/shidai/internal/sekai_handler/sekai_helper/s_caller/s_caller.go b/src/shidai/internal/sekai_handler/sekai_helper/s_caller/s_caller.go new file mode 100644 index 0000000..6bdfe69 --- /dev/null +++ b/src/shidai/internal/sekai_handler/sekai_helper/s_caller/s_caller.go @@ -0,0 +1,75 @@ +package scaller + +import ( + "fmt" + + httpexecutor "github.com/kiracore/sekin/src/shidai/internal/http_executor" + "github.com/kiracore/sekin/src/shidai/internal/logger" + "github.com/kiracore/sekin/src/shidai/internal/types" + "go.uber.org/zap" +) + +var log = logger.GetLogger() + +func InitCmd(networkName, moniker string) error { + cmd := httpexecutor.CommandRequest{ + Command: "init", + Args: map[string]interface{}{ + "home": types.SEKAI_HOME, + "chain-id": networkName, + "moniker": moniker, + }, + } + _, err := httpexecutor.ExecuteCallerCommand(types.SEKAI_CONTAINER_ADDRESS, "8080", "POST", cmd) + if err != nil { + log.Error("Failed to execute caller command", zap.Any("command", cmd), zap.Error(err)) + return fmt.Errorf("unable execute <%v> request, error: %w", cmd, err) + } + return nil +} + +func AddGenesisAccount(networkName, moniker, accountName string, coins []string) error { + // "address": "genesis", + // "coins": ["300000000000000ukex"], + // "keyring-backend": "test", + // "home": "/sekai", + // "log_format": "", + // "log_level": "", + // "trace": false + cmd := httpexecutor.CommandRequest{ + Command: "add-genesis-account", + Args: map[string]interface{}{ + "home": types.SEKAI_HOME, + "chain-id": networkName, + "moniker": moniker, + "address": accountName, + "keyring-backend": types.DefaultKeyring, + "coins": coins, + }, + } + _, err := httpexecutor.ExecuteCallerCommand(types.SEKAI_CONTAINER_ADDRESS, "8080", "POST", cmd) + if err != nil { + log.Error("Failed to execute caller command", zap.Any("command", cmd), zap.Error(err)) + return fmt.Errorf("unable execute <%v> request, error: %w", cmd, err) + } + return nil +} + +func GentxClaimCmd(networkName, moniker, accountName string) error { + cmd := httpexecutor.CommandRequest{ + Command: "gentx-claim", + Args: map[string]interface{}{ + "home": types.SEKAI_HOME, + "chain-id": networkName, + "moniker": moniker, + "address": accountName, + "keyring-backend": types.DefaultKeyring, + }, + } + _, err := httpexecutor.ExecuteCallerCommand(types.SEKAI_CONTAINER_ADDRESS, "8080", "POST", cmd) + if err != nil { + log.Error("Failed to execute caller command", zap.Any("command", cmd), zap.Error(err)) + return fmt.Errorf("unable execute <%v> request, error: %w", cmd, err) + } + return nil +} diff --git a/src/shidai/internal/types/types.go b/src/shidai/internal/types/types.go index 7706701..b79cac2 100644 --- a/src/shidai/internal/types/types.go +++ b/src/shidai/internal/types/types.go @@ -277,6 +277,10 @@ const ( InvalidOrMissingTx = "invalid or missing tx" + InvalidOrMissingNetworkName = "invalid or missing network name" + InvalidOrMissingMoniker = "invalid or missing moniker" + InvalidOrMissingCoins = "invalid or mission coins, []string required" + InvalidRequest = "invalid request" FilePermRO os.FileMode = 0444 @@ -286,6 +290,9 @@ const ( DirPermRO os.FileMode = 0555 DirPermWR os.FileMode = 0755 + ValidatorAccountName = "validator" + DefaultKeyring = "test" + UPDATER_BIN_PATH = "/updater" SEKIN_LATEST_COMPOSE_URL = "https://raw.githubusercontent.com/KiraCore/sekin/main/compose.yml" @@ -294,8 +301,11 @@ const ( ) var ( - ErrInvalidOrMissingMnemonic = errors.New(InvalidOrMissingMnemonic) - ErrInvalidOrMissingIP = errors.New(InvalidOrMissingIP) + ErrInvalidOrMissingMnemonic = errors.New(InvalidOrMissingMnemonic) + ErrInvalidOrMissingIP = errors.New(InvalidOrMissingIP) + ErrInvalidOrMissingNetworkName = errors.New(InvalidOrMissingNetworkName) + ErrInvalidOrMissingMoniker = errors.New(InvalidOrMissingMoniker) + ErrInvalidOrMissingCoins = errors.New(InvalidOrMissingCoins) ErrInvalidOrMissingTx = errors.New(InvalidOrMissingTx)