github.com/cosmos/cosmos-sdk@v0.50.10/x/genutil/client/cli/genaccount_test.go (about) 1 package cli_test 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "os" 8 "path" 9 "testing" 10 11 "github.com/spf13/viper" 12 "github.com/stretchr/testify/require" 13 14 "cosmossdk.io/log" 15 16 "github.com/cosmos/cosmos-sdk/client" 17 "github.com/cosmos/cosmos-sdk/client/flags" 18 addresscodec "github.com/cosmos/cosmos-sdk/codec/address" 19 "github.com/cosmos/cosmos-sdk/crypto/hd" 20 "github.com/cosmos/cosmos-sdk/crypto/keyring" 21 "github.com/cosmos/cosmos-sdk/server" 22 "github.com/cosmos/cosmos-sdk/testutil/testdata" 23 sdk "github.com/cosmos/cosmos-sdk/types" 24 moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" 25 "github.com/cosmos/cosmos-sdk/x/auth" 26 banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" 27 "github.com/cosmos/cosmos-sdk/x/genutil" 28 genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" 29 genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" 30 genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" 31 ) 32 33 func TestAddGenesisAccountCmd(t *testing.T) { 34 _, _, addr1 := testdata.KeyTestPubAddr() 35 tests := []struct { 36 name string 37 addr string 38 denom string 39 withKeyring bool 40 expectErr bool 41 }{ 42 { 43 name: "invalid address", 44 addr: "", 45 denom: "1000atom", 46 withKeyring: false, 47 expectErr: true, 48 }, 49 { 50 name: "valid address", 51 addr: addr1.String(), 52 denom: "1000atom", 53 withKeyring: false, 54 expectErr: false, 55 }, 56 { 57 name: "multiple denoms", 58 addr: addr1.String(), 59 denom: "1000atom, 2000stake", 60 withKeyring: false, 61 expectErr: false, 62 }, 63 { 64 name: "with keyring", 65 addr: "ser", 66 denom: "1000atom", 67 withKeyring: true, 68 expectErr: false, 69 }, 70 } 71 72 for _, tc := range tests { 73 tc := tc 74 t.Run(tc.name, func(t *testing.T) { 75 home := t.TempDir() 76 logger := log.NewNopLogger() 77 cfg, err := genutiltest.CreateDefaultCometConfig(home) 78 require.NoError(t, err) 79 80 appCodec := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}).Codec 81 err = genutiltest.ExecInitCmd(testMbm, home, appCodec) 82 require.NoError(t, err) 83 84 serverCtx := server.NewContext(viper.New(), cfg, logger) 85 clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home) 86 87 if tc.withKeyring { 88 path := hd.CreateHDPath(118, 0, 0).String() 89 kr, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, home, nil, appCodec) 90 require.NoError(t, err) 91 _, _, err = kr.NewMnemonic(tc.addr, keyring.English, path, keyring.DefaultBIP39Passphrase, hd.Secp256k1) 92 require.NoError(t, err) 93 clientCtx = clientCtx.WithKeyring(kr) 94 } 95 96 ctx := context.Background() 97 ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) 98 ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) 99 100 cmd := genutilcli.AddGenesisAccountCmd(home, addresscodec.NewBech32Codec("cosmos")) 101 cmd.SetArgs([]string{ 102 tc.addr, 103 tc.denom, 104 fmt.Sprintf("--%s=home", flags.FlagHome), 105 }) 106 107 if tc.expectErr { 108 require.Error(t, cmd.ExecuteContext(ctx)) 109 } else { 110 require.NoError(t, cmd.ExecuteContext(ctx)) 111 } 112 }) 113 } 114 } 115 116 func TestBulkAddGenesisAccountCmd(t *testing.T) { 117 _, _, addr1 := testdata.KeyTestPubAddr() 118 _, _, addr2 := testdata.KeyTestPubAddr() 119 _, _, addr3 := testdata.KeyTestPubAddr() 120 addr1Str := addr1.String() 121 addr2Str := addr2.String() 122 addr3Str := addr3.String() 123 124 tests := []struct { 125 name string 126 state [][]genutil.GenesisAccount 127 expected map[string]sdk.Coins 128 appendFlag bool 129 expectErr bool 130 }{ 131 { 132 name: "invalid address", 133 state: [][]genutil.GenesisAccount{ 134 { 135 { 136 Address: "invalid", 137 Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), 138 }, 139 }, 140 }, 141 expectErr: true, 142 }, 143 { 144 name: "no append flag for multiple account adds", 145 state: [][]genutil.GenesisAccount{ 146 { 147 { 148 Address: addr1Str, 149 Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), 150 }, 151 }, 152 { 153 { 154 Address: addr1Str, 155 Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 2)), 156 }, 157 }, 158 }, 159 appendFlag: false, 160 expectErr: true, 161 }, 162 163 { 164 name: "multiple additions with append", 165 state: [][]genutil.GenesisAccount{ 166 { 167 { 168 Address: addr1Str, 169 Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), 170 }, 171 { 172 Address: addr2Str, 173 Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), 174 }, 175 }, 176 { 177 { 178 Address: addr1Str, 179 Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 2)), 180 }, 181 { 182 Address: addr2Str, 183 Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 1)), 184 }, 185 { 186 Address: addr3Str, 187 Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), 188 }, 189 }, 190 }, 191 expected: map[string]sdk.Coins{ 192 addr1Str: sdk.NewCoins(sdk.NewInt64Coin("test", 3)), 193 addr2Str: sdk.NewCoins(sdk.NewInt64Coin("test", 1), sdk.NewInt64Coin("stake", 1)), 194 addr3Str: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), 195 }, 196 appendFlag: true, 197 expectErr: false, 198 }, 199 } 200 201 for _, tc := range tests { 202 tc := tc 203 t.Run(tc.name, func(t *testing.T) { 204 home := t.TempDir() 205 logger := log.NewNopLogger() 206 cfg, err := genutiltest.CreateDefaultCometConfig(home) 207 require.NoError(t, err) 208 209 appCodec := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}).Codec 210 err = genutiltest.ExecInitCmd(testMbm, home, appCodec) 211 require.NoError(t, err) 212 213 serverCtx := server.NewContext(viper.New(), cfg, logger) 214 clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home) 215 216 ctx := context.Background() 217 ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) 218 ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) 219 220 // The first iteration (pre-append) may not error. 221 // Check if any errors after all state transitions to genesis. 222 doesErr := false 223 224 // apply multiple state iterations if applicable (e.g. --append) 225 for _, state := range tc.state { 226 bz, err := json.Marshal(state) 227 require.NoError(t, err) 228 229 filePath := path.Join(home, "accounts.json") 230 err = os.WriteFile(filePath, bz, 0o600) 231 require.NoError(t, err) 232 233 cmd := genutilcli.AddBulkGenesisAccountCmd(home, addresscodec.NewBech32Codec("cosmos")) 234 args := []string{filePath} 235 if tc.appendFlag { 236 args = append(args, "--append") 237 } 238 cmd.SetArgs(args) 239 240 err = cmd.ExecuteContext(ctx) 241 if err != nil { 242 doesErr = true 243 } 244 } 245 require.Equal(t, tc.expectErr, doesErr) 246 247 // an error already occurred, no need to check the state 248 if doesErr { 249 return 250 } 251 252 appState, _, err := genutiltypes.GenesisStateFromGenFile(path.Join(home, "config", "genesis.json")) 253 require.NoError(t, err) 254 255 bankState := banktypes.GetGenesisStateFromAppState(appCodec, appState) 256 257 require.EqualValues(t, len(tc.expected), len(bankState.Balances)) 258 for _, acc := range bankState.Balances { 259 require.True(t, tc.expected[acc.Address].Equal(acc.Coins), "expected: %v, got: %v", tc.expected[acc.Address], acc.Coins) 260 } 261 262 expectedSupply := sdk.NewCoins() 263 for _, coins := range tc.expected { 264 expectedSupply = expectedSupply.Add(coins...) 265 } 266 require.Equal(t, expectedSupply, bankState.Supply) 267 }) 268 } 269 }