diff --git a/app/app.go b/app/app.go index a9c0c240..865dad5f 100644 --- a/app/app.go +++ b/app/app.go @@ -19,7 +19,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/crisis" distr "github.com/cosmos/cosmos-sdk/x/distribution" - "github.com/cosmos/cosmos-sdk/x/genaccounts" "github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/mint" @@ -43,7 +42,6 @@ var ( // non-dependant module elements, such as codec registration // and genesis verification. ModuleBasics = module.NewBasicManager( - genaccounts.AppModuleBasic{}, genutil.AppModuleBasic{}, auth.AppModuleBasic{}, bank.AppModuleBasic{}, @@ -182,7 +180,6 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. app.mm = module.NewManager( - genaccounts.NewAppModule(app.accountKeeper), genutil.NewAppModule(app.accountKeeper, app.stakingKeeper, app.BaseApp.DeliverTx), auth.NewAppModule(app.accountKeeper), bank.NewAppModule(app.bankKeeper, app.accountKeeper), @@ -205,9 +202,9 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b // NOTE: The genutils module must occur after staking so that pools are // properly initialized with tokens from genesis accounts. app.mm.SetOrderInitGenesis( - genaccounts.ModuleName, distr.ModuleName, staking.ModuleName, - auth.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName, - mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName, + distr.ModuleName, staking.ModuleName, auth.ModuleName, bank.ModuleName, + slashing.ModuleName, gov.ModuleName, mint.ModuleName, supply.ModuleName, + crisis.ModuleName, genutil.ModuleName, ) app.mm.RegisterInvariants(&app.crisisKeeper) @@ -218,7 +215,6 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b // NOTE: This is not required for apps that don't use the simulator for fuzz testing // transactions. app.sm = module.NewSimulationManager( - genaccounts.NewAppModule(app.accountKeeper), auth.NewAppModule(app.accountKeeper), bank.NewAppModule(app.bankKeeper, app.accountKeeper), supply.NewAppModule(app.supplyKeeper, app.accountKeeper), diff --git a/app/app_test.go b/app/app_test.go index 1388fe02..7f8b971d 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -28,10 +28,10 @@ func TestGaiadExport(t *testing.T) { // ensure that black listed addresses are properly set in bank keeper func TestBlackListedAddrs(t *testing.T) { db := db.NewMemDB() - app := NewGaiaApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0) + gapp := NewGaiaApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0) for acc := range maccPerms { - require.True(t, app.bankKeeper.BlacklistedAddr(app.supplyKeeper.GetModuleAddress(acc))) + require.True(t, gapp.bankKeeper.BlacklistedAddr(gapp.supplyKeeper.GetModuleAddress(acc))) } } diff --git a/app/genesis.go b/app/genesis.go new file mode 100644 index 00000000..97258ac9 --- /dev/null +++ b/app/genesis.go @@ -0,0 +1,11 @@ +package app + +import "encoding/json" + +// GenesisState defines a type alias for the Gaia genesis application state. +type GenesisState map[string]json.RawMessage + +// NewDefaultGenesisState generates the default state for the application. +func NewDefaultGenesisState() GenesisState { + return ModuleBasics.DefaultGenesis() +} diff --git a/app/sim_test.go b/app/sim_test.go index 00273bee..2924d24f 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -261,18 +261,18 @@ func BenchmarkFullAppSimulation(b *testing.B) { _ = os.RemoveAll(dir) }() - app := NewGaiaApp(logger, db, nil, true, simapp.FlagPeriodValue, interBlockCacheOpt()) + gapp := NewGaiaApp(logger, db, nil, true, simapp.FlagPeriodValue, interBlockCacheOpt()) // Run randomized simulation // TODO: parameterize numbers, save for a later PR _, simParams, simErr := simulation.SimulateFromSeed( - b, os.Stdout, app.BaseApp, simapp.AppStateFn(app.Codec(), app.sm), - testAndRunTxs(app, config), app.ModuleAccountAddrs(), config, + b, os.Stdout, gapp.BaseApp, simapp.AppStateFn(gapp.Codec(), gapp.sm), + testAndRunTxs(gapp, config), gapp.ModuleAccountAddrs(), config, ) // export state and params before the simulation error is checked if config.ExportStatePath != "" { - if err := ExportStateToJSON(app, config.ExportStatePath); err != nil { + if err := ExportStateToJSON(gapp, config.ExportStatePath); err != nil { fmt.Println(err) b.Fail() } @@ -320,18 +320,18 @@ func TestFullAppSimulation(t *testing.T) { _ = os.RemoveAll(dir) }() - app := NewGaiaApp(logger, db, nil, true, simapp.FlagPeriodValue, fauxMerkleModeOpt) - require.Equal(t, "GaiaApp", app.Name()) + gapp := NewGaiaApp(logger, db, nil, true, simapp.FlagPeriodValue, fauxMerkleModeOpt) + require.Equal(t, "GaiaApp", gapp.Name()) // Run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( - t, os.Stdout, app.BaseApp, simapp.AppStateFn(app.Codec(), app.sm), - testAndRunTxs(app, config), app.ModuleAccountAddrs(), config, + t, os.Stdout, gapp.BaseApp, simapp.AppStateFn(gapp.Codec(), gapp.sm), + testAndRunTxs(gapp, config), gapp.ModuleAccountAddrs(), config, ) // export state and params before the simulation error is checked if config.ExportStatePath != "" { - err := ExportStateToJSON(app, config.ExportStatePath) + err := ExportStateToJSON(gapp, config.ExportStatePath) require.NoError(t, err) } @@ -490,19 +490,19 @@ func TestAppSimulationAfterImport(t *testing.T) { _ = os.RemoveAll(dir) }() - app := NewGaiaApp(logger, db, nil, true, simapp.FlagPeriodValue, fauxMerkleModeOpt) - require.Equal(t, "GaiaApp", app.Name()) + gapp := NewGaiaApp(logger, db, nil, true, simapp.FlagPeriodValue, fauxMerkleModeOpt) + require.Equal(t, "GaiaApp", gapp.Name()) // Run randomized simulation // Run randomized simulation stopEarly, simParams, simErr := simulation.SimulateFromSeed( - t, os.Stdout, app.BaseApp, simapp.AppStateFn(app.Codec(), app.sm), - testAndRunTxs(app, config), app.ModuleAccountAddrs(), config, + t, os.Stdout, gapp.BaseApp, simapp.AppStateFn(gapp.Codec(), gapp.sm), + testAndRunTxs(gapp, config), gapp.ModuleAccountAddrs(), config, ) // export state and params before the simulation error is checked if config.ExportStatePath != "" { - err := ExportStateToJSON(app, config.ExportStatePath) + err := ExportStateToJSON(gapp, config.ExportStatePath) require.NoError(t, err) } @@ -529,7 +529,7 @@ func TestAppSimulationAfterImport(t *testing.T) { fmt.Printf("Exporting genesis...\n") - appState, _, err := app.ExportAppStateAndValidators(true, []string{}) + appState, _, err := gapp.ExportAppStateAndValidators(true, []string{}) if err != nil { panic(err) } @@ -553,7 +553,7 @@ func TestAppSimulationAfterImport(t *testing.T) { // Run randomized simulation on imported app _, _, err = simulation.SimulateFromSeed( - t, os.Stdout, newApp.BaseApp, simapp.AppStateFn(app.Codec(), app.sm), + t, os.Stdout, newApp.BaseApp, simapp.AppStateFn(gapp.Codec(), gapp.sm), testAndRunTxs(newApp, config), newApp.ModuleAccountAddrs(), config, ) @@ -623,17 +623,17 @@ func BenchmarkInvariants(b *testing.B) { os.RemoveAll(dir) }() - app := NewGaiaApp(logger, db, nil, true, simapp.FlagPeriodValue, interBlockCacheOpt()) + gapp := NewGaiaApp(logger, db, nil, true, simapp.FlagPeriodValue, interBlockCacheOpt()) // 2. Run parameterized simulation (w/o invariants) _, simParams, simErr := simulation.SimulateFromSeed( - b, ioutil.Discard, app.BaseApp, simapp.AppStateFn(app.Codec(), app.sm), - testAndRunTxs(app, config), app.ModuleAccountAddrs(), config, + b, ioutil.Discard, gapp.BaseApp, simapp.AppStateFn(gapp.Codec(), gapp.sm), + testAndRunTxs(gapp, config), gapp.ModuleAccountAddrs(), config, ) // export state and params before the simulation error is checked if config.ExportStatePath != "" { - if err := ExportStateToJSON(app, config.ExportStatePath); err != nil { + if err := ExportStateToJSON(gapp, config.ExportStatePath); err != nil { fmt.Println(err) b.Fail() } @@ -651,13 +651,13 @@ func BenchmarkInvariants(b *testing.B) { b.FailNow() } - ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight() + 1}) + ctx := gapp.NewContext(true, abci.Header{Height: gapp.LastBlockHeight() + 1}) // 3. Benchmark each invariant separately // // NOTE: We use the crisis keeper as it has all the invariants registered with // their respective metadata which makes it useful for testing/benchmarking. - for _, cr := range app.crisisKeeper.Routes() { + for _, cr := range gapp.crisisKeeper.Routes() { b.Run(fmt.Sprintf("%s/%s", cr.ModuleName, cr.Route), func(b *testing.B) { if res, stop := cr.Invar(ctx); stop { fmt.Printf("broken invariant at block %d of %d\n%s", ctx.BlockHeight()-1, config.NumBlocks, res) diff --git a/cli_test/cli_test.go b/cli_test/cli_test.go index 971f5881..b4a5aed8 100644 --- a/cli_test/cli_test.go +++ b/cli_test/cli_test.go @@ -25,7 +25,6 @@ import ( "github.com/cosmos/cosmos-sdk/tests" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/genaccounts" "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/mint" ) @@ -1272,12 +1271,12 @@ func TestGaiadAddGenesisAccount(t *testing.T) { genesisState := f.GenesisState() cdc := app.MakeCodec() - accounts := genaccounts.GetGenesisStateFromAppState(cdc, genesisState) + accounts := auth.GetGenesisStateFromAppState(cdc, genesisState).Accounts - require.Equal(t, accounts[0].Address, f.KeyAddress(keyFoo)) - require.Equal(t, accounts[1].Address, f.KeyAddress(keyBar)) - require.True(t, accounts[0].Coins.IsEqual(startCoins)) - require.True(t, accounts[1].Coins.IsEqual(bazCoins)) + require.Equal(t, accounts[0].GetAddress(), f.KeyAddress(keyFoo)) + require.Equal(t, accounts[1].GetAddress(), f.KeyAddress(keyBar)) + require.True(t, accounts[0].GetCoins().IsEqual(startCoins)) + require.True(t, accounts[1].GetCoins().IsEqual(bazCoins)) // Cleanup testing directories f.Cleanup() diff --git a/cmd/gaiad/genaccounts.go b/cmd/gaiad/genaccounts.go new file mode 100644 index 00000000..5c8192de --- /dev/null +++ b/cmd/gaiad/genaccounts.go @@ -0,0 +1,142 @@ +package main + +import ( + "errors" + "fmt" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/tendermint/tendermint/libs/cli" + + "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/server" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" + "github.com/cosmos/cosmos-sdk/x/genutil" +) + +const ( + flagClientHome = "home-client" + flagVestingStart = "vesting-start-time" + flagVestingEnd = "vesting-end-time" + flagVestingAmt = "vesting-amount" +) + +// AddGenesisAccountCmd returns add-genesis-account cobra Command. +func AddGenesisAccountCmd( + ctx *server.Context, cdc *codec.Codec, defaultNodeHome, defaultClientHome string, +) *cobra.Command { + + cmd := &cobra.Command{ + Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]", + Short: "Add a genesis account to genesis.json", + Long: `Add a genesis account to genesis.json. The provided account must specify +the account address or key name and a list of initial coins. If a key name is given, +the address will be looked up in the local Keybase. The list of initial tokens must +contain valid denominations. Accounts may optionally be supplied with vesting parameters. +`, + Args: cobra.ExactArgs(2), + RunE: func(_ *cobra.Command, args []string) error { + config := ctx.Config + config.SetRoot(viper.GetString(cli.HomeFlag)) + + addr, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + // attempt to lookup address from Keybase if no address was provided + kb, err := keys.NewKeyBaseFromDir(viper.GetString(flagClientHome)) + if err != nil { + return err + } + + info, err := kb.Get(args[0]) + if err != nil { + return fmt.Errorf("failed to get address from Keybase: %w", err) + } + + addr = info.GetAddress() + } + + coins, err := sdk.ParseCoins(args[1]) + if err != nil { + return fmt.Errorf("failed to parse coins: %w", err) + } + + vestingStart := viper.GetInt64(flagVestingStart) + vestingEnd := viper.GetInt64(flagVestingEnd) + vestingAmt, err := sdk.ParseCoins(viper.GetString(flagVestingAmt)) + if err != nil { + return fmt.Errorf("failed to parse vesting amount: %w", err) + } + + // create concrete account type based on input parameters + var genAccount authexported.GenesisAccount + + baseAccount := auth.NewBaseAccount(addr, coins.Sort(), nil, 0, 0) + if !vestingAmt.IsZero() { + baseVestingAccount := auth.NewBaseVestingAccount( + baseAccount, vestingAmt.Sort(), sdk.Coins{}, sdk.Coins{}, vestingEnd, + ) + + switch { + case vestingStart != 0 && vestingEnd != 0: + genAccount = auth.NewContinuousVestingAccountRaw(baseVestingAccount, vestingStart) + + case vestingEnd != 0: + genAccount = auth.NewDelayedVestingAccountRaw(baseVestingAccount) + + default: + return errors.New("invalid vesting parameters; must supply start and end time or end time") + } + } else { + genAccount = baseAccount + } + + if err := genAccount.Validate(); err != nil { + return fmt.Errorf("failed to validate new genesis account: %w", err) + } + + genFile := config.GenesisFile() + appState, genDoc, err := genutil.GenesisStateFromGenFile(cdc, genFile) + if err != nil { + return fmt.Errorf("failed to unmarshal genesis state: %w", err) + } + + authGenState := auth.GetGenesisStateFromAppState(cdc, appState) + + if authGenState.Accounts.Contains(addr) { + return fmt.Errorf("cannot add account at existing address %s", addr) + } + + // Add the new account to the set of genesis accounts and sanitize the + // accounts afterwards. + authGenState.Accounts = append(authGenState.Accounts, genAccount) + authGenState.Accounts = auth.SanitizeGenesisAccounts(authGenState.Accounts) + + authGenStateBz, err := cdc.MarshalJSON(authGenState) + if err != nil { + return fmt.Errorf("failed to marshal auth genesis state: %w", err) + } + + appState[auth.ModuleName] = authGenStateBz + + appStateJSON, err := cdc.MarshalJSON(appState) + if err != nil { + return fmt.Errorf("failed to marshal application genesis state: %w", err) + } + + genDoc.AppState = appStateJSON + return genutil.ExportGenesisFile(genDoc, genFile) + }, + } + + cmd.Flags().String(cli.HomeFlag, defaultNodeHome, "node's home directory") + cmd.Flags().String(flagClientHome, defaultClientHome, "client's home directory") + cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts") + cmd.Flags().Uint64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts") + cmd.Flags().Uint64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts") + + return cmd +} diff --git a/cmd/gaiad/main.go b/cmd/gaiad/main.go index bc442fc7..2be4370a 100644 --- a/cmd/gaiad/main.go +++ b/cmd/gaiad/main.go @@ -20,13 +20,11 @@ import ( "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/genaccounts" - genaccscli "github.com/cosmos/cosmos-sdk/x/genaccounts/client/cli" + "github.com/cosmos/cosmos-sdk/x/auth" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" "github.com/cosmos/cosmos-sdk/x/staking" ) -// gaiad custom flags const flagInvCheckPeriod = "inv-check-period" var invCheckPeriod uint @@ -49,14 +47,18 @@ func main() { } rootCmd.AddCommand(genutilcli.InitCmd(ctx, cdc, app.ModuleBasics, app.DefaultNodeHome)) - rootCmd.AddCommand(genutilcli.CollectGenTxsCmd(ctx, cdc, genaccounts.AppModuleBasic{}, app.DefaultNodeHome)) + rootCmd.AddCommand(genutilcli.CollectGenTxsCmd(ctx, cdc, auth.GenesisAccountIterator{}, app.DefaultNodeHome)) rootCmd.AddCommand(genutilcli.MigrateGenesisCmd(ctx, cdc)) - rootCmd.AddCommand(genutilcli.GenTxCmd(ctx, cdc, app.ModuleBasics, staking.AppModuleBasic{}, - genaccounts.AppModuleBasic{}, app.DefaultNodeHome, app.DefaultCLIHome)) + rootCmd.AddCommand( + genutilcli.GenTxCmd( + ctx, cdc, app.ModuleBasics, staking.AppModuleBasic{}, + auth.GenesisAccountIterator{}, app.DefaultNodeHome, app.DefaultCLIHome, + ), + ) rootCmd.AddCommand(genutilcli.ValidateGenesisCmd(ctx, cdc, app.ModuleBasics)) - rootCmd.AddCommand(genaccscli.AddGenesisAccountCmd(ctx, cdc, app.DefaultNodeHome, app.DefaultCLIHome)) + rootCmd.AddCommand(AddGenesisAccountCmd(ctx, cdc, app.DefaultNodeHome, app.DefaultCLIHome)) rootCmd.AddCommand(client.NewCompletionCmd(rootCmd, true)) - rootCmd.AddCommand(testnetCmd(ctx, cdc, app.ModuleBasics, genaccounts.AppModuleBasic{})) + rootCmd.AddCommand(testnetCmd(ctx, cdc, app.ModuleBasics, auth.GenesisAccountIterator{})) rootCmd.AddCommand(replayCmd()) server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators) @@ -93,13 +95,14 @@ func exportAppStateAndTMValidators( ) (json.RawMessage, []tmtypes.GenesisValidator, error) { if height != -1 { - gApp := app.NewGaiaApp(logger, db, traceStore, false, uint(1)) - err := gApp.LoadHeight(height) + gapp := app.NewGaiaApp(logger, db, traceStore, false, uint(1)) + err := gapp.LoadHeight(height) if err != nil { return nil, nil, err } - return gApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) + return gapp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) } - gApp := app.NewGaiaApp(logger, db, traceStore, true, uint(1)) - return gApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) + + gapp := app.NewGaiaApp(logger, db, traceStore, true, uint(1)) + return gapp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) } diff --git a/cmd/gaiad/replay.go b/cmd/gaiad/replay.go index 934f7340..5e161d05 100644 --- a/cmd/gaiad/replay.go +++ b/cmd/gaiad/replay.go @@ -92,7 +92,7 @@ func replayTxs(rootDir string) error { // Application fmt.Fprintln(os.Stderr, "Creating application") - myapp := app.NewGaiaApp( + gapp := app.NewGaiaApp( ctx.Logger, appDB, traceStoreWriter, true, uint(1), baseapp.SetPruning(store.PruneEverything), // nothing ) @@ -109,7 +109,7 @@ func replayTxs(rootDir string) error { } // tmsm.SaveState(tmDB, genState) - cc := proxy.NewLocalClientCreator(myapp) + cc := proxy.NewLocalClientCreator(gapp) proxyApp := proxy.NewAppConns(cc) err = proxyApp.Start() if err != nil { diff --git a/cmd/gaiad/testnet.go b/cmd/gaiad/testnet.go index c7cef604..53a56f07 100644 --- a/cmd/gaiad/testnet.go +++ b/cmd/gaiad/testnet.go @@ -26,7 +26,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/genaccounts" + authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/cosmos/cosmos-sdk/x/staking" @@ -114,8 +114,8 @@ func InitTestnet(cmd *cobra.Command, config *tmconfig.Config, cdc *codec.Codec, gaiaConfig.MinGasPrices = minGasPrices var ( - accs []genaccounts.GenesisAccount - genFiles []string + genAccounts []authexported.GenesisAccount + genFiles []string ) // generate private keys, node IDs, and initial transactions @@ -193,13 +193,11 @@ func InitTestnet(cmd *cobra.Command, config *tmconfig.Config, cdc *codec.Codec, accTokens := sdk.TokensFromConsensusPower(1000) accStakingTokens := sdk.TokensFromConsensusPower(500) - accs = append(accs, genaccounts.GenesisAccount{ - Address: addr, - Coins: sdk.Coins{ - sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), accTokens), - sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens), - }, - }) + coins := sdk.Coins{ + sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), accTokens), + sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens), + } + genAccounts = append(genAccounts, auth.NewBaseAccount(addr, coins.Sort(), nil, 0, 0)) valTokens := sdk.TokensFromConsensusPower(100) msg := staking.NewMsgCreateValidator( @@ -210,10 +208,12 @@ func InitTestnet(cmd *cobra.Command, config *tmconfig.Config, cdc *codec.Codec, staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), sdk.OneInt(), ) + kb, err := keys.NewKeyBaseFromDir(clientDir) if err != nil { return err } + tx := auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, []auth.StdSignature{}, memo) txBldr := auth.NewTxBuilderFromCLI().WithChainID(chainID).WithMemo(memo).WithKeybase(kb) @@ -241,7 +241,7 @@ func InitTestnet(cmd *cobra.Command, config *tmconfig.Config, cdc *codec.Codec, srvconfig.WriteConfigFile(gaiaConfigFilePath, gaiaConfig) } - if err := initGenFiles(cdc, mbm, chainID, accs, genFiles, numValidators); err != nil { + if err := initGenFiles(cdc, mbm, chainID, genAccounts, genFiles, numValidators); err != nil { return err } @@ -257,13 +257,19 @@ func InitTestnet(cmd *cobra.Command, config *tmconfig.Config, cdc *codec.Codec, return nil } -func initGenFiles(cdc *codec.Codec, mbm module.BasicManager, chainID string, - accs []genaccounts.GenesisAccount, genFiles []string, numValidators int) error { +func initGenFiles( + cdc *codec.Codec, mbm module.BasicManager, chainID string, + genAccounts []authexported.GenesisAccount, genFiles []string, numValidators int, +) error { appGenState := mbm.DefaultGenesis() // set the accounts in the genesis state - appGenState = genaccounts.SetGenesisStateInAppState(cdc, appGenState, accs) + authDataBz := appGenState[auth.ModuleName] + var authGenState auth.GenesisState + cdc.MustUnmarshalJSON(authDataBz, &authGenState) + authGenState.Accounts = genAccounts + appGenState[auth.ModuleName] = cdc.MustMarshalJSON(authGenState) appGenStateJSON, err := codec.MarshalJSONIndent(cdc, appGenState) if err != nil { diff --git a/docs/genesis-state.md b/docs/genesis-state.md index fdd26283..f73d8583 100644 --- a/docs/genesis-state.md +++ b/docs/genesis-state.md @@ -9,7 +9,6 @@ The Gaia genesis state is defined as follows: ```go type GenesisState struct { - Accounts []GenesisAccount `json:"accounts"` AuthData auth.GenesisState `json:"auth"` BankData bank.GenesisState `json:"bank"` StakingData staking.GenesisState `json:"staking"` @@ -27,23 +26,10 @@ which internally calls each module's `InitGenesis` providing its own respective ## Accounts -Genesis accounts defined in the `GenesisState` are defined as follows: - -```go -type GenesisAccount struct { - Address sdk.AccAddress `json:"address"` - Coins sdk.Coins `json:"coins"` - Sequence uint64 `json:"sequence_number"` - AccountNumber uint64 `json:"account_number"` - - // vesting account fields - OriginalVesting sdk.Coins `json:"original_vesting"` // total vesting coins upon initialization - DelegatedFree sdk.Coins `json:"delegated_free"` // delegated vested coins at time of delegation - DelegatedVesting sdk.Coins `json:"delegated_vesting"` // delegated vesting coins at time of delegation - StartTime int64 `json:"start_time"` // vesting start time (UNIX Epoch time) - EndTime int64 `json:"end_time"` // vesting end time (UNIX Epoch time) -} -``` +Genesis accounts are defined in the `GenesisState` of the `x/auth` module and +exist under the `accounts` key. There is no single concrete implementation of a +genesis account but they all implement the `GenesisAccount` interface defined by +`x/auth`. Each account must have a valid and unique account number in addition to a sequence number (nonce) and address. diff --git a/docs/translations/cn/genesis-state.md b/docs/translations/cn/genesis-state.md index 168d434e..07831e1b 100644 --- a/docs/translations/cn/genesis-state.md +++ b/docs/translations/cn/genesis-state.md @@ -2,22 +2,6 @@ Gaia 创世状态`GenesisState`由账户、各种模块状态和元数据组成,例如创世交易。 每个模块可以指定自己的`GenesisState`。 此外,每个模块可以指定自己的创世状态有效性验证、导入和导出功能。 -Gaia 创世状态定义如下: - -```go -type GenesisState struct { - Accounts []GenesisAccount `json:"accounts"` - AuthData auth.GenesisState `json:"auth"` - BankData bank.GenesisState `json:"bank"` - StakingData staking.GenesisState `json:"staking"` - MintData mint.GenesisState `json:"mint"` - DistrData distr.GenesisState `json:"distribution"` - GovData gov.GenesisState `json:"gov"` - SlashingData slashing.GenesisState `json:"slashing"` - GenTxs []json.RawMessage `json:"gentxs"` -} -``` - 在 Gaia 的 ABCI`initChainer`定义中调用`initFromGenesisState`,它在内部调用每个模块的`InitGenesis`,提供它自己的`GenesisState`作为参数。 ## 账户(Accounts) diff --git a/docs/translations/kr/genesis.md b/docs/translations/kr/genesis.md index 7dd9384f..6fa981a8 100644 --- a/docs/translations/kr/genesis.md +++ b/docs/translations/kr/genesis.md @@ -2,22 +2,6 @@ Gaia의 제네시스 스테이트인 `GenesisState`는 계정 정보, 모듈 스테이트 그리고 제네시스 트랜잭션 같은 메타데이터 등으로 구성됩니다. 각 모듈은 각자의 `GenesisState`를 지정할 수 있습니다. 또한, 각 모듈은 각자의 제네시스 스테이트 검증, 임포트, 엑스포트 기능 등을 지정할 수 있습니다. -Gaia 제네시스 스테이트는 다음과 같이 정의됩니다: - -```go -type GenesisState struct { - Accounts []GenesisAccount `json:"accounts"` - AuthData auth.GenesisState `json:"auth"` - BankData bank.GenesisState `json:"bank"` - StakingData staking.GenesisState `json:"staking"` - MintData mint.GenesisState `json:"mint"` - DistrData distr.GenesisState `json:"distr"` - GovData gov.GenesisState `json:"gov"` - SlashingData slashing.GenesisState `json:"slashing"` - GenTxs []json.RawMessage `json:"gentxs"` -} -``` - ABCI `initChainer`에서는 Gaia의 `initFromGenesisState`를 기반으로 각 모듈의 `InitGenesis`를 호출해 각 모듈들의 `GenesisState`를 파라미터 값으로 불러옵니다. ## 계정 diff --git a/go.mod b/go.mod index 7734d017..b0befef6 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.13 require ( github.com/btcsuite/btcd v0.0.0-20190807005414-4063feeff79a // indirect - github.com/cosmos/cosmos-sdk v0.34.4-0.20190910181238-84627faf79eb + github.com/cosmos/cosmos-sdk v0.34.4-0.20190913222629-1028283e6fc1 github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d // indirect github.com/go-kit/kit v0.9.0 // indirect github.com/golang/mock v1.3.1 // indirect diff --git a/go.sum b/go.sum index ed5a869f..92855c6e 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,8 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cosmos/cosmos-sdk v0.34.4-0.20190910181238-84627faf79eb h1:VKEfR1unkvgquOUgGcuXq6gPXDd7L125MSuCSEmthNM= -github.com/cosmos/cosmos-sdk v0.34.4-0.20190910181238-84627faf79eb/go.mod h1:De67lt7tcfjIhSv58L/96UEdMvR3GZhOtvHntfEglDA= +github.com/cosmos/cosmos-sdk v0.34.4-0.20190913222629-1028283e6fc1 h1:nvpz1FYhr4GPneKZrrIyZ5leN1p+fVeGeMp+kvku79Q= +github.com/cosmos/cosmos-sdk v0.34.4-0.20190913222629-1028283e6fc1/go.mod h1:WFgmzqlpCWWhon5UF59Nu3olrxCUB3+S/GzTeUyfs1U= github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= @@ -74,6 +74,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -100,6 +101,7 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -168,6 +170,7 @@ github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZ github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.2.4 h1:DxYL0itZyPaR5Z9HILdxSoHx+gNs6Yx+neOGS3IVUk0= github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= @@ -303,6 +306,7 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -319,6 +323,7 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= diff --git a/lcd_test/helpers.go b/lcd_test/helpers.go index dd6acccd..28ed3a24 100644 --- a/lcd_test/helpers.go +++ b/lcd_test/helpers.go @@ -10,27 +10,27 @@ import ( "sort" "strings" + "github.com/pkg/errors" + "github.com/spf13/viper" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/lcd" "github.com/cosmos/cosmos-sdk/codec" crkeys "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/store" "github.com/cosmos/cosmos-sdk/tests" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" + authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/cosmos/cosmos-sdk/x/crisis" distr "github.com/cosmos/cosmos-sdk/x/distribution" - "github.com/cosmos/cosmos-sdk/x/genaccounts" "github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/supply" - "github.com/pkg/errors" - "github.com/spf13/viper" tmcfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" @@ -47,7 +47,7 @@ import ( tmtypes "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tm-db" - gapp "github.com/cosmos/gaia/app" + "github.com/cosmos/gaia/app" ) // TODO: Make InitializeTestLCD safe to call in multiple tests at the same time @@ -70,8 +70,8 @@ func InitializeLCD(nValidators int, initAddrs []sdk.AccAddress, minting bool, po logger = log.NewFilter(logger, log.AllowError()) db := dbm.NewMemDB() - app := gapp.NewGaiaApp(logger, db, nil, true, 0, baseapp.SetPruning(store.PruneNothing)) - cdc = gapp.MakeCodec() + gapp := app.NewGaiaApp(logger, db, nil, true, 0, baseapp.SetPruning(store.PruneNothing)) + cdc = app.MakeCodec() genDoc, valConsPubKeys, valOperAddrs, privVal, err := defaultGenesis(config, nValidators, initAddrs, minting) if err != nil { @@ -96,7 +96,7 @@ func InitializeLCD(nValidators int, initAddrs []sdk.AccAddress, minting bool, po // TODO Set to false once the upstream Tendermint proof verification issue is fixed. viper.Set(client.FlagTrustNode, true) - node, err := startTM(config, logger, genDoc, privVal, app) + node, err := startTM(config, logger, genDoc, privVal, gapp) if err != nil { return } @@ -151,7 +151,7 @@ func defaultGenesis(config *tmcfg.Config, nValidators int, initAddrs []sdk.AccAd // append any additional (non-proposing) validators var genTxs []auth.StdTx - var accs []genaccounts.GenesisAccount + var genAccounts []authexported.GenesisAccount totalSupply := sdk.ZeroInt() @@ -165,6 +165,7 @@ func defaultGenesis(config *tmcfg.Config, nValidators int, initAddrs []sdk.AccAd pubKey = ed25519.GenPrivKey().PubKey() power = 1 } + startTokens := sdk.TokensFromConsensusPower(power) msg := staking.NewMsgCreateValidator( @@ -175,29 +176,32 @@ func defaultGenesis(config *tmcfg.Config, nValidators int, initAddrs []sdk.AccAd staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), sdk.OneInt(), ) + stdSignMsg := auth.StdSignMsg{ ChainID: genDoc.ChainID, Msgs: []sdk.Msg{msg}, } + var sig []byte sig, err = operPrivKey.Sign(stdSignMsg.Bytes()) if err != nil { return } + transaction := auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, []auth.StdSignature{{Signature: sig, PubKey: operPrivKey.PubKey()}}, "") genTxs = append(genTxs, transaction) valConsPubKeys = append(valConsPubKeys, pubKey) valOperAddrs = append(valOperAddrs, sdk.ValAddress(operAddr)) - accAuth := auth.NewBaseAccountWithAddress(sdk.AccAddress(operAddr)) + account := auth.NewBaseAccountWithAddress(sdk.AccAddress(operAddr)) accTokens := sdk.TokensFromConsensusPower(150) totalSupply = totalSupply.Add(accTokens) - accAuth.Coins = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, accTokens)) - accs = append(accs, genaccounts.NewGenesisAccount(&accAuth)) + account.Coins = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, accTokens)) + genAccounts = append(genAccounts, &account) } - genesisState := simapp.NewDefaultGenesisState() + genesisState := app.NewDefaultGenesisState() genDoc.AppState, err = cdc.MarshalJSON(genesisState) if err != nil { return @@ -208,21 +212,28 @@ func defaultGenesis(config *tmcfg.Config, nValidators int, initAddrs []sdk.AccAd return } - // add some tokens to init accounts - stakingDataBz := genesisState[staking.ModuleName] - var stakingData staking.GenesisState - cdc.MustUnmarshalJSON(stakingDataBz, &stakingData) - // add some tokens to init accounts for _, addr := range initAddrs { accAuth := auth.NewBaseAccountWithAddress(addr) accTokens := sdk.TokensFromConsensusPower(100) accAuth.Coins = sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, accTokens)} totalSupply = totalSupply.Add(accTokens) - acc := genaccounts.NewGenesisAccount(&accAuth) - accs = append(accs, acc) + + genAccounts = append(genAccounts, &accAuth) } + // auth genesis state: params and genesis accounts + authDataBz := genesisState[auth.ModuleName] + var authGenState auth.GenesisState + cdc.MustUnmarshalJSON(authDataBz, &authGenState) + authGenState.Accounts = genAccounts + genesisState[auth.ModuleName] = cdc.MustMarshalJSON(authGenState) + + stakingDataBz := genesisState[staking.ModuleName] + var stakingData staking.GenesisState + cdc.MustUnmarshalJSON(stakingDataBz, &stakingData) + genesisState[staking.ModuleName] = cdc.MustMarshalJSON(stakingData) + // distr data distrDataBz := genesisState[distr.ModuleName] var distrData distr.GenesisState @@ -233,10 +244,6 @@ func defaultGenesis(config *tmcfg.Config, nValidators int, initAddrs []sdk.AccAd distrDataBz = cdc.MustMarshalJSON(distrData) genesisState[distr.ModuleName] = distrDataBz - // staking and genesis accounts - genesisState[staking.ModuleName] = cdc.MustMarshalJSON(stakingData) - genesisState[genaccounts.ModuleName] = cdc.MustMarshalJSON(accs) - // supply data supplyDataBz := genesisState[supply.ModuleName] var supplyData supply.GenesisState @@ -289,6 +296,7 @@ func defaultGenesis(config *tmcfg.Config, nValidators int, initAddrs []sdk.AccAd if err != nil { return } + genDoc.AppState = appState return } @@ -300,7 +308,7 @@ func defaultGenesis(config *tmcfg.Config, nValidators int, initAddrs []sdk.AccAd // TODO: Clean up the WAL dir or enable it to be not persistent! func startTM( tmcfg *tmcfg.Config, logger log.Logger, genDoc *tmtypes.GenesisDoc, - privVal tmtypes.PrivValidator, app *gapp.GaiaApp, + privVal tmtypes.PrivValidator, app *app.GaiaApp, ) (*nm.Node, error) { genDocProvider := func() (*tmtypes.GenesisDoc, error) { return genDoc, nil } @@ -350,7 +358,7 @@ func startLCD(logger log.Logger, listenAddr string, cdc *codec.Codec) (net.Liste func registerRoutes(rs *lcd.RestServer) { client.RegisterRoutes(rs.CliCtx, rs.Mux) authrest.RegisterTxRoutes(rs.CliCtx, rs.Mux) - gapp.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux) + app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux) } var cdc = codec.New()