From ba28cf7e96eb250460298a70cb5305c00da2d5b6 Mon Sep 17 00:00:00 2001 From: Snobbish Bee <125891987+snobbee@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:37:50 +0100 Subject: [PATCH] feat: add chain-initiator tool to use mainnet snapshot in localnet --- .../chain-initiator/account-unmarshal-json.go | 38 ++ .../chain-initiator/add-genesis-account.go | 19 + scripts/chain-initiator/add-key.go | 29 ++ scripts/chain-initiator/collect-gentxs.go | 19 + scripts/chain-initiator/filter-accounts.go | 17 + scripts/chain-initiator/filter-balances.go | 24 ++ scripts/chain-initiator/gen-tx.go | 19 + scripts/chain-initiator/init-chain.go | 19 + scripts/chain-initiator/initiator.go | 121 ++++++ scripts/chain-initiator/read-genesis-file.go | 23 ++ scripts/chain-initiator/remove-home.go | 19 + .../chain-initiator/should-filter-account.go | 15 + scripts/chain-initiator/start.go | 24 ++ scripts/chain-initiator/types.go | 362 ++++++++++++++++++ scripts/chain-initiator/validate-genesis.go | 19 + scripts/chain-initiator/write-genesis-file.go | 28 ++ 16 files changed, 795 insertions(+) create mode 100644 scripts/chain-initiator/account-unmarshal-json.go create mode 100644 scripts/chain-initiator/add-genesis-account.go create mode 100644 scripts/chain-initiator/add-key.go create mode 100644 scripts/chain-initiator/collect-gentxs.go create mode 100644 scripts/chain-initiator/filter-accounts.go create mode 100644 scripts/chain-initiator/filter-balances.go create mode 100644 scripts/chain-initiator/gen-tx.go create mode 100644 scripts/chain-initiator/init-chain.go create mode 100644 scripts/chain-initiator/initiator.go create mode 100644 scripts/chain-initiator/read-genesis-file.go create mode 100644 scripts/chain-initiator/remove-home.go create mode 100644 scripts/chain-initiator/should-filter-account.go create mode 100644 scripts/chain-initiator/start.go create mode 100644 scripts/chain-initiator/types.go create mode 100644 scripts/chain-initiator/validate-genesis.go create mode 100644 scripts/chain-initiator/write-genesis-file.go diff --git a/scripts/chain-initiator/account-unmarshal-json.go b/scripts/chain-initiator/account-unmarshal-json.go new file mode 100644 index 0000000000..f80a07bd34 --- /dev/null +++ b/scripts/chain-initiator/account-unmarshal-json.go @@ -0,0 +1,38 @@ +package main + +import ( + "encoding/json" + "fmt" +) + +func (a *Account) UnmarshalJSON(data []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + + // Set the Type field from the raw data + typeStr, ok := raw["@type"].(string) + if !ok { + return fmt.Errorf("type field is missing or invalid") + } + a.Type = typeStr + + switch a.Type { + case "/cosmos.auth.v1beta1.BaseAccount": + var ba BaseAccount + if err := json.Unmarshal(data, &ba); err != nil { + return err + } + a.BaseAccount = &ba + case "/cosmos.auth.v1beta1.ModuleAccount": + var ma ModuleAccount + if err := json.Unmarshal(data, &ma); err != nil { + return err + } + a.ModuleAccount = &ma + default: + return fmt.Errorf("unknown account type: %s", a.Type) + } + return nil +} diff --git a/scripts/chain-initiator/add-genesis-account.go b/scripts/chain-initiator/add-genesis-account.go new file mode 100644 index 0000000000..6deed9611c --- /dev/null +++ b/scripts/chain-initiator/add-genesis-account.go @@ -0,0 +1,19 @@ +package main + +import ( + "log" + "os/exec" +) + +func addGenesisAccount(cmdPath, address, balance, homePath string) { + // Command and arguments + args := []string{"add-genesis-account", address, balance + "rowan", "--home", homePath} + + // Execute the command + if err := exec.Command(cmdPath, args...).Run(); err != nil { + log.Fatalf("Command execution failed: %v", err) + } + + // If execution reaches here, the command was successful + log.Printf("add genesis account with address %s, balance: %s and home path %s successfully", address, balance, homePath) +} diff --git a/scripts/chain-initiator/add-key.go b/scripts/chain-initiator/add-key.go new file mode 100644 index 0000000000..288053f2a7 --- /dev/null +++ b/scripts/chain-initiator/add-key.go @@ -0,0 +1,29 @@ +package main + +import ( + "encoding/json" + "log" + "os/exec" +) + +func addKey(cmdPath, name, homePath, keyringBackend string) string { + // Command and arguments + args := []string{"keys", "add", name, "--home", homePath, "--keyring-backend", keyringBackend, "--output", "json"} + + // Execute the command + output, err := exec.Command(cmdPath, args...).CombinedOutput() + if err != nil { + log.Fatalf("Command execution failed: %v", err) + } + + // Unmarshal the JSON output + var keyOutput KeyOutput + if err := json.Unmarshal(output, &keyOutput); err != nil { + log.Fatalf("Failed to unmarshal JSON output: %v", err) + } + + // Log the address + log.Printf("add key with name %s, home path: %s, keyring backend %s and address %s successfully", name, homePath, keyringBackend, keyOutput.Address) + + return keyOutput.Address +} diff --git a/scripts/chain-initiator/collect-gentxs.go b/scripts/chain-initiator/collect-gentxs.go new file mode 100644 index 0000000000..07fe9834ad --- /dev/null +++ b/scripts/chain-initiator/collect-gentxs.go @@ -0,0 +1,19 @@ +package main + +import ( + "log" + "os/exec" +) + +func collectGentxs(cmdPath, homePath string) { + // Command and arguments + args := []string{"collect-gentxs", "--home", homePath} + + // Execute the command + if err := exec.Command(cmdPath, args...).Run(); err != nil { + log.Fatalf("Command execution failed: %v", err) + } + + // If execution reaches here, the command was successful + log.Printf("collect gen txs with home path %s successfully", homePath) +} diff --git a/scripts/chain-initiator/filter-accounts.go b/scripts/chain-initiator/filter-accounts.go new file mode 100644 index 0000000000..7c6bd83615 --- /dev/null +++ b/scripts/chain-initiator/filter-accounts.go @@ -0,0 +1,17 @@ +package main + +func filterAccounts(accounts []Account, filterAddresses []string) []Account { + filterMap := make(map[string]struct{}) + for _, addr := range filterAddresses { + filterMap[addr] = struct{}{} + } + + var newAccounts []Account + for _, account := range accounts { + if shouldFilterAccount(account, filterMap) { + continue + } + newAccounts = append(newAccounts, account) + } + return newAccounts +} diff --git a/scripts/chain-initiator/filter-balances.go b/scripts/chain-initiator/filter-balances.go new file mode 100644 index 0000000000..9f6f217e2d --- /dev/null +++ b/scripts/chain-initiator/filter-balances.go @@ -0,0 +1,24 @@ +package main + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +func filterBalances(balances []banktypes.Balance, filterAddresses []string) ([]banktypes.Balance, sdk.Coins) { + filterMap := make(map[string]struct{}) + for _, addr := range filterAddresses { + filterMap[addr] = struct{}{} + } + + var newBalances []banktypes.Balance + var coinsToRemove sdk.Coins + for _, balance := range balances { + if _, exists := filterMap[balance.Address]; exists { + coinsToRemove = coinsToRemove.Add(balance.Coins...) + continue + } + newBalances = append(newBalances, balance) + } + return newBalances, coinsToRemove +} diff --git a/scripts/chain-initiator/gen-tx.go b/scripts/chain-initiator/gen-tx.go new file mode 100644 index 0000000000..bb6e351041 --- /dev/null +++ b/scripts/chain-initiator/gen-tx.go @@ -0,0 +1,19 @@ +package main + +import ( + "log" + "os/exec" +) + +func genTx(cmdPath, name, balance, chainId, homePath, keyringBackend string) { + // Command and arguments + args := []string{"gentx", name, balance + "rowan", "--chain-id", chainId, "--home", homePath, "--keyring-backend", keyringBackend} + + // Execute the command + if err := exec.Command(cmdPath, args...).Run(); err != nil { + log.Fatalf("Command execution failed: %v", err) + } + + // If execution reaches here, the command was successful + log.Printf("gen tx with name %s, balance: %s, chain id %s, home path %s and keyring backend %s successfully", name, balance, chainId, homePath, keyringBackend) +} diff --git a/scripts/chain-initiator/init-chain.go b/scripts/chain-initiator/init-chain.go new file mode 100644 index 0000000000..3beaa6b1cf --- /dev/null +++ b/scripts/chain-initiator/init-chain.go @@ -0,0 +1,19 @@ +package main + +import ( + "log" + "os/exec" +) + +func initChain(cmdPath, moniker, chainId, homePath string) { + // Command and arguments + args := []string{"init", moniker, "--chain-id", chainId, "--home", homePath} + + // Execute the command + if err := exec.Command(cmdPath, args...).Run(); err != nil { + log.Fatalf("Command execution failed: %v", err) + } + + // If execution reaches here, the command was successful + log.Printf("init chain with moniker %s, chain id %s and home path: %s successfully", moniker, chainId, homePath) +} diff --git a/scripts/chain-initiator/initiator.go b/scripts/chain-initiator/initiator.go new file mode 100644 index 0000000000..eca05f7725 --- /dev/null +++ b/scripts/chain-initiator/initiator.go @@ -0,0 +1,121 @@ +package main + +import ( + "log" + + app "github.com/Sifchain/sifnode/app" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/spf13/cobra" +) + +const ( + moniker = "node" + chainId = "sifchain-1" + keyringBackend = "test" + validatorKeyName = "validator" + validatorBalance = "4000000000000000000000000000" +) + +func main() { + var rootCmd = &cobra.Command{ + Use: "initiator [cmd_path] [home_path] [genesis_file_path]", + Short: "Chain Initiator is a tool for modifying genesis files", + Long: `A tool for performing various operations on genesis files of a blockchain setup.`, + Args: cobra.ExactArgs(3), // Expect exactly two arguments + Run: func(cmd *cobra.Command, args []string) { + cmdPath := args[0] // sifnoded + homePath := args[1] // /tmp/node + genesisFilePath := args[2] // /tmp/genesis.json + + // set address prefix + app.SetConfig(false) + + // remove home path + removeHome(homePath) + + // init chain + initChain(cmdPath, moniker, chainId, homePath) + + // add validator key + validatorAddress := addKey(cmdPath, validatorKeyName, homePath, keyringBackend) + + // add genesis account + addGenesisAccount(cmdPath, validatorAddress, validatorBalance, homePath) + + // generate genesis tx + genTx(cmdPath, validatorKeyName, validatorBalance, chainId, homePath, keyringBackend) + + // collect genesis txs + collectGentxs(cmdPath, homePath) + + // validate genesis + validateGenesis(cmdPath, homePath) + + genesis, err := readGenesisFile(genesisFilePath) + if err != nil { + log.Fatalf("Error reading genesis file: %v", err) + } + + genesisInitFilePath := homePath + "/config/genesis.json" + genesisInit, err := readGenesisFile(genesisInitFilePath) + if err != nil { + log.Fatalf("Error reading initial genesis file: %v", err) + } + + filterAccountAddresses := []string{ + "sif1harggtyrlukcfrtmpgjzptsnaedcdh38qqknp2", // multisig account with missing pubkeys + } + filterBalanceAddresses := []string{ + "sif1harggtyrlukcfrtmpgjzptsnaedcdh38qqknp2", + authtypes.NewModuleAddress("distribution").String(), + authtypes.NewModuleAddress("bonded_tokens_pool").String(), + authtypes.NewModuleAddress("not_bonded_tokens_pool").String(), + } + + var coinsToRemove sdk.Coins + + genesis.AppState.Auth.Accounts = filterAccounts(genesis.AppState.Auth.Accounts, filterAccountAddresses) + genesis.AppState.Bank.Balances, coinsToRemove = filterBalances(genesis.AppState.Bank.Balances, filterBalanceAddresses) + + newValidatorBalance, ok := sdk.NewIntFromString("4000000000000000000000000000") + if !ok { + panic("invalid number") + } + newValidatorBalanceCoin := sdk.NewCoin("rowan", newValidatorBalance) + + // update supply + genesis.AppState.Bank.Supply = genesis.AppState.Bank.Supply.Sub(coinsToRemove).Add(newValidatorBalanceCoin) + + // Add new validator account and balance + genesis.AppState.Auth.Accounts = append(genesis.AppState.Auth.Accounts, genesisInit.AppState.Auth.Accounts[0]) + genesis.AppState.Bank.Balances = append(genesis.AppState.Bank.Balances, genesisInit.AppState.Bank.Balances[0]) + + // reset staking data + stakingParams := genesis.AppState.Staking.Params + genesis.AppState.Staking = genesisInit.AppState.Staking + genesis.AppState.Staking.Params = stakingParams + + // reset slashing data + genesis.AppState.Slashing = genesisInit.AppState.Slashing + + // reset distribution data + genesis.AppState.Distribution = genesisInit.AppState.Distribution + + // set genutil from genesisInit + genesis.AppState.Genutil = genesisInit.AppState.Genutil + + outputFilePath := homePath + "/config/genesis.json" + if err := writeGenesisFile(outputFilePath, genesis); err != nil { + log.Fatalf("Error writing genesis file: %v", err) + } + + // start chain + start(cmdPath, homePath) + }, + } + + if err := rootCmd.Execute(); err != nil { + log.Fatalf("Error executing command: %v", err) + } +} diff --git a/scripts/chain-initiator/read-genesis-file.go b/scripts/chain-initiator/read-genesis-file.go new file mode 100644 index 0000000000..afeb432d0a --- /dev/null +++ b/scripts/chain-initiator/read-genesis-file.go @@ -0,0 +1,23 @@ +package main + +import ( + "bufio" + "encoding/json" + "fmt" + "os" +) + +func readGenesisFile(filePath string) (Genesis, error) { + var genesis Genesis + file, err := os.Open(filePath) + if err != nil { + return genesis, fmt.Errorf("error opening file: %w", err) + } + defer file.Close() + + if err := json.NewDecoder(bufio.NewReader(file)).Decode(&genesis); err != nil { + return genesis, fmt.Errorf("error decoding JSON: %w", err) + } + + return genesis, nil +} diff --git a/scripts/chain-initiator/remove-home.go b/scripts/chain-initiator/remove-home.go new file mode 100644 index 0000000000..c370e28995 --- /dev/null +++ b/scripts/chain-initiator/remove-home.go @@ -0,0 +1,19 @@ +package main + +import ( + "log" + "os/exec" +) + +func removeHome(homePath string) { + // Command and arguments + args := []string{"-rf", homePath} + + // Execute the command + if err := exec.Command("rm", args...).Run(); err != nil { + log.Fatalf("Command execution failed: %v", err) + } + + // If execution reaches here, the command was successful + log.Printf("removed home path %s successfully", homePath) +} diff --git a/scripts/chain-initiator/should-filter-account.go b/scripts/chain-initiator/should-filter-account.go new file mode 100644 index 0000000000..f361c37761 --- /dev/null +++ b/scripts/chain-initiator/should-filter-account.go @@ -0,0 +1,15 @@ +package main + +func shouldFilterAccount(account Account, filterAddresses map[string]struct{}) bool { + if account.BaseAccount != nil { + if _, exists := filterAddresses[account.BaseAccount.Address]; exists { + return true + } + } + if account.ModuleAccount != nil { + if _, exists := filterAddresses[account.ModuleAccount.BaseAccount.Address]; exists { + return true + } + } + return false +} diff --git a/scripts/chain-initiator/start.go b/scripts/chain-initiator/start.go new file mode 100644 index 0000000000..bd153c3fee --- /dev/null +++ b/scripts/chain-initiator/start.go @@ -0,0 +1,24 @@ +package main + +import ( + "log" + "os" + "os/exec" +) + +func start(cmdPath, homePath string) { + // Command and arguments + args := []string{"start", "--home", homePath} + + // Set up the command + cmd := exec.Command(cmdPath, args...) + + // Attach command's stdout and stderr to os.Stdout and os.Stderr + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + // Execute the command and stream the output + if err := cmd.Run(); err != nil { + log.Fatalf("Command execution failed: %v", err) + } +} diff --git a/scripts/chain-initiator/types.go b/scripts/chain-initiator/types.go new file mode 100644 index 0000000000..02d2afe7a1 --- /dev/null +++ b/scripts/chain-initiator/types.go @@ -0,0 +1,362 @@ +package main + +import ( + "encoding/json" + "time" + + admintypes "github.com/Sifchain/sifnode/x/admin/types" + clptypes "github.com/Sifchain/sifnode/x/clp/types" + dispensationtypes "github.com/Sifchain/sifnode/x/dispensation/types" + + // epochstypes "github.com/Sifchain/sifnode/x/epochs/types" + margintypes "github.com/Sifchain/sifnode/x/margin/types" + oracletypes "github.com/Sifchain/sifnode/x/oracle/types" + tokenregistrytypes "github.com/Sifchain/sifnode/x/tokenregistry/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authz "github.com/cosmos/cosmos-sdk/x/authz" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" + distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + + // genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + ibcconnectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibctypes "github.com/cosmos/ibc-go/v4/modules/core/types" +) + +type Genesis struct { + GenesisTime time.Time `json:"genesis_time"` + ChainID string `json:"chain_id"` + InitialHeight string `json:"initial_height"` + ConsensusParams ConsensusParams `json:"consensus_params"` + AppHash string `json:"app_hash"` + AppState AppState `json:"app_state"` + // Include other top-level fields as needed +} + +type ConsensusParams struct { + Version Version `json:"version"` + Block Block `json:"block"` + Evidence Evidence `json:"evidence"` + Validator Validator `json:"validator"` +} + +type Version struct{} + +type Validator struct { + PubKeyTypes []string `json:"pub_key_types"` +} + +type Evidence struct { + MaxAgeNumBlocks string `json:"max_age_num_blocks"` + MaxAgeDuration string `json:"max_age_duration"` + MaxBytes string `json:"max_bytes,omitempty"` +} + +type Block struct { + MaxBytes string `json:"max_bytes"` + MaxGas string `json:"max_gas"` + TimeIotaMs string `json:"time_iota_ms"` +} + +type AppState struct { + Admin Admin `json:"admin"` + Auth Auth `json:"auth"` + AuthZ authz.GenesisState `json:"authz"` + Bank banktypes.GenesisState `json:"bank"` + Capability Capability `json:"capability"` + CLP CLP `json:"clp"` + Crisis crisistypes.GenesisState `json:"crisis"` + Dispensation Dispensation `json:"dispensation"` + Distribution Distribution `json:"distribution"` + // Epochs epochstypes.GenesisState `json:"epochs"` + Ethbridge struct{} `json:"ethbridge"` + Evidence EvidenceState `json:"evidence"` + Genutil Genutil `json:"genutil"` + Gov Gov `json:"gov"` + Ibc Ibc `json:"ibc"` + Margin Margin `json:"margin"` + Mint Mint `json:"mint"` + Oracle Oracle `json:"oracle"` + Params interface{} `json:"params"` + Slashing Slashing `json:"slashing"` + Staking Staking `json:"staking"` + TokenRegistry TokenRegistry `json:"tokenregistry"` + Transfer transfertypes.GenesisState `json:"transfer"` + Upgrade struct{} `json:"upgrade"` + // Include other fields as needed +} + +type Genutil struct { + // genutiltypes.GenesisState + + GenTxs []interface{} `json:"gen_txs"` +} + +type Admin struct { + admintypes.GenesisState + + AdminAccounts []AdminAccount `json:"admin_accounts"` +} + +type AdminAccount struct { + admintypes.AdminAccount + + AdminType string `json:"admin_type"` +} + +type TokenRegistry struct { + tokenregistrytypes.GenesisState + + Registry Registry `json:"registry"` +} + +type Registry struct { + tokenregistrytypes.Registry + + Entries []*RegistryEntry `json:"entries"` +} + +type RegistryEntry struct { + tokenregistrytypes.RegistryEntry + + Decimals json.Number `json:"decimals"` + Permissions []interface{} `json:"permissions"` +} + +type EvidenceState struct { + evidencetypes.GenesisState + + Evidence []interface{} `json:"evidence"` +} + +type Oracle struct { + oracletypes.GenesisState + + AddressWhitelist []interface{} `json:"address_whitelist"` + Prophecies []interface{} `json:"prophecies"` +} + +type Dispensation struct { + dispensationtypes.GenesisState + + DistributionRecords interface{} `json:"distribution_records"` + Distributions interface{} `json:"distributions"` + Claims interface{} `json:"claims"` +} + +type Capability struct { + capabilitytypes.GenesisState + + Index json.Number `json:"index"` + Owners []interface{} `json:"owners"` +} + +type Slashing struct { + slashingtypes.GenesisState + + Params SlashingParams `json:"params"` + SigningInfos []interface{} `json:"signing_infos"` + MissedBlocks []interface{} `json:"missed_blocks"` +} + +type SlashingParams struct { + slashingtypes.Params + + SignedBlocksWindow json.Number `json:"signed_blocks_window"` + DowntimeJailDuration string `json:"downtime_jail_duration"` +} + +type Mint struct { + minttypes.GenesisState + + Params MintParams `json:"params"` +} + +type MintParams struct { + minttypes.Params + + BlocksPerYear json.Number `json:"blocks_per_year"` +} + +type Gov struct { + govtypes.GenesisState + + StartingProposalId json.Number `json:"starting_proposal_id"` + Deposits []interface{} `json:"deposits"` + Votes []interface{} `json:"votes"` + Proposals []interface{} `json:"proposals"` + DepositParams GovDepositParams `json:"deposit_params"` + VotingParams GovVotingParams `json:"voting_params"` +} + +type GovDepositParams struct { + govtypes.DepositParams + + MaxDepositPeriod string `json:"max_deposit_period"` +} + +type GovVotingParams struct { + govtypes.VotingParams + + VotingPeriod string `json:"voting_period"` +} + +type Staking struct { + stakingtypes.GenesisState + + Params StakingParams `json:"params"` + LastValidatorPowers []interface{} `json:"last_validator_powers"` + Validators []interface{} `json:"validators"` + Delegations []interface{} `json:"delegations"` + UnbondingDelegations []interface{} `json:"unbonding_delegations"` + Redelegations []interface{} `json:"redelegations"` +} + +type StakingParams struct { + stakingtypes.Params + + UnbondingTime string `json:"unbonding_time"` + MaxValidators json.Number `json:"max_validators"` + MaxEntries json.Number `json:"max_entries"` + HistoricalEntries json.Number `json:"historical_entries"` +} + +type Distribution struct { + distributiontypes.GenesisState + + DelegatorWithdrawInfos []interface{} `json:"delegator_withdraw_infos"` + OutstandingRewards []interface{} `json:"outstanding_rewards"` + ValidatorAccumulatedCommissions []interface{} `json:"validator_accumulated_commissions"` + ValidatorHistoricalRewards []interface{} `json:"validator_historical_rewards"` + ValidatorCurrentRewards []interface{} `json:"validator_current_rewards"` + DelegatorStartingInfos []interface{} `json:"delegator_starting_infos"` + ValidatorSlashEvents []interface{} `json:"validator_slash_events"` +} + +type Ibc struct { + ibctypes.GenesisState + + ClientGenesis ClientGenesis `json:"client_genesis"` + ConnectionGenesis ConnectionGenesis `json:"connection_genesis"` + ChannelGenesis ChannelGenesis `json:"channel_genesis"` +} + +type ClientGenesis struct { + ibcclienttypes.GenesisState + + Clients []interface{} `json:"clients"` + ClientsConsensus []interface{} `json:"clients_consensus"` + ClientsMetadata []interface{} `json:"clients_metadata"` + Params ibcclienttypes.Params `json:"params"` + NextClientSequence json.Number `json:"next_client_sequence"` +} + +type ConnectionGenesis struct { + ibcconnectiontypes.GenesisState + + Connections []interface{} `json:"connections"` + ClientConnectionPaths []interface{} `json:"client_connection_paths"` + NextConnectionSequence json.Number `json:"next_connection_sequence"` + Params ConnectionGenesisParams `json:"params"` +} + +type ConnectionGenesisParams struct { + ibcconnectiontypes.Params + + MaxExpectedTimePerBlock json.Number `json:"max_expected_time_per_block"` +} + +type ChannelGenesis struct { + ibcchanneltypes.GenesisState + + Channels []interface{} `json:"channels"` + Acknowledgements []interface{} `json:"acknowledgements"` + Commitments []interface{} `json:"commitments"` + Receipts []interface{} `json:"receipts"` + SendSequences []interface{} `json:"send_sequences"` + RecvSequences []interface{} `json:"recv_sequences"` + AckSequences []interface{} `json:"ack_sequences"` + NextChannelSequence json.Number `json:"next_channel_sequence"` +} + +type CLPParams struct { + clptypes.Params + + MinCreatePoolThreshold json.Number `json:"min_create_pool_threshold"` +} + +type CLP struct { + clptypes.GenesisState + + Params CLPParams `json:"params"` + PoolList []interface{} `json:"pool_list"` + LiquidityProviders []interface{} `json:"liquidity_providers"` +} + +type Margin struct { + margintypes.GenesisState + + Params MarginParams `json:"params"` +} + +type MarginParams struct { + margintypes.Params + + EpochLength json.Number `json:"epoch_length"` + MaxOpenPositions json.Number `json:"max_open_positions"` +} + +type AuthParams struct { + authtypes.Params + + MaxMemoCharacters json.Number `json:"max_memo_characters"` + TxSigLimit json.Number `json:"tx_sig_limit"` + TxSizeCostPerByte json.Number `json:"tx_size_cost_per_byte"` + SigVerifyCostEd25519 json.Number `json:"sig_verify_cost_ed25519"` + SigVerifyCostSecp256K1 json.Number `json:"sig_verify_cost_secp256k1"` +} + +type BaseAccount struct { + Address string `json:"address"` + PubKey interface{} `json:"pub_key"` + AccountNumber json.Number `json:"account_number"` + Sequence json.Number `json:"sequence"` +} + +type ModuleAccount struct { + BaseAccount BaseAccount `json:"base_account"` + Name string `json:"name"` + Permissions []string `json:"permissions"` +} + +type Account struct { + *BaseAccount + *ModuleAccount + + Type string `json:"@type"` +} + +type Auth struct { + authtypes.GenesisState + + Params AuthParams `json:"params"` + Accounts []Account `json:"accounts"` +} + +// KeyOutput represents the JSON structure of the output from the add key command +type KeyOutput struct { + Name string `json:"name"` + Type string `json:"type"` + Address string `json:"address"` + PubKey string `json:"pubkey"` + Mnemonic string `json:"mnemonic"` +} diff --git a/scripts/chain-initiator/validate-genesis.go b/scripts/chain-initiator/validate-genesis.go new file mode 100644 index 0000000000..a8e24d02fe --- /dev/null +++ b/scripts/chain-initiator/validate-genesis.go @@ -0,0 +1,19 @@ +package main + +import ( + "log" + "os/exec" +) + +func validateGenesis(cmdPath, homePath string) { + // Command and arguments + args := []string{"validate-genesis", "--home", homePath} + + // Execute the command + if err := exec.Command(cmdPath, args...).Run(); err != nil { + log.Fatalf("Command execution failed: %v", err) + } + + // If execution reaches here, the command was successful + log.Printf("validate genesis with home path %s successfully", homePath) +} diff --git a/scripts/chain-initiator/write-genesis-file.go b/scripts/chain-initiator/write-genesis-file.go new file mode 100644 index 0000000000..d9334ee021 --- /dev/null +++ b/scripts/chain-initiator/write-genesis-file.go @@ -0,0 +1,28 @@ +package main + +import ( + "bufio" + "encoding/json" + "fmt" + "os" +) + +func writeGenesisFile(filePath string, genesis Genesis) error { + file, err := os.Create(filePath) + if err != nil { + return fmt.Errorf("error creating output file: %w", err) + } + defer file.Close() + + writer := bufio.NewWriter(file) + defer writer.Flush() + + encoder := json.NewEncoder(writer) + // encoder.SetIndent("", " ") // disable for now + + if err := encoder.Encode(genesis); err != nil { + return fmt.Errorf("error encoding JSON: %w", err) + } + + return nil +}