From 19a455a0d30c58b424408b80741ba7f2a21cf027 Mon Sep 17 00:00:00 2001 From: artpav <19916123+artemijspavlovs@users.noreply.github.com> Date: Mon, 8 Jul 2024 20:07:31 +0300 Subject: [PATCH] feat: add rollapp init (#803) --- cmd/config/init/flags.go | 100 ++------ cmd/config/init/format.go | 2 +- cmd/config/init/genesis.go | 392 ++++++++++++++--------------- cmd/config/init/local_hub.go | 309 +++++++++++------------ cmd/rollapp/init/main.go | 80 +++--- config/config.go | 78 +++--- go.mod | 1 + go.sum | 2 + test/config/init/testutils/keys.go | 7 +- utils/archives/archives.go | 66 ++--- 10 files changed, 494 insertions(+), 543 deletions(-) diff --git a/cmd/config/init/flags.go b/cmd/config/init/flags.go index 2ece8950..dd80eca7 100644 --- a/cmd/config/init/flags.go +++ b/cmd/config/init/flags.go @@ -1,17 +1,17 @@ package initconfig import ( + "encoding/json" "fmt" "path/filepath" "strings" + "github.com/BurntSushi/toml" "github.com/spf13/cobra" "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/cmd/utils" "github.com/dymensionxyz/roller/config" - global_utils "github.com/dymensionxyz/roller/utils" - "github.com/dymensionxyz/roller/version" ) const ( @@ -44,99 +44,45 @@ func AddFlags(cmd *cobra.Command) error { return nil } -func GetInitConfig(initCmd *cobra.Command, args []string) (*config.RollappConfig, error) { - home := initCmd.Flag(utils.FlagNames.Home).Value.String() - rollerConfigFilePath := filepath.Join(home, "roller.toml") - // interactive, _ := initCmd.Flags().GetBool(FlagNames.Interactive) - raType, err := global_utils.GetKeyFromTomlFile(rollerConfigFilePath, "execution") - if err != nil { - return nil, err - } - raID, err := global_utils.GetKeyFromTomlFile(rollerConfigFilePath, "rollapp_id") - if err != nil { - return nil, err - } - raBaseDenom, err := global_utils.GetKeyFromTomlFile(rollerConfigFilePath, "base_denom") - if err != nil { - return nil, err - } - da, err := global_utils.GetKeyFromTomlFile(rollerConfigFilePath, "da") - if err != nil { +func GetInitConfig( + initCmd *cobra.Command, + args []string, +) (*config.RollappConfig, error) { + var cfg config.RollappConfig + rollerConfigFilePath := filepath.Join(utils.GetRollerRootDir(), config.RollerConfigFileName) + if _, err := toml.DecodeFile(rollerConfigFilePath, &cfg); err != nil { return nil, err } - - fmt.Println(home, raType, raID, raBaseDenom, da) - - // load initial config if exists - var cfg config.RollappConfig - // load from flags - cfg.Home = home + cfg.Home = utils.GetRollerRootDir() // TODO: support wasm, make the bainry name generic, like 'rollappd' // for both RollApp types cfg.RollappBinary = consts.Executables.RollappEVM - cfg.VMType = config.VMType(raType) + // token supply is provided in the pre-created genesis // cfg.TokenSupply = initCmd.Flag(FlagNames.TokenSupply).Value.String() - // decimals, _ := initCmd.Flags().GetUint(FlagNames.Decimals) - cfg.Decimals = 18 - cfg.DA = config.DAType(strings.ToLower(da)) + cfg.DA = config.DAType(strings.ToLower(string(cfg.DA))) hubID := initCmd.Flag(FlagNames.HubID).Value.String() if hub, ok := consts.Hubs[hubID]; ok { cfg.HubData = hub } - cfg.RollerVersion = version.TrimVersionStr(version.BuildVersion) - cfg.RollappID = raID - cfg.Denom = raBaseDenom - - return formatBaseCfg(cfg, initCmd) -} + // cfg.RollerVersion = version.TrimVersionStr(version.BuildVersion) + // cfg.RollappID = raID + // cfg.Denom = raBaseDenom -func formatBaseCfg( - cfg config.RollappConfig, - initCmd *cobra.Command, -) (*config.RollappConfig, error) { - setDecimals(initCmd, &cfg) - return &cfg, nil -} + fmt.Println(cfg.VMType == config.EVM_ROLLAPP) -// there's no need for a custom chain id as the rollapp id is set via the genesis-creator -// func generateRollappId(rlpCfg config.RollappConfig) (string, error) { -// for { -// RandEthId, err := generateRandEthId() -// if err != nil { -// return "", err -// } -// if rlpCfg.HubData.ID == consts.LocalHubID { -// return fmt.Sprintf("%s_%s-1", rlpCfg.RollappID, RandEthId), nil -// } -// isUnique, err := isEthIdentifierUnique(RandEthId, rlpCfg) -// if err != nil { -// return "", err -// } -// if isUnique { -// return fmt.Sprintf("%s_%s-1", rlpCfg.RollappID, RandEthId), nil -// } -// } -// } - -// func generateRandEthId() (string, error) { -// max := big.NewInt(9000000) -// n, err := rand.Int(rand.Reader, max) -// if err != nil { -// return "", err -// } -// return fmt.Sprintf("%d", n), nil -// } - -func setDecimals(initCmd *cobra.Command, cfg *config.RollappConfig) { - decimals, _ := initCmd.Flags().GetUint(FlagNames.Decimals) - if cfg.VMType == config.EVM_ROLLAPP || initCmd.Flags().Lookup(FlagNames.Decimals).Changed { - cfg.Decimals = decimals + if cfg.VMType == config.EVM_ROLLAPP { + cfg.Decimals = 18 } else { cfg.Decimals = 6 } + + j, _ := json.MarshalIndent(cfg, "", " ") + fmt.Println(string(j)) + + return &cfg, nil } func getAvailableHubsMessage() string { diff --git a/cmd/config/init/format.go b/cmd/config/init/format.go index 147408ec..ac56e76c 100644 --- a/cmd/config/init/format.go +++ b/cmd/config/init/format.go @@ -35,7 +35,7 @@ func FormatTokenSupplyLine(rollappConfig config.RollappConfig) string { return fmt.Sprintf( "💰 Total Token Supply: %s %s. Note that 1 %s == 1 * 10^%d %s (like 1 ETH == 1 * 10^18 wei).", addCommasToNum( - rollappConfig.TokenSupply, + "1000000000", ), displayDenom, displayDenom, diff --git a/cmd/config/init/genesis.go b/cmd/config/init/genesis.go index 4ff9ac70..2904137f 100644 --- a/cmd/config/init/genesis.go +++ b/cmd/config/init/genesis.go @@ -1,131 +1,122 @@ package initconfig import ( - "fmt" - "math/big" "os" - "os/exec" - "path/filepath" - "strconv" - "strings" "github.com/tidwall/sjson" - - "github.com/dymensionxyz/roller/cmd/consts" - "github.com/dymensionxyz/roller/cmd/utils" - "github.com/dymensionxyz/roller/config" ) const ( totalSupplyToStakingRatio = 2 ) -func initializeRollappGenesis(initConfig config.RollappConfig) error { - totalTokenSupply, success := new(big.Int).SetString(initConfig.TokenSupply, 10) - if !success { - return fmt.Errorf("invalid token supply") - } - totalTokenSupply = totalTokenSupply.Mul(totalTokenSupply, new(big.Int).Exp(big.NewInt(10), - new(big.Int).SetUint64(uint64(initConfig.Decimals)), nil)) - relayerGenesisBalance := new(big.Int).Div(totalTokenSupply, big.NewInt(10)) - sequencerGenesisBalance := new(big.Int).Sub(totalTokenSupply, relayerGenesisBalance) - sequencerBalanceStr := sequencerGenesisBalance.String() + initConfig.Denom - relayerBalanceStr := relayerGenesisBalance.String() + initConfig.Denom - rollappConfigDirPath := filepath.Join(initConfig.Home, consts.ConfigDirName.Rollapp) - genesisSequencerAccountCmd := exec.Command( - initConfig.RollappBinary, - "add-genesis-account", - consts.KeysIds.RollappSequencer, - sequencerBalanceStr, - "--keyring-backend", - "test", - "--home", - rollappConfigDirPath, - ) - _, err := utils.ExecBashCommandWithStdout(genesisSequencerAccountCmd) - if err != nil { - return err - } - rlyRollappAddress, err := utils.GetRelayerAddress(initConfig.Home, initConfig.RollappID) - if err != nil { - return err - } - genesisRelayerAccountCmd := exec.Command( - initConfig.RollappBinary, - "add-genesis-account", - rlyRollappAddress, - relayerBalanceStr, - "--keyring-backend", - "test", - "--home", - rollappConfigDirPath, - ) - _, err = utils.ExecBashCommandWithStdout(genesisRelayerAccountCmd) - if err != nil { - return err - } - - err = updateGenesisParams( - GetGenesisFilePath(initConfig.Home), - initConfig.Denom, - initConfig.Decimals, - initConfig.Home, - ) - if err != nil { - return err - } - - err = generateGenesisTx(initConfig) - if err != nil { - return err - } - - err = createTokenMetadaJSON( - filepath.Join(RollappConfigDir(initConfig.Home), "tokenmetadata.json"), - initConfig.Denom, - initConfig.Decimals, - ) - if err != nil { - return err - } - - return nil -} - -func GetGenesisFilePath(root string) string { - return filepath.Join(RollappConfigDir(root), - "genesis.json") -} - type PathValue struct { Path string Value interface{} } -// TODO(#130): fix to support epochs -func getDefaultGenesisParams( - denom string, - decimals uint, - genesisOperatorAddress string, -) []PathValue { - return []PathValue{ - {"app_state.mint.params.mint_denom", denom}, - {"app_state.staking.params.bond_denom", denom}, - {"app_state.crisis.constant_fee.denom", denom}, - {"app_state.evm.params.evm_denom", denom}, - {"app_state.gov.deposit_params.min_deposit.0.denom", denom}, - {"consensus_params.block.max_gas", "40000000"}, - {"app_state.feemarket.params.no_base_fee", true}, - {"app_state.feemarket.params.min_gas_price", "0.0"}, - {"app_state.distribution.params.base_proposer_reward", "0.8"}, - {"app_state.distribution.params.community_tax", "0.00002"}, - {"app_state.gov.voting_params.voting_period", "300s"}, - {"app_state.staking.params.unbonding_time", "3628800s"}, - {"app_state.bank.denom_metadata", getBankDenomMetadata(denom, decimals)}, - {"app_state.sequencers.genesis_operator_address", genesisOperatorAddress}, - } -} - +// func initializeRollappGenesis(initConfig config.RollappConfig) error { +// totalTokenSupply, success := new(big.Int).SetString(initConfig.TokenSupply, 10) +// if !success { +// return fmt.Errorf("invalid token supply") +// } +// totalTokenSupply = totalTokenSupply.Mul(totalTokenSupply, new(big.Int).Exp(big.NewInt(10), +// new(big.Int).SetUint64(uint64(initConfig.Decimals)), nil)) +// relayerGenesisBalance := new(big.Int).Div(totalTokenSupply, big.NewInt(10)) +// sequencerGenesisBalance := new(big.Int).Sub(totalTokenSupply, relayerGenesisBalance) +// sequencerBalanceStr := sequencerGenesisBalance.String() + initConfig.Denom +// relayerBalanceStr := relayerGenesisBalance.String() + initConfig.Denom +// rollappConfigDirPath := filepath.Join(initConfig.Home, consts.ConfigDirName.Rollapp) +// genesisSequencerAccountCmd := exec.Command( +// initConfig.RollappBinary, +// "add-genesis-account", +// consts.KeysIds.RollappSequencer, +// sequencerBalanceStr, +// "--keyring-backend", +// "test", +// "--home", +// rollappConfigDirPath, +// ) +// _, err := utils.ExecBashCommandWithStdout(genesisSequencerAccountCmd) +// if err != nil { +// return err +// } +// rlyRollappAddress, err := utils.GetRelayerAddress(initConfig.Home, initConfig.RollappID) +// if err != nil { +// return err +// } +// genesisRelayerAccountCmd := exec.Command( +// initConfig.RollappBinary, +// "add-genesis-account", +// rlyRollappAddress, +// relayerBalanceStr, +// "--keyring-backend", +// "test", +// "--home", +// rollappConfigDirPath, +// ) +// _, err = utils.ExecBashCommandWithStdout(genesisRelayerAccountCmd) +// if err != nil { +// return err +// } +// +// err = updateGenesisParams( +// GetGenesisFilePath(initConfig.Home), +// initConfig.Denom, +// initConfig.Decimals, +// initConfig.Home, +// ) +// if err != nil { +// return err +// } +// +// err = generateGenesisTx(initConfig) +// if err != nil { +// return err +// } +// +// err = createTokenMetadaJSON( +// filepath.Join(RollappConfigDir(initConfig.Home), "tokenmetadata.json"), +// initConfig.Denom, +// initConfig.Decimals, +// ) +// if err != nil { +// return err +// } +// +// return nil +// } +// +// func GetGenesisFilePath(root string) string { +// return filepath.Join(RollappConfigDir(root), +// "genesis.json") +// } +// +// // TODO(#130): fix to support epochs +// func getDefaultGenesisParams( +// +// denom string, +// decimals uint, +// genesisOperatorAddress string, +// +// ) []PathValue { +// return []PathValue{ +// {"app_state.mint.params.mint_denom", denom}, +// {"app_state.staking.params.bond_denom", denom}, +// {"app_state.crisis.constant_fee.denom", denom}, +// {"app_state.evm.params.evm_denom", denom}, +// {"app_state.gov.deposit_params.min_deposit.0.denom", denom}, +// {"consensus_params.block.max_gas", "40000000"}, +// {"app_state.feemarket.params.no_base_fee", true}, +// {"app_state.feemarket.params.min_gas_price", "0.0"}, +// {"app_state.distribution.params.base_proposer_reward", "0.8"}, +// {"app_state.distribution.params.community_tax", "0.00002"}, +// {"app_state.gov.voting_params.voting_period", "300s"}, +// {"app_state.staking.params.unbonding_time", "3628800s"}, +// // {"app_state.bank.denom_metadata", getBankDenomMetadata(denom, decimals)}, +// {"app_state.sequencers.genesis_operator_address", genesisOperatorAddress}, +// } +// } func UpdateJSONParams(jsonFilePath string, params []PathValue) error { jsonFileContent, err := os.ReadFile(jsonFilePath) if err != nil { @@ -147,92 +138,93 @@ func UpdateJSONParams(jsonFilePath string, params []PathValue) error { return nil } -func updateGenesisParams(genesisFilePath string, denom string, decimals uint, home string) error { - oa, err := getGenesisOperatorAddress(home) - if err != nil { - return err - } - params := getDefaultGenesisParams(denom, decimals, oa) - return UpdateJSONParams(genesisFilePath, params) -} - -func getGenesisOperatorAddress(home string) (string, error) { - rollappConfigDirPath := filepath.Join(home, consts.ConfigDirName.Rollapp) - getOperatorAddrCommand := exec.Command( - consts.Executables.RollappEVM, - "keys", - "show", - consts.KeysIds.RollappSequencer, - "-a", - "--keyring-backend", - "test", - "--home", - rollappConfigDirPath, - "--bech", - "val", - ) - - addr, err := utils.ExecBashCommandWithStdout(getOperatorAddrCommand) - if err != nil { - return "", err - } - - a := strings.TrimSpace(addr.String()) - return a, nil -} - -func generateGenesisTx(initConfig config.RollappConfig) error { - err := registerSequencerAsGoverner(initConfig) - if err != nil { - return fmt.Errorf("failed to execute gentx command: %v", err) - } - // collect gentx - rollappConfigDirPath := filepath.Join(initConfig.Home, consts.ConfigDirName.Rollapp) - collectGentx := exec.Command( - initConfig.RollappBinary, - "collect-gentxs", - "--home", - rollappConfigDirPath, - ) - _, err = utils.ExecBashCommandWithStdout(collectGentx) - if err != nil { - return err - } - return nil -} - -// registerSequencerAsGoverner registers the sequencer as a governor of the rollapp chain. -// currently it sets the staking amount to half of the total token supply. -// TODO: make the staking amount configurable -func registerSequencerAsGoverner(initConfig config.RollappConfig) error { - totalSupply, err := strconv.Atoi(initConfig.TokenSupply) - if err != nil { - return fmt.Errorf("error converting string to integer: %w", err) - } - // Convert to token supply with decimals - stakedSupply := big.NewInt(int64(totalSupply / totalSupplyToStakingRatio)) - multiplier := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(initConfig.Decimals)), nil) - stakedSupply.Mul(stakedSupply, multiplier) - // Build and run the gentx command - rollappConfigDirPath := filepath.Join(initConfig.Home, consts.ConfigDirName.Rollapp) - gentxCmd := exec.Command( - initConfig.RollappBinary, - "gentx", - consts.KeysIds.RollappSequencer, - fmt.Sprint( - stakedSupply, - initConfig.Denom, - ), - "--chain-id", - initConfig.RollappID, - "--keyring-backend", - "test", - "--home", - rollappConfigDirPath, - ) - _, err = utils.ExecBashCommandWithStdout(gentxCmd) - if err != nil { - return err - } - return nil -} +// +// func updateGenesisParams(genesisFilePath string, denom string, decimals uint, home string) error { +// oa, err := getGenesisOperatorAddress(home) +// if err != nil { +// return err +// } +// params := getDefaultGenesisParams(denom, decimals, oa) +// return UpdateJSONParams(genesisFilePath, params) +// } +// +// func getGenesisOperatorAddress(home string) (string, error) { +// rollappConfigDirPath := filepath.Join(home, consts.ConfigDirName.Rollapp) +// getOperatorAddrCommand := exec.Command( +// consts.Executables.RollappEVM, +// "keys", +// "show", +// consts.KeysIds.RollappSequencer, +// "-a", +// "--keyring-backend", +// "test", +// "--home", +// rollappConfigDirPath, +// "--bech", +// "val", +// ) +// +// addr, err := utils.ExecBashCommandWithStdout(getOperatorAddrCommand) +// if err != nil { +// return "", err +// } +// +// a := strings.TrimSpace(addr.String()) +// return a, nil +// } +// +// func generateGenesisTx(initConfig config.RollappConfig) error { +// err := registerSequencerAsGoverner(initConfig) +// if err != nil { +// return fmt.Errorf("failed to execute gentx command: %v", err) +// } +// // collect gentx +// rollappConfigDirPath := filepath.Join(initConfig.Home, consts.ConfigDirName.Rollapp) +// collectGentx := exec.Command( +// initConfig.RollappBinary, +// "collect-gentxs", +// "--home", +// rollappConfigDirPath, +// ) +// _, err = utils.ExecBashCommandWithStdout(collectGentx) +// if err != nil { +// return err +// } +// return nil +// } +// +// // registerSequencerAsGoverner registers the sequencer as a governor of the rollapp chain. +// // currently it sets the staking amount to half of the total token supply. +// // TODO: make the staking amount configurable +// func registerSequencerAsGoverner(initConfig config.RollappConfig) error { +// totalSupply, err := strconv.Atoi(initConfig.TokenSupply) +// if err != nil { +// return fmt.Errorf("error converting string to integer: %w", err) +// } +// // Convert to token supply with decimals +// stakedSupply := big.NewInt(int64(totalSupply / totalSupplyToStakingRatio)) +// multiplier := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(initConfig.Decimals)), nil) +// stakedSupply.Mul(stakedSupply, multiplier) +// // Build and run the gentx command +// rollappConfigDirPath := filepath.Join(initConfig.Home, consts.ConfigDirName.Rollapp) +// gentxCmd := exec.Command( +// initConfig.RollappBinary, +// "gentx", +// consts.KeysIds.RollappSequencer, +// fmt.Sprint( +// stakedSupply, +// initConfig.Denom, +// ), +// "--chain-id", +// initConfig.RollappID, +// "--keyring-backend", +// "test", +// "--home", +// rollappConfigDirPath, +// ) +// _, err = utils.ExecBashCommandWithStdout(gentxCmd) +// if err != nil { +// return err +// } +// return nil +// } diff --git a/cmd/config/init/local_hub.go b/cmd/config/init/local_hub.go index fe2c9ba6..cff8665a 100644 --- a/cmd/config/init/local_hub.go +++ b/cmd/config/init/local_hub.go @@ -1,156 +1,157 @@ package initconfig -import ( - "fmt" - "os/exec" - "path/filepath" - - "github.com/dymensionxyz/roller/cmd/consts" - "github.com/dymensionxyz/roller/cmd/utils" - "github.com/dymensionxyz/roller/config" - global_utils "github.com/dymensionxyz/roller/utils" - "github.com/pelletier/go-toml" -) - -const validatorKeyID = "local-user" - -func initLocalHub(rlpCfg config.RollappConfig) error { - initBashCmd := getInitDymdCmd(rlpCfg) - _, err := utils.ExecBashCommandWithStdout(initBashCmd) - if err != nil { - return err - } - localHubPath := filepath.Join(rlpCfg.Home, consts.ConfigDirName.LocalHub) - if err = UpdateJSONParams(filepath.Join(localHubPath, "config", "genesis.json"), getHubGenesisParams()); err != nil { - return err - } - if err := UpdateTendermintConfig(rlpCfg); err != nil { - return err - } - if err := UpdateAppConfig(rlpCfg); err != nil { - return err - } - if err := UpdateClientConfig(rlpCfg); err != nil { - return err - } - if err != nil { - return err - } - addr, err := createAddressBinary(utils.KeyConfig{ - Dir: consts.ConfigDirName.LocalHub, - ID: validatorKeyID, - ChainBinary: consts.Executables.Dymension, - Type: config.SDK_ROLLAPP, - }, rlpCfg.Home) - if err != nil { - return err - } - addGenAccountCmd := exec.Command(consts.Executables.Dymension, "add-genesis-account", addr, - "1000000000000000000000000"+consts.Denoms.Hub, "--home", localHubPath) - _, err = utils.ExecBashCommandWithStdout(addGenAccountCmd) - if err != nil { - return err - } - genTxCmd := exec.Command( - consts.Executables.Dymension, - "gentx", - validatorKeyID, - "670000000000000000000000"+consts.Denoms.Hub, - "--home", - localHubPath, - "--chain-id", - rlpCfg.HubData.ID, - "--keyring-backend", - "test", - ) - _, err = utils.ExecBashCommandWithStdout(genTxCmd) - if err != nil { - return err - } - collectGentxsCmd := exec.Command(consts.Executables.Dymension, "collect-gentxs", "--home", - localHubPath) - _, err = utils.ExecBashCommandWithStdout(collectGentxsCmd) - if err != nil { - return err - } - return nil -} - -func getInitDymdCmd(rlpCfg config.RollappConfig) *exec.Cmd { - return exec.Command( - consts.Executables.Dymension, - "init", - "local", - "--chain-id", - rlpCfg.HubData.ID, - "--home", - filepath.Join(rlpCfg.Home, consts.ConfigDirName.LocalHub), - ) -} - -func getHubGenesisParams() []PathValue { - return []PathValue{ - {"app_state.rollapp.params.dispute_period_in_blocks", "2"}, - {"app_state.staking.params.max_validators", "110"}, - {"consensus_params.block.max_gas", "40000000"}, - {"app_state.feemarket.params.no_base_fee", true}, - {"app_state.evm.params.evm_denom", consts.Denoms.Hub}, - {"app_state.evm.params.enable_create", false}, - {"app_state.crisis.constant_fee.denom", consts.Denoms.Hub}, - {"app_state.staking.params.bond_denom", consts.Denoms.Hub}, - {"app_state.mint.params.mint_denom", consts.Denoms.Hub}, - } -} - -func UpdateTendermintConfig(rlpCfg config.RollappConfig) error { - tendermintConfigFilePath := filepath.Join( - rlpCfg.Home, - consts.ConfigDirName.LocalHub, - "config", - "config.toml", - ) - tmCfg, err := toml.LoadFile(tendermintConfigFilePath) - if err != nil { - return fmt.Errorf("failed to load %s: %v", tendermintConfigFilePath, err) - } - tmCfg.Set("rpc.laddr", "tcp://127.0.0.1:36657") - tmCfg.Set("p2p.laddr", "tcp://127.0.0.1:36656") - return global_utils.WriteTomlTreeToFile(tmCfg, tendermintConfigFilePath) -} - -func UpdateAppConfig(rlpCfg config.RollappConfig) error { - appConfigFilePath := filepath.Join( - rlpCfg.Home, - consts.ConfigDirName.LocalHub, - "config", - "app.toml", - ) - appCfg, err := toml.LoadFile(appConfigFilePath) - if err != nil { - return fmt.Errorf("failed to load %s: %v", appConfigFilePath, err) - } - appCfg.Set("grpc.address", "127.0.0.1:8090") - appCfg.Set("grpc-web.address", "127.0.0.1:8091") - appCfg.Set("json-rpc.address", "127.0.0.1:9545") - appCfg.Set("json-rpc.ws-address", "127.0.0.1:9546") - appCfg.Set("api.enable", true) - appCfg.Set("api.address", "tcp://127.0.0.1:1318") - appCfg.Set("minimum-gas-prices", "0"+consts.Denoms.Hub) - return global_utils.WriteTomlTreeToFile(appCfg, appConfigFilePath) -} - -func UpdateClientConfig(rlpCfg config.RollappConfig) error { - clientConfigFilePath := filepath.Join( - rlpCfg.Home, - consts.ConfigDirName.LocalHub, - "config", - "client.toml", - ) - clientCfg, err := toml.LoadFile(clientConfigFilePath) - if err != nil { - return fmt.Errorf("failed to load %s: %v", clientConfigFilePath, err) - } - clientCfg.Set("chain-id", rlpCfg.HubData.ID) - clientCfg.Set("node", "tcp://127.0.0.1:36657") - return global_utils.WriteTomlTreeToFile(clientCfg, clientConfigFilePath) -} +// +// import ( +// "fmt" +// "os/exec" +// "path/filepath" +// +// "github.com/dymensionxyz/roller/cmd/consts" +// "github.com/dymensionxyz/roller/cmd/utils" +// "github.com/dymensionxyz/roller/config" +// global_utils "github.com/dymensionxyz/roller/utils" +// "github.com/pelletier/go-toml" +// ) +// +// const validatorKeyID = "local-user" +// +// func initLocalHub(rlpCfg config.RollappConfig) error { +// initBashCmd := getInitDymdCmd(rlpCfg) +// _, err := utils.ExecBashCommandWithStdout(initBashCmd) +// if err != nil { +// return err +// } +// localHubPath := filepath.Join(rlpCfg.Home, consts.ConfigDirName.LocalHub) +// if err = UpdateJSONParams(filepath.Join(localHubPath, "config", "genesis.json"), getHubGenesisParams()); err != nil { +// return err +// } +// if err := UpdateTendermintConfig(rlpCfg); err != nil { +// return err +// } +// if err := UpdateAppConfig(rlpCfg); err != nil { +// return err +// } +// if err := UpdateClientConfig(rlpCfg); err != nil { +// return err +// } +// if err != nil { +// return err +// } +// addr, err := createAddressBinary(utils.KeyConfig{ +// Dir: consts.ConfigDirName.LocalHub, +// ID: validatorKeyID, +// ChainBinary: consts.Executables.Dymension, +// Type: config.SDK_ROLLAPP, +// }, rlpCfg.Home) +// if err != nil { +// return err +// } +// addGenAccountCmd := exec.Command(consts.Executables.Dymension, "add-genesis-account", addr, +// "1000000000000000000000000"+consts.Denoms.Hub, "--home", localHubPath) +// _, err = utils.ExecBashCommandWithStdout(addGenAccountCmd) +// if err != nil { +// return err +// } +// genTxCmd := exec.Command( +// consts.Executables.Dymension, +// "gentx", +// validatorKeyID, +// "670000000000000000000000"+consts.Denoms.Hub, +// "--home", +// localHubPath, +// "--chain-id", +// rlpCfg.HubData.ID, +// "--keyring-backend", +// "test", +// ) +// _, err = utils.ExecBashCommandWithStdout(genTxCmd) +// if err != nil { +// return err +// } +// collectGentxsCmd := exec.Command(consts.Executables.Dymension, "collect-gentxs", "--home", +// localHubPath) +// _, err = utils.ExecBashCommandWithStdout(collectGentxsCmd) +// if err != nil { +// return err +// } +// return nil +// } +// +// func getInitDymdCmd(rlpCfg config.RollappConfig) *exec.Cmd { +// return exec.Command( +// consts.Executables.Dymension, +// "init", +// "local", +// "--chain-id", +// rlpCfg.HubData.ID, +// "--home", +// filepath.Join(rlpCfg.Home, consts.ConfigDirName.LocalHub), +// ) +// } +// +// func getHubGenesisParams() []PathValue { +// return []PathValue{ +// {"app_state.rollapp.params.dispute_period_in_blocks", "2"}, +// {"app_state.staking.params.max_validators", "110"}, +// {"consensus_params.block.max_gas", "40000000"}, +// {"app_state.feemarket.params.no_base_fee", true}, +// {"app_state.evm.params.evm_denom", consts.Denoms.Hub}, +// {"app_state.evm.params.enable_create", false}, +// {"app_state.crisis.constant_fee.denom", consts.Denoms.Hub}, +// {"app_state.staking.params.bond_denom", consts.Denoms.Hub}, +// {"app_state.mint.params.mint_denom", consts.Denoms.Hub}, +// } +// } +// +// func UpdateTendermintConfig(rlpCfg config.RollappConfig) error { +// tendermintConfigFilePath := filepath.Join( +// rlpCfg.Home, +// consts.ConfigDirName.LocalHub, +// "config", +// "config.toml", +// ) +// tmCfg, err := toml.LoadFile(tendermintConfigFilePath) +// if err != nil { +// return fmt.Errorf("failed to load %s: %v", tendermintConfigFilePath, err) +// } +// tmCfg.Set("rpc.laddr", "tcp://127.0.0.1:36657") +// tmCfg.Set("p2p.laddr", "tcp://127.0.0.1:36656") +// return global_utils.WriteTomlTreeToFile(tmCfg, tendermintConfigFilePath) +// } +// +// func UpdateAppConfig(rlpCfg config.RollappConfig) error { +// appConfigFilePath := filepath.Join( +// rlpCfg.Home, +// consts.ConfigDirName.LocalHub, +// "config", +// "app.toml", +// ) +// appCfg, err := toml.LoadFile(appConfigFilePath) +// if err != nil { +// return fmt.Errorf("failed to load %s: %v", appConfigFilePath, err) +// } +// appCfg.Set("grpc.address", "127.0.0.1:8090") +// appCfg.Set("grpc-web.address", "127.0.0.1:8091") +// appCfg.Set("json-rpc.address", "127.0.0.1:9545") +// appCfg.Set("json-rpc.ws-address", "127.0.0.1:9546") +// appCfg.Set("api.enable", true) +// appCfg.Set("api.address", "tcp://127.0.0.1:1318") +// appCfg.Set("minimum-gas-prices", "0"+consts.Denoms.Hub) +// return global_utils.WriteTomlTreeToFile(appCfg, appConfigFilePath) +// } +// +// func UpdateClientConfig(rlpCfg config.RollappConfig) error { +// clientConfigFilePath := filepath.Join( +// rlpCfg.Home, +// consts.ConfigDirName.LocalHub, +// "config", +// "client.toml", +// ) +// clientCfg, err := toml.LoadFile(clientConfigFilePath) +// if err != nil { +// return fmt.Errorf("failed to load %s: %v", clientConfigFilePath, err) +// } +// clientCfg.Set("chain-id", rlpCfg.HubData.ID) +// clientCfg.Set("node", "tcp://127.0.0.1:36657") +// return global_utils.WriteTomlTreeToFile(clientCfg, clientConfigFilePath) +// } diff --git a/cmd/rollapp/init/main.go b/cmd/rollapp/init/main.go index d6e21ce8..f77ec38c 100644 --- a/cmd/rollapp/init/main.go +++ b/cmd/rollapp/init/main.go @@ -13,6 +13,7 @@ import ( initconfig "github.com/dymensionxyz/roller/cmd/config/init" "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/cmd/utils" + "github.com/dymensionxyz/roller/config" datalayer "github.com/dymensionxyz/roller/data_layer" global_utils "github.com/dymensionxyz/roller/utils" "github.com/dymensionxyz/roller/utils/archives" @@ -74,12 +75,7 @@ after configuration files are generated, rerun the 'init' command`, return } - err = archives.ExtractZip(archivePath) - if err != nil { - fmt.Println("failed to extract: ", err) - } - - err = runInit(cmd, args) + err = runInit(cmd, args, archivePath) if err != nil { fmt.Printf("failed to initialize the RollApp: %v\n", err) return @@ -103,34 +99,16 @@ func expandHomePath(path string) (string, error) { return path, nil } -func runInit(cmd *cobra.Command, args []string) error { - fmt.Println("running init") - // noOutput, err := cmd.Flags().GetBool(initconfig.FlagNames.NoOutput) - // if err != nil { - // utils.PrettifyErrorIfExists(err) - // return err - // } - - initConfigPtr, err := initconfig.GetInitConfig(cmd, args) - if err != nil { - utils.PrettifyErrorIfExists(err) - return err - } - - initConfig := *initConfigPtr - +// in runInit I parse the entire genesis creator zip file twice to extract +// the file this looks awful but since the archive has only 2 files it's +// kinda fine +func runInit(cmd *cobra.Command, args []string, configArchivePath string) error { + home := utils.GetRollerRootDir() outputHandler := initconfig.NewOutputHandler(false) - defer outputHandler.StopSpinner() - utils.RunOnInterrupt(outputHandler.StopSpinner) - outputHandler.StartSpinner(consts.SpinnerMsgs.UniqueIdVerification) - err = initConfig.Validate() - if err != nil { - utils.PrettifyErrorIfExists(err) - return err - } + defer outputHandler.StopSpinner() - isRootExist, err := global_utils.DirNotEmpty(initConfig.Home) + isRootExist, err := global_utils.DirNotEmpty(home) if err != nil { utils.PrettifyErrorIfExists(err) return err @@ -138,13 +116,13 @@ func runInit(cmd *cobra.Command, args []string) error { if isRootExist { outputHandler.StopSpinner() - shouldOverwrite, err := outputHandler.PromptOverwriteConfig(initConfig.Home) + shouldOverwrite, err := outputHandler.PromptOverwriteConfig(home) if err != nil { utils.PrettifyErrorIfExists(err) return err } if shouldOverwrite { - err = os.RemoveAll(initConfig.Home) + err = os.RemoveAll(home) if err != nil { utils.PrettifyErrorIfExists(err) return err @@ -155,7 +133,32 @@ func runInit(cmd *cobra.Command, args []string) error { } // nolint:gofumpt - err = os.MkdirAll(initConfig.Home, 0755) + err = os.MkdirAll(home, 0755) + if err != nil { + utils.PrettifyErrorIfExists(err) + return err + } + + err = archives.ExtractFileFromNestedTar( + configArchivePath, + config.RollerConfigFileName, + home, + ) + if err != nil { + return err + } + + initConfigPtr, err := initconfig.GetInitConfig(cmd, args) + if err != nil { + utils.PrettifyErrorIfExists(err) + return err + } + + initConfig := *initConfigPtr + + utils.RunOnInterrupt(outputHandler.StopSpinner) + outputHandler.StartSpinner(consts.SpinnerMsgs.UniqueIdVerification) + err = initConfig.Validate() if err != nil { utils.PrettifyErrorIfExists(err) return err @@ -218,6 +221,15 @@ func runInit(cmd *cobra.Command, args []string) error { return err } + err = archives.ExtractFileFromNestedTar( + configArchivePath, + "genesis.json", + filepath.Join(home, consts.ConfigDirName.Rollapp, "config"), + ) + if err != nil { + return err + } + // 20240607 genesis is generated using the genesis-creator // err = initializeRollappGenesis(initConfig) // if err != nil { diff --git a/config/config.go b/config/config.go index 19bdafe9..3d34edce 100644 --- a/config/config.go +++ b/config/config.go @@ -2,12 +2,11 @@ package config import ( "fmt" - "math/big" "strings" "unicode" ) -const RollerConfigFileName = "config.toml" +const RollerConfigFileName = "roller.toml" type VMType string @@ -27,16 +26,24 @@ const ( var SupportedDas = []DAType{Celestia, Avail, Local} type RollappConfig struct { - Home string - RollappID string + Home string `toml:"home"` + RollappID string `toml:"rollapp_id"` RollappBinary string - VMType VMType - Denom string - TokenSupply string + VMType VMType `toml:"execution"` + Denom string `toml:"denom"` + // TokenSupply string Decimals uint HubData HubData DA DAType - RollerVersion string + RollerVersion string `toml:"roller_version"` + + // new roller.toml + Environment string `toml:"environment"` + // Execution string `toml:"execution"` + ExecutionVersion string `toml:"execution_version"` + Bech32Prefix string `toml:"bech32_prefix"` + BaseDenom string `toml:"base_denom"` + MinGasPrices string `toml:"minimum_gas_prices"` } type HubData = struct { @@ -53,11 +60,14 @@ func (c RollappConfig) Validate() error { if err != nil { return err } - err = VerifyTokenSupply(c.TokenSupply) - if err != nil { - return err - } - err = IsValidDenom(c.Denom) + + // the assumption is that the supply is coming from the genesis creator + // err = VerifyTokenSupply(c.TokenSupply) + // if err != nil { + // return err + // } + + err = IsValidDenom(c.BaseDenom) if err != nil { return err } @@ -99,27 +109,27 @@ func VerifyHubID(data HubData) error { return nil } -func VerifyTokenSupply(supply string) error { - tokenSupply := new(big.Int) - _, ok := tokenSupply.SetString(supply, 10) - if !ok { - return fmt.Errorf("invalid token supply: %s. Must be a valid integer", supply) - } - - ten := big.NewInt(10) - remainder := new(big.Int) - remainder.Mod(tokenSupply, ten) - - if remainder.Cmp(big.NewInt(0)) != 0 { - return fmt.Errorf("invalid token supply: %s. Must be divisible by 10", supply) - } - - if tokenSupply.Cmp(big.NewInt(10_000_000)) < 0 { - return fmt.Errorf("token supply %s must be greater than 10,000,000", tokenSupply) - } - - return nil -} +// func VerifyTokenSupply(supply string) error { +// tokenSupply := new(big.Int) +// _, ok := tokenSupply.SetString(supply, 10) +// if !ok { +// return fmt.Errorf("invalid token supply: %s. Must be a valid integer", supply) +// } +// +// ten := big.NewInt(10) +// remainder := new(big.Int) +// remainder.Mod(tokenSupply, ten) +// +// if remainder.Cmp(big.NewInt(0)) != 0 { +// return fmt.Errorf("invalid token supply: %s. Must be divisible by 10", supply) +// } +// +// if tokenSupply.Cmp(big.NewInt(10_000_000)) < 0 { +// return fmt.Errorf("token supply %s must be greater than 10,000,000", tokenSupply) +// } +// +// return nil +// } func ValidateDecimals(decimals uint) error { if decimals > 18 { diff --git a/go.mod b/go.mod index 323b1f79..57456adc 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( ) require ( + github.com/BurntSushi/toml v1.4.0 // indirect github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/go.sum b/go.sum index 436c895e..2d803def 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3 github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= diff --git a/test/config/init/testutils/keys.go b/test/config/init/testutils/keys.go index ff2a18f6..3aa0f3f4 100644 --- a/test/config/init/testutils/keys.go +++ b/test/config/init/testutils/keys.go @@ -9,7 +9,6 @@ import ( "github.com/pelletier/go-toml" - initconfig "github.com/dymensionxyz/roller/cmd/config/init" "github.com/dymensionxyz/roller/cmd/consts" "github.com/dymensionxyz/roller/config" "github.com/dymensionxyz/roller/sequencer" @@ -39,9 +38,9 @@ func SanitizeConfigDir(root string, rlpCfg *config.RollappConfig) error { if err := os.Remove(nodeKeyPath); err != nil { return err } - if err := SanitizeGenesis(initconfig.GetGenesisFilePath(root)); err != nil { - return err - } + // if err := SanitizeGenesis(initconfig.GetGenesisFilePath(root)); err != nil { + // return err + // } if err := SanitizeRlyConfig(rlpCfg); err != nil { return err } diff --git a/utils/archives/archives.go b/utils/archives/archives.go index 448c6a6b..3ce93b49 100644 --- a/utils/archives/archives.go +++ b/utils/archives/archives.go @@ -7,16 +7,13 @@ import ( "io" "os" "path/filepath" - "slices" - - "github.com/dymensionxyz/roller/cmd/consts" - "github.com/dymensionxyz/roller/cmd/utils" ) -// ExtractZip function extracts the zip file created by the genesis-generator -// into a temporary directory and passes the tar archive container within -// the zip archive to ExtractTar for processing -func ExtractZip(zipFile string) error { +// TODO: work with actual gzip archive once genesis creator exports one + +// TraverseTARFile function extracts a .tar file from a .zip archive and +// extracts the fileName into outputDir +func ExtractFileFromNestedTar(sourceZipFilePath, fileName, outputDir string) error { tmpDir, err := os.MkdirTemp("", "genesis_zip_files") if err != nil { return err @@ -24,7 +21,7 @@ func ExtractZip(zipFile string) error { // nolint errcheck defer os.RemoveAll(tmpDir) - zipReader, err := zip.OpenReader(zipFile) + zipReader, err := zip.OpenReader(sourceZipFilePath) if err != nil { return err } @@ -33,7 +30,6 @@ func ExtractZip(zipFile string) error { var tarFilePath string - // Iterate through the files in the ZIP archive for _, f := range zipReader.File { if filepath.Ext(f.Name) == ".tar" { // nolint gosec @@ -41,6 +37,11 @@ func ExtractZip(zipFile string) error { if err := extractFileFromZip(f, tarFilePath); err != nil { return fmt.Errorf("failed to extract .tar file %s: %w", tarFilePath, err) } + + err := TraverseTARFile(tarFilePath, fileName, outputDir) + if err != nil { + return fmt.Errorf("failed to traverse the tar file: %v ", err) + } } } @@ -48,31 +49,20 @@ func ExtractZip(zipFile string) error { return fmt.Errorf("no .tar file found in the zip archive") } - // Process the extracted .tar file - if err := ExtractTar(tarFilePath, tmpDir); err != nil { - return fmt.Errorf("failed to extract .tar file %s: %w", tarFilePath, err) - } - return nil } -// ExtractTar function extracts the tar archive created by the genesis-generator -// and moves the files into the correct location -func ExtractTar(tarFile, outputDir string) error { - supportedFiles := []string{"roller.toml", "genesis.json"} - - // Open the .tar file +// TraverseTARFile function traverses a .tar archuve and extracts the fileName into +// outputDir +func TraverseTARFile(tarFile, fileName, outputDir string) error { file, err := os.Open(tarFile) if err != nil { return fmt.Errorf("failed to open tar file: %w", err) } // nolint errcheck defer file.Close() - - // Create a tar reader tarReader := tar.NewReader(file) - // Iterate through the files in the tar archive for { header, err := tarReader.Next() if err == io.EOF { @@ -82,26 +72,20 @@ func ExtractTar(tarFile, outputDir string) error { return fmt.Errorf("ExtractTar: Next() failed: %w", err) } - if !slices.Contains(supportedFiles, header.Name) { + if fileName != header.Name { continue } - switch header.Name { - case "roller.toml": - // Create directory - filePath := filepath.Join(utils.GetRollerRootDir(), "roller.toml") - err := createFileFromArchive(filePath, tarReader) + if fileName == header.Name { + fp := filepath.Join(outputDir, fileName) + fmt.Println(fp) + + err := createFileFromArchive(fp, tarReader) if err != nil { return err } - case "genesis.json": - filePath := filepath.Join( - utils.GetRollerRootDir(), - consts.ConfigDirName.Rollapp, - "config", - "genesis.json", - ) - err := createFileFromArchive(filePath, tarReader) + + _, err = os.Stat(fp) if err != nil { return err } @@ -112,10 +96,14 @@ func ExtractTar(tarFile, outputDir string) error { } func createFileFromArchive(outputPath string, tarReader *tar.Reader) error { - if err := os.MkdirAll(filepath.Dir(outputPath), 0o755); err != nil { + dir := filepath.Dir(outputPath) + + fmt.Println("creating dir:", dir) + if err := os.MkdirAll(dir, 0o755); err != nil { return fmt.Errorf("ExtractTar: MkdirAll() failed: %w", err) } + fmt.Println("creating file:", outputPath) outFile, err := os.Create(outputPath) if err != nil { return fmt.Errorf("ExtractTar: Create() failed: %w", err)