Skip to content

Commit 18ddc93

Browse files
feat: initial genesis replace cmd
1 parent fe70928 commit 18ddc93

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-0
lines changed

cmd/fetchd/cmd/genreplace.go

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
package cmd
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"regexp"
7+
"strings"
8+
9+
"github.com/spf13/cobra"
10+
11+
"github.com/cosmos/cosmos-sdk/client"
12+
"github.com/cosmos/cosmos-sdk/client/flags"
13+
"github.com/cosmos/cosmos-sdk/server"
14+
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
15+
"github.com/cosmos/cosmos-sdk/x/genutil"
16+
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
17+
)
18+
19+
const (
20+
flagNewDescription = "new-description"
21+
)
22+
23+
// ReplaceGenesisValuesCmd returns replace-genesis-values cobra Command.
24+
func ReplaceGenesisValuesCmd(defaultNodeHome string) *cobra.Command {
25+
cmd := &cobra.Command{
26+
Use: "replace-genesis-values [new-denom] [old-denom]",
27+
Short: "Replace the major values within genesis.json, such as native denom",
28+
Long: `Replace the major values within genesis.json, such as native denom.
29+
`,
30+
Args: cobra.ExactArgs(2),
31+
RunE: func(cmd *cobra.Command, args []string) error {
32+
clientCtx := client.GetClientContextFromCmd(cmd)
33+
cdc := clientCtx.Codec
34+
35+
serverCtx := server.GetServerContextFromCmd(cmd)
36+
config := serverCtx.Config
37+
38+
config.SetRoot(clientCtx.HomeDir)
39+
40+
newDesc, err := cmd.Flags().GetString(flagNewDescription)
41+
if err != nil {
42+
return err
43+
}
44+
45+
inputData := replacementData{
46+
NewBaseDenom: args[0],
47+
OldBaseDenom: args[1],
48+
NewDenom: fmt.Sprintf("a%s", args[0]),
49+
OldDenom: fmt.Sprintf("a%s", args[1]),
50+
NewDescription: newDesc,
51+
OldAddrPrefix: "fetch",
52+
NewAddrPrefix: "asi",
53+
}
54+
55+
genFile := config.GenesisFile()
56+
57+
appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile)
58+
if err != nil {
59+
return fmt.Errorf("failed to unmarshal genesis state: %w", err)
60+
}
61+
62+
//authGenState := authtypes.GetGenesisStateFromAppState(cdc, appState) TODO: amend account prefix here, potentially
63+
64+
bankGenState := banktypes.GetGenesisStateFromAppState(cdc, appState)
65+
replaceDenomMetadata(&inputData, bankGenState)
66+
67+
bankGenStateBz, err := cdc.MarshalJSON(bankGenState)
68+
if err != nil {
69+
return fmt.Errorf("failed to marshal auth genesis state: %w", err)
70+
}
71+
72+
appState[banktypes.ModuleName] = bankGenStateBz
73+
74+
appStateJSON, err := json.Marshal(appState)
75+
if err != nil {
76+
return fmt.Errorf("failed to marshal application genesis state: %w", err)
77+
}
78+
79+
appStateStr := string(appStateJSON)
80+
for _, target := range []string{"denom", "bond_denom", "mint_denom", "base_denom", "base"} {
81+
re := regexp.MustCompile(fmt.Sprintf(`("%s"\s*:\s*)"%s"`, target, inputData.OldDenom))
82+
if re.MatchString(appStateStr) {
83+
appStateStr = re.ReplaceAllString(appStateStr, fmt.Sprintf(`${1}"%s"`, inputData.NewDenom))
84+
}
85+
}
86+
87+
genDoc.AppState = []byte(appStateStr)
88+
return genutil.ExportGenesisFile(genDoc, genFile)
89+
},
90+
}
91+
92+
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
93+
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
94+
cmd.Flags().String(flagNewDescription, "", "The new description for the native coin in the genesis file")
95+
flags.AddQueryFlagsToCmd(cmd)
96+
97+
return cmd
98+
}
99+
100+
func replaceDenomMetadata(d *replacementData, b *banktypes.GenesisState) {
101+
denomRegex := getRegex(d.OldDenom, d.NewDenom)
102+
upperDenomRegex := getRegex(strings.ToUpper(d.OldBaseDenom), strings.ToUpper(d.NewBaseDenom))
103+
exponentDenomRegex := getPartialRegexLeft(d.OldBaseDenom, d.NewBaseDenom)
104+
105+
for _, metadata := range b.DenomMetadata {
106+
replaceString(&metadata.Base, []*regexPair{denomRegex})
107+
if metadata.Name == d.OldBaseDenom {
108+
metadata.Description = d.NewDescription
109+
}
110+
replaceString(&metadata.Display, []*regexPair{upperDenomRegex})
111+
replaceString(&metadata.Name, []*regexPair{upperDenomRegex})
112+
replaceString(&metadata.Symbol, []*regexPair{upperDenomRegex})
113+
for _, unit := range metadata.DenomUnits {
114+
replaceString(&unit.Denom, []*regexPair{upperDenomRegex})
115+
replaceString(&unit.Denom, []*regexPair{exponentDenomRegex})
116+
}
117+
118+
}
119+
}
120+
121+
func getRegex(oldValue string, newValue string) *regexPair {
122+
return &regexPair{
123+
pattern: fmt.Sprintf(`^%s$`, oldValue),
124+
replacement: fmt.Sprintf(`%s`, newValue),
125+
}
126+
}
127+
128+
func getPartialRegexLeft(oldValue string, newValue string) *regexPair {
129+
return &regexPair{
130+
pattern: fmt.Sprintf(`(.*?)%s`, oldValue),
131+
replacement: fmt.Sprintf(`${1}%s`, newValue),
132+
}
133+
}
134+
135+
func getPartialRegexRight(oldValue string, newValue string) *regexPair {
136+
return &regexPair{
137+
pattern: fmt.Sprintf(`%s(.*)`, oldValue),
138+
replacement: fmt.Sprintf(`%s${1}`, newValue),
139+
}
140+
}
141+
142+
func replaceString(s *string, replacements []*regexPair) {
143+
for _, pair := range replacements {
144+
re := regexp.MustCompile(pair.pattern)
145+
if re.MatchString(*s) {
146+
*s = re.ReplaceAllString(*s, pair.replacement)
147+
}
148+
}
149+
}
150+
151+
type regexPair struct {
152+
pattern string
153+
replacement string
154+
}
155+
156+
type replacementData struct {
157+
NewBaseDenom string
158+
OldBaseDenom string
159+
NewDenom string
160+
OldDenom string
161+
NewDescription string
162+
OldAddrPrefix string
163+
NewAddrPrefix string
164+
}

cmd/fetchd/cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
132132
genutilcli.ValidateGenesisCmd(app.ModuleBasics),
133133
AddGenesisAccountCmd(app.DefaultNodeHome),
134134
AddGenesisDelegationCmd(app.DefaultNodeHome),
135+
ReplaceGenesisValuesCmd(app.DefaultNodeHome),
135136
tmcli.NewCompletionCmd(rootCmd, true),
136137
debug.Cmd(),
137138
AddGenesisWasmMsgCmd(app.DefaultNodeHome),

0 commit comments

Comments
 (0)