Merge PR #122: Genesis Account Command + Types

This commit is contained in:
Federico Kunze
2019-09-15 03:19:46 +03:00
committed by Alexander Bezobchuk
parent f35c63d672
commit 6970ebe19b
15 changed files with 269 additions and 145 deletions

View File

@@ -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),

View File

@@ -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)))
}
}

11
app/genesis.go Normal file
View File

@@ -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()
}

View File

@@ -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)

View File

@@ -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()

142
cmd/gaiad/genaccounts.go Normal file
View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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.

View File

@@ -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

View File

@@ -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`를 파라미터 값으로 불러옵니다.
## 계정

2
go.mod
View File

@@ -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

9
go.sum
View File

@@ -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=

View File

@@ -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()