Skip to content

Commit

Permalink
feat: Auto-generate EIP115 and revision (#499)
Browse files Browse the repository at this point in the history
  • Loading branch information
ItayLevyOfficial authored Sep 6, 2023
1 parent ecfe396 commit 7715895
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 114 deletions.
39 changes: 35 additions & 4 deletions cmd/config/init/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package initconfig

import (
"fmt"
"math/rand"
"strings"
"time"

"github.com/dymensionxyz/roller/version"

Expand Down Expand Up @@ -49,13 +51,14 @@ func GetInitConfig(initCmd *cobra.Command, args []string) (config.RollappConfig,
if err := RunInteractiveMode(&cfg); err != nil {
return cfg, err
}
setDecimals(initCmd, &cfg)
return cfg, nil
return formatBaseCfg(cfg, initCmd), nil
}

rollappId := args[0]
denom := args[1]

if !isAlphanumeric(rollappId) {
return cfg, fmt.Errorf("invalid rollapp id %s. %s", rollappId, validRollappIDMsg)
}
hubID := initCmd.Flag(FlagNames.HubID).Value.String()
tokenSupply := initCmd.Flag(FlagNames.TokenSupply).Value.String()
cfg.RollappID = rollappId
Expand All @@ -64,8 +67,36 @@ func GetInitConfig(initCmd *cobra.Command, args []string) (config.RollappConfig,
cfg.TokenSupply = tokenSupply
cfg.DA = config.DAType(strings.ToLower(initCmd.Flag(FlagNames.DAType).Value.String()))
cfg.VMType = config.VMType(initCmd.Flag(FlagNames.VMType).Value.String())
return formatBaseCfg(cfg, initCmd), nil
}

func formatBaseCfg(cfg config.RollappConfig, initCmd *cobra.Command) config.RollappConfig {
setDecimals(initCmd, &cfg)
return cfg, nil
formattedRollappId, err := generateRollappId(cfg)
if err != nil {
return cfg
}
cfg.RollappID = formattedRollappId
return cfg
}

func generateRollappId(rlpCfg config.RollappConfig) (string, error) {
for {
RandEthId := generateRandEthId()
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 {
rand.Seed(time.Now().UnixNano())
randomNumber := rand.Intn(9000000) + 1000000
return fmt.Sprintf("%d", randomNumber)
}

func setDecimals(initCmd *cobra.Command, cfg *config.RollappConfig) {
Expand Down
17 changes: 6 additions & 11 deletions cmd/config/init/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func InitCmd() *cobra.Command {
Use: "init <rollapp-id> <denom> | --interactive",
Short: "Initialize a RollApp configuration on your local machine.",
Long: "Initialize a RollApp configuration on your local machine\n" + requiredFlagsUsage(),
Example: `init mars_9721-1 btc`,
Example: `init mars btc`,
PreRunE: func(cmd *cobra.Command, args []string) error {
interactive, _ := cmd.Flags().GetBool(FlagNames.Interactive)
if interactive {
Expand Down Expand Up @@ -46,14 +46,13 @@ func InitCmd() *cobra.Command {
return initCmd
}

const validRollappIDMsg = "A valid RollApp ID should contain only alphanumeric characters, for example, 'mars', 'venus', 'earth', etc."

func requiredFlagsUsage() string {
return `
A valid RollApp ID should follow the format 'name_uniqueID-revision', where
- 'name' is made up of lowercase English letters
- 'uniqueID' is a number up to the length of 5 digits representing the unique ID EIP155 rollapp ID
- 'revision' is a number up to the length of 5 digits representing the revision number for this rollapp
return fmt.Sprintf(`
%s
A valid denom should consist of 3-6 English alphabet letters, for example, 'btc', 'eth', 'pepe', etc.`
A valid denom should consist of 3-6 English alphabet letters, for example, 'btc', 'eth', 'pepe', etc.`, validRollappIDMsg)
}

func runInit(cmd *cobra.Command, args []string) error {
Expand All @@ -73,10 +72,6 @@ func runInit(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
err = VerifyUniqueRollappID(initConfig.RollappID, initConfig)
if err != nil {
return err
}
isRootExist, err := global_utils.DirNotEmpty(initConfig.Home)
if err != nil {
return err
Expand Down
28 changes: 15 additions & 13 deletions cmd/config/init/interactive.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"strings"
"unicode"

"github.com/dymensionxyz/roller/config"
"github.com/manifoldco/promptui"
Expand Down Expand Up @@ -50,27 +51,19 @@ func RunInteractiveMode(cfg *config.RollappConfig) error {
}
promptChainID := promptui.Prompt{
Label: "Enter your RollApp ID",
Default: "myrollapp_1234-1",
Default: "myrollapp",
AllowEdit: true,
}
for {
chainID, err := promptChainID.Run()
rollappID, err := promptChainID.Run()
if err != nil {
return err
}
if cfg.VMType == config.EVM_ROLLAPP {
err = config.ValidateRollAppID(chainID)
if err != nil {
fmt.Println(err)
continue
}
}
err = VerifyUniqueRollappID(chainID, *cfg)
if err != nil {
fmt.Println(err)
if !isAlphanumeric(rollappID) {
fmt.Printf("invalid rollapp id %s. %s\n", rollappID, validRollappIDMsg)
continue
}
cfg.RollappID = chainID
cfg.RollappID = rollappID
break
}

Expand Down Expand Up @@ -112,3 +105,12 @@ func RunInteractiveMode(cfg *config.RollappConfig) error {

return nil
}

func isAlphanumeric(s string) bool {
for _, r := range s {
if !unicode.IsLetter(r) && !unicode.IsDigit(r) {
return false
}
}
return true
}
59 changes: 2 additions & 57 deletions cmd/config/init/unique_rollapp_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,12 @@ package initconfig

import (
"encoding/json"
"fmt"
"github.com/dymensionxyz/roller/cmd/consts"
"github.com/dymensionxyz/roller/cmd/utils"
"github.com/dymensionxyz/roller/config"
"net/http"
"os/exec"
"strings"
)

// TODO(#150): roller should use RPC for queries instead of REST
func IsRollappIDUnique(rollappID string, initConfig config.RollappConfig) (bool, error) {
if initConfig.VMType == config.SDK_ROLLAPP {
url := initConfig.HubData.API_URL + "/dymensionxyz/dymension/rollapp/rollapp/" + rollappID

req, err := http.NewRequest("GET", url, nil)
if err != nil {
return false, err
}

req.Header.Set("accept", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return false, err
}
defer resp.Body.Close()

if resp.StatusCode == 404 {
return true, nil
} else if resp.StatusCode == 200 {
return false, nil
} else {
return false, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
} else {
return verifyUniqueEthIdentifier(rollappID, initConfig)
}
}

type Rollapp struct {
ID string `json:"rollappId"`
}
Expand All @@ -50,7 +16,7 @@ type RollappsListResponse struct {
Rollapps []Rollapp `json:"rollapp"`
}

func verifyUniqueEthIdentifier(rollappID string, rlpCfg config.RollappConfig) (bool, error) {
func isEthIdentifierUnique(ethID string, rlpCfg config.RollappConfig) (bool, error) {
commonDymdFlags := utils.GetCommonDymdFlags(rlpCfg)
// TODO: Move the filtering by ethereum rollapp ID logic to the hub
args := []string{"q", "rollapp", "list", "--limit", "1000000"}
Expand All @@ -66,30 +32,9 @@ func verifyUniqueEthIdentifier(rollappID string, rlpCfg config.RollappConfig) (b
return false, err
}
for _, rollapp := range rollappsListResponse.Rollapps {
if config.GetEthID(rollapp.ID) == config.GetEthID(rollappID) {
if config.GetEthID(rollapp.ID) == ethID {
return false, nil
}
}
return true, nil
}

func VerifyUniqueRollappID(rollappID string, initConfig config.RollappConfig) error {
isUniqueRollapp, err := IsRollappIDUnique(rollappID, initConfig)
if err != nil {
if initConfig.HubData.ID == LocalHubID {
// When using a local hub and the hub is not yet running, we assume the rollapp ID is unique
return nil
}
return err
}
if !isUniqueRollapp {
if initConfig.VMType == config.SDK_ROLLAPP {
return fmt.Errorf("rollapp ID \"%s\" already exists on the hub. Please use a unique ID", rollappID)
} else {
ethID := config.GetEthID(rollappID)
return fmt.Errorf("EIP155 ID \"%s\" already exists on the hub (%s). Please use a unique EIP155 ID",
ethID, strings.Replace(rollappID, ethID, fmt.Sprintf("*%s*", ethID), 1))
}
}
return nil
}
23 changes: 0 additions & 23 deletions config/chainid.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,9 @@
package config

import (
"fmt"
"regexp"
)

var (
regexChainID = `[a-z]{1,}`
regexEIP155Separator = `_{1}`
regexEIP155 = `[1-9][0-9]*`
regexEpochSeparator = `-{1}`
regexEpoch = `[1-9][0-9]*`
rollappID = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)%s(%s)$`,
regexChainID,
regexEIP155Separator,
regexEIP155,
regexEpochSeparator,
regexEpoch))
)

func ValidateRollAppID(id string) error {
if !rollappID.MatchString(id) {
return fmt.Errorf("invalid RollApp ID '%s'. "+
"Expected format: name_uniqueID-revision (e.g. myrollapp_1234-1)", id)
}
return nil
}

func GetEthID(rollappID string) string {
re := regexp.MustCompile(`_(\d+)-`)
matches := re.FindStringSubmatch(rollappID)
Expand Down
6 changes: 0 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,6 @@ func (c RollappConfig) Validate() error {
if err != nil {
return err
}
if c.VMType == EVM_ROLLAPP {
err = ValidateRollAppID(c.RollappID)
if err != nil {
return err
}
}
err = IsValidDenom(c.Denom)
if err != nil {
return err
Expand Down

0 comments on commit 7715895

Please sign in to comment.