From ff66629b68ac5fd2592dbd351670c14afedf3156 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 23 Apr 2018 14:51:35 +0200 Subject: [PATCH 01/22] Example WriteGenesis implementation --- examples/democoin/x/pow/keeper.go | 18 +++++++++++++++++- examples/democoin/x/pow/keeper_test.go | 4 ++++ types/initgenesis.go | 10 ---------- 3 files changed, 21 insertions(+), 11 deletions(-) delete mode 100644 types/initgenesis.go diff --git a/examples/democoin/x/pow/keeper.go b/examples/democoin/x/pow/keeper.go index 9a5edf0b5c..4d95840b7b 100644 --- a/examples/democoin/x/pow/keeper.go +++ b/examples/democoin/x/pow/keeper.go @@ -36,13 +36,29 @@ func NewKeeper(key sdk.StoreKey, config Config, ck bank.Keeper, codespace sdk.Co return Keeper{key, config, ck, codespace} } -// Init Genessis for the POW module +// InitGenesis for the POW module func (k Keeper) InitGenesis(ctx sdk.Context, genesis Genesis) error { k.SetLastDifficulty(ctx, genesis.Difficulty) k.SetLastCount(ctx, genesis.Count) return nil } +// WriteGenesis for the PoW module +func (k Keeper) WriteGenesis(ctx sdk.Context) Genesis { + difficulty, err := k.GetLastDifficulty(ctx) + if err != nil { + panic(err) + } + count, err := k.GetLastCount(ctx) + if err != nil { + panic(err) + } + return Genesis{ + difficulty, + count, + } +} + var lastDifficultyKey = []byte("lastDifficultyKey") // get the last mining difficulty diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index 4c01559f6c..015f98556d 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -40,6 +40,10 @@ func TestPowKeeperGetSet(t *testing.T) { err := keeper.InitGenesis(ctx, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) + genesis := keeper.WriteGenesis(ctx) + assert.Nil(t, err) + assert.Equal(t, genesis, Genesis{uint64(1), uint64(0)}) + res, err := keeper.GetLastDifficulty(ctx) assert.Nil(t, err) assert.Equal(t, res, uint64(1)) diff --git a/types/initgenesis.go b/types/initgenesis.go deleted file mode 100644 index ff3c03cf4d..0000000000 --- a/types/initgenesis.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -import ( - "encoding/json" -) - -// Run only once on chain initialization, should write genesis state to store -// or throw an error if some required information was not provided, in which case -// the application will panic. -type InitGenesis func(ctx Context, data json.RawMessage) error From f71191e402a2045a65b7166e72545178016ba766 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 24 Apr 2018 12:49:37 +0200 Subject: [PATCH 02/22] Add simple WriteGenesis for stake & cool modules --- cmd/gaia/app/app.go | 2 +- examples/democoin/x/cool/keeper.go | 6 ++++++ x/stake/handler.go | 9 ++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 690dafe538..46e8e3a2fa 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -113,7 +113,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // load the initial stake information - stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) + app.stakeKeeper.InitGenesis(ctx, genesisState.StakeData) return abci.ResponseInitChain{} } diff --git a/examples/democoin/x/cool/keeper.go b/examples/democoin/x/cool/keeper.go index b180cd23c4..6a1f8da6d2 100644 --- a/examples/democoin/x/cool/keeper.go +++ b/examples/democoin/x/cool/keeper.go @@ -48,3 +48,9 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data Genesis) error { k.setTrend(ctx, data.Trend) return nil } + +// WriteGenesis - output the genesis trend +func (k Keeper) WriteGenesis(ctx sdk.Context) Genesis { + trend := k.GetTrend(ctx) + return Genesis{trend} +} diff --git a/x/stake/handler.go b/x/stake/handler.go index e397203857..a04bdf862b 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -49,7 +49,7 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { //_____________________________________________________________________ // InitGenesis - store genesis parameters -func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { +func (k Keeper) InitGenesis(ctx sdk.Context, data GenesisState) { k.setPool(ctx, data.Pool) k.setParams(ctx, data.Params) for _, candidate := range data.Candidates { @@ -57,6 +57,13 @@ func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { } } +// WriteGenesis - output genesis parameters +func (k Keeper) WriteGenesis(ctx sdk.Context) GenesisState { + pool := k.GetPool(ctx) + params := k.GetParams(ctx) + return GenesisState{pool, params} +} + //_____________________________________________________________________ // These functions assume everything has been authenticated, From 0436d890c7dd9d273f6fa49226e7461e259bf714 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 24 Apr 2018 15:05:19 +0200 Subject: [PATCH 03/22] Add candidates & bonds to stake module genesis --- x/stake/handler.go | 12 +++++++++++- x/stake/keeper.go | 28 ++++++++++++++++++++++++++-- x/stake/types.go | 7 ++++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/x/stake/handler.go b/x/stake/handler.go index a04bdf862b..d7b7ef86ed 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -55,13 +55,23 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data GenesisState) { for _, candidate := range data.Candidates { k.setCandidate(ctx, candidate) } + for _, bond := range data.Bonds { + k.setDelegatorBond(ctx, bond) + } } // WriteGenesis - output genesis parameters func (k Keeper) WriteGenesis(ctx sdk.Context) GenesisState { pool := k.GetPool(ctx) params := k.GetParams(ctx) - return GenesisState{pool, params} + candidates := k.GetCandidates(ctx, -1) + bonds := k.GetBonds(ctx, -1) + return GenesisState{ + pool, + params, + candidates, + bonds, + } } //_____________________________________________________________________ diff --git a/x/stake/keeper.go b/x/stake/keeper.go index f1b4363140..d30d7b46e3 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -74,7 +74,7 @@ func (k Keeper) GetCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candi return candidate, true } -// Get the set of all candidates, retrieve a maxRetrieve number of records +// Get the set of all candidates, retrieve a maxRetrieve number of records, -1 maxRetrieve = no limit func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Candidates) { store := ctx.KVStore(k.storeKey) iterator := store.Iterator(subspace(CandidatesKey)) @@ -82,7 +82,7 @@ func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Ca candidates = make([]Candidate, maxRetrieve) i := 0 for ; ; i++ { - if !iterator.Valid() || i > int(maxRetrieve-1) { + if !iterator.Valid() || (maxRetrieve >= 0 && i > int(maxRetrieve-1)) { iterator.Close() break } @@ -371,6 +371,30 @@ func (k Keeper) GetDelegatorBond(ctx sdk.Context, return bond, true } +// load all bonds, -1 maxRetrieve = no limit +func (k Keeper) GetBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorBond) { + store := ctx.KVStore(k.storeKey) + iterator := store.Iterator(subspace(DelegatorBondKeyPrefix)) + + bonds = make([]DelegatorBond, maxRetrieve) + i := 0 + for ; ; i++ { + if !iterator.Valid() || (maxRetrieve >= 0 && i > int(maxRetrieve-1)) { + iterator.Close() + break + } + bondBytes := iterator.Value() + var bond DelegatorBond + err := k.cdc.UnmarshalBinary(bondBytes, &bond) + if err != nil { + panic(err) + } + bonds[i] = bond + iterator.Next() + } + return bonds[:i] // trim +} + // load all bonds of a delegator func (k Keeper) GetDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRetrieve int16) (bonds []DelegatorBond) { store := ctx.KVStore(k.storeKey) diff --git a/x/stake/types.go b/x/stake/types.go index 634b51186b..6e15acd96d 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -9,9 +9,10 @@ import ( // GenesisState - all staking state that must be provided at genesis type GenesisState struct { - Pool Pool `json:"pool"` - Params Params `json:"params"` - Candidates []Candidate `json:"candidates"` + Pool Pool `json:"pool"` + Params Params `json:"params"` + Candidates []Candidate `json:"candidates"` + Bonds []DelegatorBond `json:"bonds"` } //_________________________________________________________________________ From 203d2c19ccf95a48ffa0dd939bfed7b1d6fae756 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 24 Apr 2018 15:26:28 +0200 Subject: [PATCH 04/22] Add export command to stake module --- x/stake/commands/export.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 x/stake/commands/export.go diff --git a/x/stake/commands/export.go b/x/stake/commands/export.go new file mode 100644 index 0000000000..f3d1516d53 --- /dev/null +++ b/x/stake/commands/export.go @@ -0,0 +1,30 @@ +package commands + +import ( + "fmt" + + "github.com/spf13/cobra" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" // XXX fix + "github.com/cosmos/cosmos-sdk/x/stake" +) + +// get the command to export state +func GetCmdExport(load func() (stake.Keeper, sdk.Context), cdc *wire.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "export", + Short: "Export stake module state as JSON to stdout", + RunE: func(cmd *cobra.Command, args []string) error { + keeper, ctx := load() + genesis := keeper.WriteGenesis(ctx) + output, err := wire.MarshalJSONIndent(cdc, genesis) + if err != nil { + return err + } + fmt.Println(string(output)) + return nil + }, + } + return cmd +} From 55c82e44a2c3ab5623a2826e26dacd51b9713115 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 24 Apr 2018 15:46:39 +0200 Subject: [PATCH 05/22] export-stake command works --- cmd/gaia/app/app.go | 5 +++++ cmd/gaia/cmd/gaiad/main.go | 2 ++ x/stake/commands/export.go | 11 ++++++----- x/stake/handler.go | 4 ++-- x/stake/keeper.go | 8 ++++---- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 46e8e3a2fa..9c7eb51809 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -117,3 +117,8 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci return abci.ResponseInitChain{} } + +// custom logic for export +func (app *GaiaApp) ExportStake() stake.GenesisState { + return app.stakeKeeper.WriteGenesis(app.NewContext(true, abci.Header{})) +} diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 0417671a2f..ca9b72cdf2 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -12,6 +12,8 @@ import ( "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" + stake "github.com/cosmos/cosmos-sdk/x/stake" + stakecmd "github.com/cosmos/cosmos-sdk/x/stake/commands" ) func main() { diff --git a/x/stake/commands/export.go b/x/stake/commands/export.go index f3d1516d53..679aa5d1a7 100644 --- a/x/stake/commands/export.go +++ b/x/stake/commands/export.go @@ -5,19 +5,20 @@ import ( "github.com/spf13/cobra" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" // XXX fix "github.com/cosmos/cosmos-sdk/x/stake" ) // get the command to export state -func GetCmdExport(load func() (stake.Keeper, sdk.Context), cdc *wire.Codec) *cobra.Command { +func GetCmdExport(export func() (stake.GenesisState, error), cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "export", + Use: "export-stake", Short: "Export stake module state as JSON to stdout", RunE: func(cmd *cobra.Command, args []string) error { - keeper, ctx := load() - genesis := keeper.WriteGenesis(ctx) + genesis, err := export() + if err != nil { + return err + } output, err := wire.MarshalJSONIndent(cdc, genesis) if err != nil { return err diff --git a/x/stake/handler.go b/x/stake/handler.go index d7b7ef86ed..36e1110d80 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -64,8 +64,8 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data GenesisState) { func (k Keeper) WriteGenesis(ctx sdk.Context) GenesisState { pool := k.GetPool(ctx) params := k.GetParams(ctx) - candidates := k.GetCandidates(ctx, -1) - bonds := k.GetBonds(ctx, -1) + candidates := k.GetCandidates(ctx, 32767) + bonds := k.GetBonds(ctx, 32767) return GenesisState{ pool, params, diff --git a/x/stake/keeper.go b/x/stake/keeper.go index d30d7b46e3..6bb3f054f7 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -74,7 +74,7 @@ func (k Keeper) GetCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candi return candidate, true } -// Get the set of all candidates, retrieve a maxRetrieve number of records, -1 maxRetrieve = no limit +// Get the set of all candidates, retrieve a maxRetrieve number of records func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Candidates) { store := ctx.KVStore(k.storeKey) iterator := store.Iterator(subspace(CandidatesKey)) @@ -82,7 +82,7 @@ func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Ca candidates = make([]Candidate, maxRetrieve) i := 0 for ; ; i++ { - if !iterator.Valid() || (maxRetrieve >= 0 && i > int(maxRetrieve-1)) { + if !iterator.Valid() || i > int(maxRetrieve-1) { iterator.Close() break } @@ -371,7 +371,7 @@ func (k Keeper) GetDelegatorBond(ctx sdk.Context, return bond, true } -// load all bonds, -1 maxRetrieve = no limit +// load all bonds func (k Keeper) GetBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorBond) { store := ctx.KVStore(k.storeKey) iterator := store.Iterator(subspace(DelegatorBondKeyPrefix)) @@ -379,7 +379,7 @@ func (k Keeper) GetBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorB bonds = make([]DelegatorBond, maxRetrieve) i := 0 for ; ; i++ { - if !iterator.Valid() || (maxRetrieve >= 0 && i > int(maxRetrieve-1)) { + if !iterator.Valid() || i > int(maxRetrieve-1) { iterator.Close() break } From f92e83d2e07c85495978e5720a6b72f73639e3f0 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 17:53:07 +0200 Subject: [PATCH 06/22] Swap to general `export` command --- cmd/gaia/app/app.go | 7 ++-- cmd/gaia/cmd/gaiad/main.go | 17 +++++++-- examples/basecoin/app/app.go | 5 +++ examples/basecoin/cmd/basecoind/main.go | 13 ++++++- examples/democoin/app/app.go | 19 ++++++++-- examples/democoin/cmd/democoind/main.go | 18 +++++++++- server/export.go | 48 +++++++++++++++++++++++++ server/util.go | 5 ++- x/stake/commands/export.go | 31 ---------------- 9 files changed, 122 insertions(+), 41 deletions(-) create mode 100644 server/export.go delete mode 100644 x/stake/commands/export.go diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 9c7eb51809..fe47826896 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -119,6 +119,9 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // custom logic for export -func (app *GaiaApp) ExportStake() stake.GenesisState { - return app.stakeKeeper.WriteGenesis(app.NewContext(true, abci.Header{})) +func (app *GaiaApp) ExportGenesis() GenesisState { + return GenesisState{ + Accounts: []GenesisAccount{}, + StakeData: app.stakeKeeper.WriteGenesis(app.NewContext(true, abci.Header{})), + } } diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index ca9b72cdf2..36b7099523 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -12,8 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" - stake "github.com/cosmos/cosmos-sdk/x/stake" - stakecmd "github.com/cosmos/cosmos-sdk/x/stake/commands" + "github.com/cosmos/cosmos-sdk/wire" ) func main() { @@ -26,6 +25,7 @@ func main() { } server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp) + server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp, exportApp) // prepare and add flags executor := cli.PrepareBaseCmd(rootCmd, "GA", app.DefaultNodeHome) @@ -41,3 +41,16 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { bapp := app.NewGaiaApp(logger, db) return bapp, nil } + +func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB("gaia", dataDir) + if err != nil { + return nil, nil, err + } + bapp := app.NewGaiaApp(log.NewNopLogger(), db) + if err != nil { + return nil, nil, err + } + return bapp.ExportGenesis(), app.MakeCodec(), nil +} diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index a1ec9a38bf..c85ff44413 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -119,3 +119,8 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) } return abci.ResponseInitChain{} } + +// Custom logic for state export +func (app *BasecoinApp) ExportGenesis() types.GenesisState { + return types.GenesisState{} +} diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 8d14821c6a..5a165735ef 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/wire" ) func main() { @@ -25,7 +26,7 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, generateApp) + server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, generateApp, exportApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.basecoind") @@ -42,3 +43,13 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { bapp := app.NewBasecoinApp(logger, db) return bapp, nil } + +func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB("basecoin", dataDir) + if err != nil { + return nil, nil, err + } + bapp := app.NewBasecoinApp(logger, db) + return bapp.ExportGenesis(), nil, nil +} diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index aabd4c41c5..516e3b6755 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -36,6 +36,9 @@ type DemocoinApp struct { capKeyIBCStore *sdk.KVStoreKey capKeyStakingStore *sdk.KVStoreKey + // keepers + powKeeper pow.Keeper + // Manage getting and setting accounts accountMapper sdk.AccountMapper } @@ -66,19 +69,19 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { // Add handlers. coinKeeper := bank.NewKeeper(app.accountMapper) coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper, app.RegisterCodespace(cool.DefaultCodespace)) - powKeeper := pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) + app.powKeeper = pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) ibcMapper := ibc.NewMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper)). AddRoute("cool", cool.NewHandler(coolKeeper)). - AddRoute("pow", powKeeper.Handler). + AddRoute("pow", app.powKeeper.Handler). AddRoute("sketchy", sketchy.NewHandler()). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("simplestake", simplestake.NewHandler(stakeKeeper)) // Initialize BaseApp. - app.SetInitChainer(app.initChainerFn(coolKeeper, powKeeper)) + app.SetInitChainer(app.initChainerFn(coolKeeper, app.powKeeper)) app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyPowStore, app.capKeyIBCStore, app.capKeyStakingStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, auth.BurnFeeHandler)) err := app.LoadLatestVersion(app.capKeyMainStore) @@ -142,3 +145,13 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep return abci.ResponseInitChain{} } } + +// Custom logic for state export +func (app *DemocoinApp) ExportGenesis() types.GenesisState { + ctx := app.NewContext(true, abci.Header{}) + return types.GenesisState{ + Accounts: []*types.GenesisAccount{}, + POWGenesis: app.powKeeper.WriteGenesis(ctx), + CoolGenesis: cool.Genesis{}, + } +} diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index afca80bce3..738420e8de 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -32,6 +32,12 @@ func CoolAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso key := "cool" value := json.RawMessage(`{ "trend": "ice-cold" + }`) + appState, err = server.AppendJSON(cdc, appState, key, value) + key = "pow" + value = json.RawMessage(`{ + "difficulty": 1, + "count": 0 }`) appState, err = server.AppendJSON(cdc, appState, key, value) return @@ -46,6 +52,16 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { return bapp, nil } +func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB("democoin", dataDir) + if err != nil { + return nil, nil, err + } + bapp := app.NewDemocoinApp(logger, db) + return bapp.ExportGenesis(), nil, nil +} + func main() { cdc := app.MakeCodec() ctx := server.NewDefaultContext() @@ -56,7 +72,7 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, generateApp) + server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, generateApp, exportApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.democoind") diff --git a/server/export.go b/server/export.go new file mode 100644 index 0000000000..9430eeb48a --- /dev/null +++ b/server/export.go @@ -0,0 +1,48 @@ +package server + +import ( + "fmt" + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/tendermint/tmlibs/log" + + "github.com/cosmos/cosmos-sdk/wire" +) + +// AppExporter dumps all app state to JSON-serializable structure +type AppExporter func(home string, log log.Logger) (interface{}, *wire.Codec, error) + +// ExportCmd dumps app state to JSON +func ExportCmd(app AppExporter, ctx *Context) *cobra.Command { + export := exportCmd{ + appExporter: app, + context: ctx, + } + cmd := &cobra.Command{ + Use: "export", + Short: "Export state to JSON", + RunE: export.run, + } + return cmd +} + +type exportCmd struct { + appExporter AppExporter + context *Context +} + +func (e exportCmd) run(cmd *cobra.Command, args []string) error { + home := viper.GetString("home") + genesis, cdc, err := e.appExporter(home, e.context.Logger) + if err != nil { + return errors.Errorf("Error exporting state: %v\n", err) + } + output, err := wire.MarshalJSONIndent(cdc, genesis) + if err != nil { + return errors.Errorf("Error marshalling state: %v\n", err) + } + fmt.Println(string(output)) + return nil +} diff --git a/server/util.go b/server/util.go index ed91f30489..6e7c56af0d 100644 --- a/server/util.go +++ b/server/util.go @@ -68,7 +68,8 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error func AddCommands( ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, appInit AppInit, - appCreator AppCreator) { + appCreator AppCreator, appExporter AppExporter, + context *Context) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") @@ -78,6 +79,8 @@ func AddCommands( UnsafeResetAllCmd(ctx), ShowNodeIDCmd(ctx), ShowValidatorCmd(ctx), + ExportCmd(appExporter, context), + UnsafeResetAllCmd(context), version.VersionCmd, ) } diff --git a/x/stake/commands/export.go b/x/stake/commands/export.go deleted file mode 100644 index 679aa5d1a7..0000000000 --- a/x/stake/commands/export.go +++ /dev/null @@ -1,31 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/wire" // XXX fix - "github.com/cosmos/cosmos-sdk/x/stake" -) - -// get the command to export state -func GetCmdExport(export func() (stake.GenesisState, error), cdc *wire.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "export-stake", - Short: "Export stake module state as JSON to stdout", - RunE: func(cmd *cobra.Command, args []string) error { - genesis, err := export() - if err != nil { - return err - } - output, err := wire.MarshalJSONIndent(cdc, genesis) - if err != nil { - return err - } - fmt.Println(string(output)) - return nil - }, - } - return cmd -} From 724c1eced5869300d265c0cec9b5eeb114844e60 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 18:07:13 +0200 Subject: [PATCH 07/22] Minor cleanup --- examples/basecoin/app/app.go | 10 +++++++++- examples/democoin/app/app.go | 28 ++++++++++++++++------------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index c85ff44413..529bb99d79 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" + "github.com/cosmos/cosmos-sdk/examples/democoin/x/simplestake" ) const ( @@ -32,6 +33,11 @@ type BasecoinApp struct { keyIBC *sdk.KVStoreKey keyStake *sdk.KVStoreKey + // keepers + coinKeeper bank.Keeper + ibcMapper ibc.Mapper + stakeKeeper simplestake.Keeper + // Manage getting and setting accounts accountMapper sdk.AccountMapper coinKeeper bank.Keeper @@ -122,5 +128,7 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) // Custom logic for state export func (app *BasecoinApp) ExportGenesis() types.GenesisState { - return types.GenesisState{} + return types.GenesisState{ + Accounts: []*types.GenesisAccount{}, + } } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 516e3b6755..c0b8dd0922 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -37,7 +37,11 @@ type DemocoinApp struct { capKeyStakingStore *sdk.KVStoreKey // keepers - powKeeper pow.Keeper + coinKeeper bank.Keeper + coolKeeper cool.Keeper + powKeeper pow.Keeper + ibcMapper ibc.Mapper + stakeKeeper simplestake.Keeper // Manage getting and setting accounts accountMapper sdk.AccountMapper @@ -67,21 +71,21 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { ) // Add handlers. - coinKeeper := bank.NewKeeper(app.accountMapper) - coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper, app.RegisterCodespace(cool.DefaultCodespace)) - app.powKeeper = pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) - ibcMapper := ibc.NewMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) - stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) + app.coinKeeper = bank.NewKeeper(app.accountMapper) + app.coolKeeper = cool.NewKeeper(app.capKeyMainStore, app.coinKeeper, app.RegisterCodespace(cool.DefaultCodespace)) + app.powKeeper = pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), app.coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) + app.ibcMapper = ibc.NewMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) + app.stakeKeeper = simplestake.NewKeeper(app.capKeyStakingStore, app.coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) app.Router(). - AddRoute("bank", bank.NewHandler(coinKeeper)). - AddRoute("cool", cool.NewHandler(coolKeeper)). + AddRoute("bank", bank.NewHandler(app.coinKeeper)). + AddRoute("cool", cool.NewHandler(app.coolKeeper)). AddRoute("pow", app.powKeeper.Handler). AddRoute("sketchy", sketchy.NewHandler()). - AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). - AddRoute("simplestake", simplestake.NewHandler(stakeKeeper)) + AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). + AddRoute("simplestake", simplestake.NewHandler(app.stakeKeeper)) // Initialize BaseApp. - app.SetInitChainer(app.initChainerFn(coolKeeper, app.powKeeper)) + app.SetInitChainer(app.initChainerFn(app.coolKeeper, app.powKeeper)) app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyPowStore, app.capKeyIBCStore, app.capKeyStakingStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, auth.BurnFeeHandler)) err := app.LoadLatestVersion(app.capKeyMainStore) @@ -152,6 +156,6 @@ func (app *DemocoinApp) ExportGenesis() types.GenesisState { return types.GenesisState{ Accounts: []*types.GenesisAccount{}, POWGenesis: app.powKeeper.WriteGenesis(ctx), - CoolGenesis: cool.Genesis{}, + CoolGenesis: app.coolKeeper.WriteGenesis(ctx), } } From 9746260d1d30440e8af61753e196bc3704727d89 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 18:34:25 +0200 Subject: [PATCH 08/22] Add testcases --- examples/democoin/x/cool/keeper_test.go | 50 +++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 examples/democoin/x/cool/keeper_test.go diff --git a/examples/democoin/x/cool/keeper_test.go b/examples/democoin/x/cool/keeper_test.go new file mode 100644 index 0000000000..470efea0ab --- /dev/null +++ b/examples/democoin/x/cool/keeper_test.go @@ -0,0 +1,50 @@ +package cool + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + abci "github.com/tendermint/abci/types" + dbm "github.com/tendermint/tmlibs/db" + + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + auth "github.com/cosmos/cosmos-sdk/x/auth" + bank "github.com/cosmos/cosmos-sdk/x/bank" +) + +func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { + db := dbm.NewMemDB() + capKey := sdk.NewKVStoreKey("capkey") + ms := store.NewCommitMultiStore(db) + ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db) + ms.LoadLatestVersion() + return ms, capKey +} + +func TestCoolKeeper(t *testing.T) { + ms, capKey := setupMultiStore() + cdc := wire.NewCodec() + auth.RegisterBaseAccount(cdc) + + am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ck := bank.NewKeeper(am) + keeper := NewKeeper(capKey, ck, DefaultCodespace) + + err := keeper.InitGenesis(ctx, Genesis{"icy"}) + assert.Nil(t, err) + + genesis := keeper.WriteGenesis(ctx) + assert.Nil(t, err) + assert.Equal(t, genesis, Genesis{"icy"}) + + res := keeper.GetTrend(ctx) + assert.Equal(t, res, "icy") + + keeper.setTrend(ctx, "fiery") + res = keeper.GetTrend(ctx) + assert.Equal(t, res, "fiery") +} From 88b364d5a01e98eb2e5547fd98f433a2788e74cc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 18:44:26 +0200 Subject: [PATCH 09/22] Minor bugfix --- examples/basecoin/cmd/basecoind/main.go | 2 +- examples/democoin/cmd/democoind/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 5a165735ef..164ef68654 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -51,5 +51,5 @@ func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, err return nil, nil, err } bapp := app.NewBasecoinApp(logger, db) - return bapp.ExportGenesis(), nil, nil + return bapp.ExportGenesis(), app.MakeCodec(), nil } diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 738420e8de..92e4af70f2 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -59,7 +59,7 @@ func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, err return nil, nil, err } bapp := app.NewDemocoinApp(logger, db) - return bapp.ExportGenesis(), nil, nil + return bapp.ExportGenesis(), app.MakeCodec(), nil } func main() { From dbdf6aae0e54026037ac9a64e93d99556dde1d47 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 18:49:08 +0200 Subject: [PATCH 10/22] Test GetBonds --- x/stake/keeper_test.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index e3edfbf9e2..61737def7c 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -94,7 +94,7 @@ func TestCandidate(t *testing.T) { assert.False(t, found) } -// tests GetDelegatorBond, GetDelegatorBonds, SetDelegatorBond, removeDelegatorBond +// tests GetDelegatorBond, GetDelegatorBonds, SetDelegatorBond, removeDelegatorBond, GetBonds func TestBond(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) @@ -172,6 +172,14 @@ func TestBond(t *testing.T) { assert.True(t, bondsEqual(bond2to1, resBonds[0])) assert.True(t, bondsEqual(bond2to2, resBonds[1])) assert.True(t, bondsEqual(bond2to3, resBonds[2])) + allBonds := keeper.GetBonds(ctx, 1000) + require.Equal(t, 6, len(allBonds)) + assert.True(t, bondsEqual(bond1to1, allBonds[0])) + assert.True(t, bondsEqual(bond1to2, allBonds[1])) + assert.True(t, bondsEqual(bond1to3, allBonds[2])) + assert.True(t, bondsEqual(bond2to1, allBonds[3])) + assert.True(t, bondsEqual(bond2to2, allBonds[4])) + assert.True(t, bondsEqual(bond2to3, allBonds[5])) // delete a record keeper.removeDelegatorBond(ctx, bond2to3) From c788c3e5330a07e194765fdef541d506645fdc5c Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 20:13:16 +0200 Subject: [PATCH 11/22] GetBonds => getBonds --- x/stake/handler.go | 2 +- x/stake/keeper.go | 2 +- x/stake/keeper_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x/stake/handler.go b/x/stake/handler.go index 36e1110d80..6c09b8d7c8 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -65,7 +65,7 @@ func (k Keeper) WriteGenesis(ctx sdk.Context) GenesisState { pool := k.GetPool(ctx) params := k.GetParams(ctx) candidates := k.GetCandidates(ctx, 32767) - bonds := k.GetBonds(ctx, 32767) + bonds := k.getBonds(ctx, 32767) return GenesisState{ pool, params, diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 6bb3f054f7..e53d5ce09b 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -372,7 +372,7 @@ func (k Keeper) GetDelegatorBond(ctx sdk.Context, } // load all bonds -func (k Keeper) GetBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorBond) { +func (k Keeper) getBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorBond) { store := ctx.KVStore(k.storeKey) iterator := store.Iterator(subspace(DelegatorBondKeyPrefix)) diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 61737def7c..3878b7bbb6 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -172,7 +172,7 @@ func TestBond(t *testing.T) { assert.True(t, bondsEqual(bond2to1, resBonds[0])) assert.True(t, bondsEqual(bond2to2, resBonds[1])) assert.True(t, bondsEqual(bond2to3, resBonds[2])) - allBonds := keeper.GetBonds(ctx, 1000) + allBonds := keeper.getBonds(ctx, 1000) require.Equal(t, 6, len(allBonds)) assert.True(t, bondsEqual(bond1to1, allBonds[0])) assert.True(t, bondsEqual(bond1to2, allBonds[1])) From 9450779bba49f129ab6fa0314d0621e1e42d86d5 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 20:19:02 +0200 Subject: [PATCH 12/22] InitGenesis & WriteGenesis no longer functions of keepers --- cmd/gaia/app/app.go | 4 ++-- examples/democoin/app/app.go | 8 ++++---- examples/democoin/x/cool/keeper.go | 4 ++-- examples/democoin/x/cool/keeper_test.go | 4 ++-- examples/democoin/x/pow/handler_test.go | 2 +- examples/democoin/x/pow/keeper.go | 4 ++-- examples/democoin/x/pow/keeper_test.go | 4 ++-- x/stake/handler.go | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index fe47826896..59fb3a2090 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -113,7 +113,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // load the initial stake information - app.stakeKeeper.InitGenesis(ctx, genesisState.StakeData) + stake.InitGenesis(app.stakeKeeper, ctx, genesisState.StakeData) return abci.ResponseInitChain{} } @@ -122,6 +122,6 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci func (app *GaiaApp) ExportGenesis() GenesisState { return GenesisState{ Accounts: []GenesisAccount{}, - StakeData: app.stakeKeeper.WriteGenesis(app.NewContext(true, abci.Header{})), + StakeData: stake.WriteGenesis(app.stakeKeeper, app.NewContext(true, abci.Header{})), } } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index c0b8dd0922..d4c2a2ba3f 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -134,13 +134,13 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep } // Application specific genesis handling - err = coolKeeper.InitGenesis(ctx, genesisState.CoolGenesis) + err = cool.InitGenesis(app.coolKeeper, ctx, genesisState.CoolGenesis) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") } - err = powKeeper.InitGenesis(ctx, genesisState.POWGenesis) + err = pow.InitGenesis(app.powKeeper, ctx, genesisState.POWGenesis) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") @@ -155,7 +155,7 @@ func (app *DemocoinApp) ExportGenesis() types.GenesisState { ctx := app.NewContext(true, abci.Header{}) return types.GenesisState{ Accounts: []*types.GenesisAccount{}, - POWGenesis: app.powKeeper.WriteGenesis(ctx), - CoolGenesis: app.coolKeeper.WriteGenesis(ctx), + POWGenesis: pow.WriteGenesis(app.powKeeper, ctx), + CoolGenesis: cool.WriteGenesis(app.coolKeeper, ctx), } } diff --git a/examples/democoin/x/cool/keeper.go b/examples/democoin/x/cool/keeper.go index 6a1f8da6d2..d594e29af6 100644 --- a/examples/democoin/x/cool/keeper.go +++ b/examples/democoin/x/cool/keeper.go @@ -44,13 +44,13 @@ func (k Keeper) CheckTrend(ctx sdk.Context, guessedTrend string) bool { } // InitGenesis - store the genesis trend -func (k Keeper) InitGenesis(ctx sdk.Context, data Genesis) error { +func InitGenesis(k Keeper, ctx sdk.Context, data Genesis) error { k.setTrend(ctx, data.Trend) return nil } // WriteGenesis - output the genesis trend -func (k Keeper) WriteGenesis(ctx sdk.Context) Genesis { +func WriteGenesis(k Keeper, ctx sdk.Context) Genesis { trend := k.GetTrend(ctx) return Genesis{trend} } diff --git a/examples/democoin/x/cool/keeper_test.go b/examples/democoin/x/cool/keeper_test.go index 470efea0ab..7fa8009fdd 100644 --- a/examples/democoin/x/cool/keeper_test.go +++ b/examples/democoin/x/cool/keeper_test.go @@ -34,10 +34,10 @@ func TestCoolKeeper(t *testing.T) { ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, ck, DefaultCodespace) - err := keeper.InitGenesis(ctx, Genesis{"icy"}) + err := InitGenesis(keeper, ctx, Genesis{"icy"}) assert.Nil(t, err) - genesis := keeper.WriteGenesis(ctx) + genesis := WriteGenesis(keeper, ctx) assert.Nil(t, err) assert.Equal(t, genesis, Genesis{"icy"}) diff --git a/examples/democoin/x/pow/handler_test.go b/examples/democoin/x/pow/handler_test.go index 8a4f81de24..b6f568ee1b 100644 --- a/examples/democoin/x/pow/handler_test.go +++ b/examples/democoin/x/pow/handler_test.go @@ -30,7 +30,7 @@ func TestPowHandler(t *testing.T) { count := uint64(1) difficulty := uint64(2) - err := keeper.InitGenesis(ctx, Genesis{uint64(1), uint64(0)}) + err := InitGenesis(keeper, ctx, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) nonce, proof := mine(addr, count, difficulty) diff --git a/examples/democoin/x/pow/keeper.go b/examples/democoin/x/pow/keeper.go index 4d95840b7b..398009a13b 100644 --- a/examples/democoin/x/pow/keeper.go +++ b/examples/democoin/x/pow/keeper.go @@ -37,14 +37,14 @@ func NewKeeper(key sdk.StoreKey, config Config, ck bank.Keeper, codespace sdk.Co } // InitGenesis for the POW module -func (k Keeper) InitGenesis(ctx sdk.Context, genesis Genesis) error { +func InitGenesis(k Keeper, ctx sdk.Context, genesis Genesis) error { k.SetLastDifficulty(ctx, genesis.Difficulty) k.SetLastCount(ctx, genesis.Count) return nil } // WriteGenesis for the PoW module -func (k Keeper) WriteGenesis(ctx sdk.Context) Genesis { +func WriteGenesis(k Keeper, ctx sdk.Context) Genesis { difficulty, err := k.GetLastDifficulty(ctx) if err != nil { panic(err) diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index 015f98556d..23cad93f72 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -37,10 +37,10 @@ func TestPowKeeperGetSet(t *testing.T) { ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, config, ck, DefaultCodespace) - err := keeper.InitGenesis(ctx, Genesis{uint64(1), uint64(0)}) + err := InitGenesis(keeper, ctx, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) - genesis := keeper.WriteGenesis(ctx) + genesis := WriteGenesis(keeper, ctx) assert.Nil(t, err) assert.Equal(t, genesis, Genesis{uint64(1), uint64(0)}) diff --git a/x/stake/handler.go b/x/stake/handler.go index 6c09b8d7c8..b1d58bf134 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -49,7 +49,7 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { //_____________________________________________________________________ // InitGenesis - store genesis parameters -func (k Keeper) InitGenesis(ctx sdk.Context, data GenesisState) { +func InitGenesis(k Keeper, ctx sdk.Context, data GenesisState) { k.setPool(ctx, data.Pool) k.setParams(ctx, data.Params) for _, candidate := range data.Candidates { @@ -61,7 +61,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data GenesisState) { } // WriteGenesis - output genesis parameters -func (k Keeper) WriteGenesis(ctx sdk.Context) GenesisState { +func WriteGenesis(k Keeper, ctx sdk.Context) GenesisState { pool := k.GetPool(ctx) params := k.GetParams(ctx) candidates := k.GetCandidates(ctx, 32767) From df4fdb3642d620018b44f355bb293aae84ab6f70 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 21:34:32 +0200 Subject: [PATCH 13/22] Rebase & merge changes --- cmd/gaia/cmd/gaiad/main.go | 1 - server/util.go | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 36b7099523..d791ef59fd 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -24,7 +24,6 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp) server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp, exportApp) // prepare and add flags diff --git a/server/util.go b/server/util.go index 6e7c56af0d..e77d500395 100644 --- a/server/util.go +++ b/server/util.go @@ -68,8 +68,7 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error func AddCommands( ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, appInit AppInit, - appCreator AppCreator, appExporter AppExporter, - context *Context) { + appCreator AppCreator, appExporter AppExporter) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") @@ -79,8 +78,8 @@ func AddCommands( UnsafeResetAllCmd(ctx), ShowNodeIDCmd(ctx), ShowValidatorCmd(ctx), - ExportCmd(appExporter, context), - UnsafeResetAllCmd(context), + ExportCmd(appExporter, ctx), + UnsafeResetAllCmd(ctx), version.VersionCmd, ) } From f6cef029046f7629b4f02052c15b187c639b6fcc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 22:52:35 +0200 Subject: [PATCH 14/22] Reorder parameters & remove redundant check --- cmd/gaia/app/app.go | 4 ++-- cmd/gaia/cmd/gaiad/main.go | 11 ++++------- examples/democoin/app/app.go | 8 ++++---- examples/democoin/x/cool/keeper.go | 4 ++-- examples/democoin/x/cool/keeper_test.go | 4 ++-- examples/democoin/x/pow/handler_test.go | 2 +- examples/democoin/x/pow/keeper.go | 4 ++-- examples/democoin/x/pow/keeper_test.go | 4 ++-- x/stake/handler.go | 4 ++-- 9 files changed, 21 insertions(+), 24 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 59fb3a2090..a60c03851d 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -113,7 +113,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // load the initial stake information - stake.InitGenesis(app.stakeKeeper, ctx, genesisState.StakeData) + stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) return abci.ResponseInitChain{} } @@ -122,6 +122,6 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci func (app *GaiaApp) ExportGenesis() GenesisState { return GenesisState{ Accounts: []GenesisAccount{}, - StakeData: stake.WriteGenesis(app.stakeKeeper, app.NewContext(true, abci.Header{})), + StakeData: stake.WriteGenesis(app.NewContext(true, abci.Header{}), app.stakeKeeper), } } diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index d791ef59fd..0e456453e1 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -37,8 +37,8 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { if err != nil { return nil, err } - bapp := app.NewGaiaApp(logger, db) - return bapp, nil + gapp := app.NewGaiaApp(logger, db) + return gapp, nil } func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { @@ -47,9 +47,6 @@ func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, err if err != nil { return nil, nil, err } - bapp := app.NewGaiaApp(log.NewNopLogger(), db) - if err != nil { - return nil, nil, err - } - return bapp.ExportGenesis(), app.MakeCodec(), nil + gapp := app.NewGaiaApp(log.NewNopLogger(), db) + return gapp.ExportGenesis(), app.MakeCodec(), nil } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index d4c2a2ba3f..cb16c53d75 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -134,13 +134,13 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep } // Application specific genesis handling - err = cool.InitGenesis(app.coolKeeper, ctx, genesisState.CoolGenesis) + err = cool.InitGenesis(ctx, app.coolKeeper, genesisState.CoolGenesis) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") } - err = pow.InitGenesis(app.powKeeper, ctx, genesisState.POWGenesis) + err = pow.InitGenesis(ctx, app.powKeeper, genesisState.POWGenesis) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") @@ -155,7 +155,7 @@ func (app *DemocoinApp) ExportGenesis() types.GenesisState { ctx := app.NewContext(true, abci.Header{}) return types.GenesisState{ Accounts: []*types.GenesisAccount{}, - POWGenesis: pow.WriteGenesis(app.powKeeper, ctx), - CoolGenesis: cool.WriteGenesis(app.coolKeeper, ctx), + POWGenesis: pow.WriteGenesis(ctx, app.powKeeper), + CoolGenesis: cool.WriteGenesis(ctx, app.coolKeeper), } } diff --git a/examples/democoin/x/cool/keeper.go b/examples/democoin/x/cool/keeper.go index d594e29af6..fef93b954d 100644 --- a/examples/democoin/x/cool/keeper.go +++ b/examples/democoin/x/cool/keeper.go @@ -44,13 +44,13 @@ func (k Keeper) CheckTrend(ctx sdk.Context, guessedTrend string) bool { } // InitGenesis - store the genesis trend -func InitGenesis(k Keeper, ctx sdk.Context, data Genesis) error { +func InitGenesis(ctx sdk.Context, k Keeper, data Genesis) error { k.setTrend(ctx, data.Trend) return nil } // WriteGenesis - output the genesis trend -func WriteGenesis(k Keeper, ctx sdk.Context) Genesis { +func WriteGenesis(ctx sdk.Context, k Keeper) Genesis { trend := k.GetTrend(ctx) return Genesis{trend} } diff --git a/examples/democoin/x/cool/keeper_test.go b/examples/democoin/x/cool/keeper_test.go index 7fa8009fdd..9aca3cc2a0 100644 --- a/examples/democoin/x/cool/keeper_test.go +++ b/examples/democoin/x/cool/keeper_test.go @@ -34,10 +34,10 @@ func TestCoolKeeper(t *testing.T) { ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, ck, DefaultCodespace) - err := InitGenesis(keeper, ctx, Genesis{"icy"}) + err := InitGenesis(ctx, keeper, Genesis{"icy"}) assert.Nil(t, err) - genesis := WriteGenesis(keeper, ctx) + genesis := WriteGenesis(ctx, keeper) assert.Nil(t, err) assert.Equal(t, genesis, Genesis{"icy"}) diff --git a/examples/democoin/x/pow/handler_test.go b/examples/democoin/x/pow/handler_test.go index b6f568ee1b..0fffb8f5b2 100644 --- a/examples/democoin/x/pow/handler_test.go +++ b/examples/democoin/x/pow/handler_test.go @@ -30,7 +30,7 @@ func TestPowHandler(t *testing.T) { count := uint64(1) difficulty := uint64(2) - err := InitGenesis(keeper, ctx, Genesis{uint64(1), uint64(0)}) + err := InitGenesis(ctx, keeper, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) nonce, proof := mine(addr, count, difficulty) diff --git a/examples/democoin/x/pow/keeper.go b/examples/democoin/x/pow/keeper.go index 398009a13b..931e41a320 100644 --- a/examples/democoin/x/pow/keeper.go +++ b/examples/democoin/x/pow/keeper.go @@ -37,14 +37,14 @@ func NewKeeper(key sdk.StoreKey, config Config, ck bank.Keeper, codespace sdk.Co } // InitGenesis for the POW module -func InitGenesis(k Keeper, ctx sdk.Context, genesis Genesis) error { +func InitGenesis(ctx sdk.Context, k Keeper, genesis Genesis) error { k.SetLastDifficulty(ctx, genesis.Difficulty) k.SetLastCount(ctx, genesis.Count) return nil } // WriteGenesis for the PoW module -func WriteGenesis(k Keeper, ctx sdk.Context) Genesis { +func WriteGenesis(ctx sdk.Context, k Keeper) Genesis { difficulty, err := k.GetLastDifficulty(ctx) if err != nil { panic(err) diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index 23cad93f72..cb021eb16b 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -37,10 +37,10 @@ func TestPowKeeperGetSet(t *testing.T) { ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, config, ck, DefaultCodespace) - err := InitGenesis(keeper, ctx, Genesis{uint64(1), uint64(0)}) + err := InitGenesis(ctx, keeper, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) - genesis := WriteGenesis(keeper, ctx) + genesis := WriteGenesis(ctx, keeper) assert.Nil(t, err) assert.Equal(t, genesis, Genesis{uint64(1), uint64(0)}) diff --git a/x/stake/handler.go b/x/stake/handler.go index b1d58bf134..2b55ba3b1e 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -49,7 +49,7 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { //_____________________________________________________________________ // InitGenesis - store genesis parameters -func InitGenesis(k Keeper, ctx sdk.Context, data GenesisState) { +func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { k.setPool(ctx, data.Pool) k.setParams(ctx, data.Params) for _, candidate := range data.Candidates { @@ -61,7 +61,7 @@ func InitGenesis(k Keeper, ctx sdk.Context, data GenesisState) { } // WriteGenesis - output genesis parameters -func WriteGenesis(k Keeper, ctx sdk.Context) GenesisState { +func WriteGenesis(ctx sdk.Context, k Keeper) GenesisState { pool := k.GetPool(ctx) params := k.GetParams(ctx) candidates := k.GetCandidates(ctx, 32767) From 10d2e5ae403fecc5780b19401163bb6ea537f21b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 27 Apr 2018 13:38:11 +0200 Subject: [PATCH 15/22] Move generateApp & exportApp to baseapp/helpers --- baseapp/baseapp.go | 7 +++++ baseapp/helpers.go | 38 +++++++++++++++++++++++++ cmd/gaia/app/app.go | 2 +- cmd/gaia/cmd/gaiad/main.go | 28 ++++++------------ examples/basecoin/app/app.go | 2 +- examples/basecoin/cmd/basecoind/main.go | 25 ++++++---------- examples/democoin/app/app.go | 2 +- examples/democoin/cmd/democoind/main.go | 26 ++++++----------- server/export.go | 10 ++----- server/start.go | 13 +++------ server/util.go | 3 +- 11 files changed, 83 insertions(+), 73 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 210900d614..515970d04f 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -241,6 +241,13 @@ func (app *BaseApp) setDeliverState(header abci.Header) { } //______________________________________________________________________________ + +// ExportGenesis returns the genesis state in a wire-serializable format +// should be overridden by applications extending baseapp +func (app *BaseApp) ExportGenesis() interface{} { + return nil +} + // ABCI // Implements ABCI diff --git a/baseapp/helpers.go b/baseapp/helpers.go index 43bd654d67..e2007a1f51 100644 --- a/baseapp/helpers.go +++ b/baseapp/helpers.go @@ -1,9 +1,14 @@ package baseapp import ( + "path/filepath" + + "github.com/cosmos/cosmos-sdk/wire" "github.com/tendermint/abci/server" abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" + dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" ) // RunForever - BasecoinApp execution and cleanup @@ -22,3 +27,36 @@ func RunForever(app abci.Application) { srv.Stop() }) } + +// AppCreator lets us lazily initialize app, using home dir +// and other flags (?) to start +type AppCreator func(string, log.Logger) (abci.Application, error) + +// AppExporter dumps all app state to JSON-serializable structure +type AppExporter func(home string, log log.Logger) (interface{}, *wire.Codec, error) + +// GenerateFn returns an application generation function +func GenerateFn(appFn func(log.Logger, dbm.DB) abci.Application, name string) AppCreator { + return func(rootDir string, logger log.Logger) (abci.Application, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB(name, dataDir) + if err != nil { + return nil, err + } + app := appFn(logger, db) + return app, nil + } +} + +// ExportFn returns an application export function +func ExportFn(appFn func(log.Logger, dbm.DB) (interface{}, *wire.Codec), name string) AppExporter { + return func(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB(name, dataDir) + if err != nil { + return nil, nil, err + } + genesis, codec := appFn(logger, db) + return genesis, codec, nil + } +} diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index a60c03851d..126422e2ce 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -119,7 +119,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // custom logic for export -func (app *GaiaApp) ExportGenesis() GenesisState { +func (app *GaiaApp) ExportGenesis() interface{} { return GenesisState{ Accounts: []GenesisAccount{}, StakeData: stake.WriteGenesis(app.NewContext(true, abci.Header{}), app.stakeKeeper), diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 0e456453e1..9e6dfff05d 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -1,8 +1,6 @@ package main import ( - "path/filepath" - "github.com/spf13/cobra" abci "github.com/tendermint/abci/types" @@ -10,6 +8,7 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/wire" @@ -24,29 +23,20 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp, exportApp) + server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), + baseapp.GenerateFn(newApp, "gaia"), + baseapp.ExportFn(exportApp, "gaia")) // prepare and add flags executor := cli.PrepareBaseCmd(rootCmd, "GA", app.DefaultNodeHome) executor.Execute() } -func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("gaia", dataDir) - if err != nil { - return nil, err - } - gapp := app.NewGaiaApp(logger, db) - return gapp, nil +func newApp(logger log.Logger, db dbm.DB) abci.Application { + return app.NewGaiaApp(logger, db) } -func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("gaia", dataDir) - if err != nil { - return nil, nil, err - } - gapp := app.NewGaiaApp(log.NewNopLogger(), db) - return gapp.ExportGenesis(), app.MakeCodec(), nil +func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { + gapp := app.NewGaiaApp(logger, db) + return gapp.ExportGenesis(), app.MakeCodec() } diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 529bb99d79..eb5076942f 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -127,7 +127,7 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) } // Custom logic for state export -func (app *BasecoinApp) ExportGenesis() types.GenesisState { +func (app *BasecoinApp) ExportGenesis() interface{} { return types.GenesisState{ Accounts: []*types.GenesisAccount{}, } diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 164ef68654..4aa04a914f 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -2,7 +2,6 @@ package main import ( "os" - "path/filepath" "github.com/spf13/cobra" @@ -11,6 +10,7 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/wire" @@ -26,7 +26,9 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, generateApp, exportApp) + server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, + baseapp.GenerateFn(newApp, "basecoin"), + baseapp.ExportFn(exportApp, "basecoin")) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.basecoind") @@ -34,22 +36,11 @@ func main() { executor.Execute() } -func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("basecoin", dataDir) - if err != nil { - return nil, err - } - bapp := app.NewBasecoinApp(logger, db) - return bapp, nil +func newApp(logger log.Logger, db dbm.DB) abci.Application { + return app.NewBasecoinApp(logger, db) } -func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("basecoin", dataDir) - if err != nil { - return nil, nil, err - } +func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { bapp := app.NewBasecoinApp(logger, db) - return bapp.ExportGenesis(), app.MakeCodec(), nil + return bapp.ExportGenesis(), app.MakeCodec() } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index cb16c53d75..3b383bef8f 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -151,7 +151,7 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep } // Custom logic for state export -func (app *DemocoinApp) ExportGenesis() types.GenesisState { +func (app *DemocoinApp) ExportGenesis() interface{} { ctx := app.NewContext(true, abci.Header{}) return types.GenesisState{ Accounts: []*types.GenesisAccount{}, diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 92e4af70f2..8dc01faaf6 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "os" - "path/filepath" "github.com/spf13/cobra" @@ -12,6 +11,7 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/examples/democoin/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/wire" @@ -43,23 +43,13 @@ func CoolAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso return } -func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { - db, err := dbm.NewGoLevelDB("democoin", filepath.Join(rootDir, "data")) - if err != nil { - return nil, err - } - bapp := app.NewDemocoinApp(logger, db) - return bapp, nil +func newApp(logger log.Logger, db dbm.DB) abci.Application { + return app.NewDemocoinApp(logger, db) } -func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("democoin", dataDir) - if err != nil { - return nil, nil, err - } - bapp := app.NewDemocoinApp(logger, db) - return bapp.ExportGenesis(), app.MakeCodec(), nil +func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { + dapp := app.NewDemocoinApp(logger, db) + return dapp.ExportGenesis(), app.MakeCodec() } func main() { @@ -72,7 +62,9 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, generateApp, exportApp) + server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, + baseapp.GenerateFn(newApp, "democoin"), + baseapp.ExportFn(exportApp, "democoin")) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.democoind") diff --git a/server/export.go b/server/export.go index 9430eeb48a..3ca71217ba 100644 --- a/server/export.go +++ b/server/export.go @@ -6,16 +6,12 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/tendermint/tmlibs/log" - + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/wire" ) -// AppExporter dumps all app state to JSON-serializable structure -type AppExporter func(home string, log log.Logger) (interface{}, *wire.Codec, error) - // ExportCmd dumps app state to JSON -func ExportCmd(app AppExporter, ctx *Context) *cobra.Command { +func ExportCmd(app baseapp.AppExporter, ctx *Context) *cobra.Command { export := exportCmd{ appExporter: app, context: ctx, @@ -29,7 +25,7 @@ func ExportCmd(app AppExporter, ctx *Context) *cobra.Command { } type exportCmd struct { - appExporter AppExporter + appExporter baseapp.AppExporter context *Context } diff --git a/server/start.go b/server/start.go index c9a38abdff..79f5e39803 100644 --- a/server/start.go +++ b/server/start.go @@ -6,14 +6,13 @@ import ( "github.com/spf13/viper" "github.com/tendermint/abci/server" - abci "github.com/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/baseapp" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/proxy" pvm "github.com/tendermint/tendermint/types/priv_validator" cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" ) const ( @@ -21,13 +20,9 @@ const ( flagAddress = "address" ) -// AppCreator lets us lazily initialize app, using home dir -// and other flags (?) to start -type AppCreator func(string, log.Logger) (abci.Application, error) - // StartCmd runs the service passed in, either // stand-alone, or in-process with tendermint -func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command { +func StartCmd(ctx *Context, appCreator baseapp.AppCreator) *cobra.Command { cmd := &cobra.Command{ Use: "start", Short: "Run the full node", @@ -50,7 +45,7 @@ func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command { return cmd } -func startStandAlone(ctx *Context, appCreator AppCreator) error { +func startStandAlone(ctx *Context, appCreator baseapp.AppCreator) error { // Generate the app in the proper dir addr := viper.GetString(flagAddress) home := viper.GetString("home") @@ -74,7 +69,7 @@ func startStandAlone(ctx *Context, appCreator AppCreator) error { return nil } -func startInProcess(ctx *Context, appCreator AppCreator) error { +func startInProcess(ctx *Context, appCreator baseapp.AppCreator) error { cfg := ctx.Config home := cfg.RootDir app, err := appCreator(home, ctx.Logger) diff --git a/server/util.go b/server/util.go index e77d500395..31e472839b 100644 --- a/server/util.go +++ b/server/util.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/wire" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" @@ -68,7 +69,7 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error func AddCommands( ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, appInit AppInit, - appCreator AppCreator, appExporter AppExporter) { + appCreator baseapp.AppCreator, appExporter baseapp.AppExporter) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") From ad77affb53096e1017bfdba28da8ac7f9547705d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 27 Apr 2018 16:59:47 +0200 Subject: [PATCH 16/22] Add IterateAccounts & account export --- cmd/gaia/app/app.go | 13 +++++++++++-- examples/basecoin/app/app.go | 11 ++++++++++- examples/democoin/app/app.go | 10 +++++++++- types/account.go | 1 + x/auth/mapper.go | 17 +++++++++++++++++ 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 126422e2ce..532a1e095c 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -120,8 +120,17 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci // custom logic for export func (app *GaiaApp) ExportGenesis() interface{} { + ctx := app.NewContext(true, abci.Header{}) + accounts := []GenesisAccount{} + app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { + accounts = append(accounts, GenesisAccount{ + Address: a.GetAddress(), + Coins: a.GetCoins(), + }) + return false + }) return GenesisState{ - Accounts: []GenesisAccount{}, - StakeData: stake.WriteGenesis(app.NewContext(true, abci.Header{}), app.stakeKeeper), + Accounts: accounts, + StakeData: stake.WriteGenesis(ctx, app.stakeKeeper), } } diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index eb5076942f..532c25f764 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -128,7 +128,16 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) // Custom logic for state export func (app *BasecoinApp) ExportGenesis() interface{} { + ctx := app.NewContext(true, abci.Header{}) + accounts := []*types.GenesisAccount{} + app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { + accounts = append(accounts, &types.GenesisAccount{ + Address: a.GetAddress(), + Coins: a.GetCoins(), + }) + return false + }) return types.GenesisState{ - Accounts: []*types.GenesisAccount{}, + Accounts: accounts, } } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 3b383bef8f..5f2cd32d80 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -153,8 +153,16 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep // Custom logic for state export func (app *DemocoinApp) ExportGenesis() interface{} { ctx := app.NewContext(true, abci.Header{}) + accounts := []*types.GenesisAccount{} + app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { + accounts = append(accounts, &types.GenesisAccount{ + Address: a.GetAddress(), + Coins: a.GetCoins(), + }) + return false + }) return types.GenesisState{ - Accounts: []*types.GenesisAccount{}, + Accounts: accounts, POWGenesis: pow.WriteGenesis(ctx, app.powKeeper), CoolGenesis: cool.WriteGenesis(ctx, app.coolKeeper), } diff --git a/types/account.go b/types/account.go index 91ad499795..33332867c6 100644 --- a/types/account.go +++ b/types/account.go @@ -48,6 +48,7 @@ type AccountMapper interface { NewAccountWithAddress(ctx Context, addr Address) Account GetAccount(ctx Context, addr Address) Account SetAccount(ctx Context, acc Account) + IterateAccounts(ctx Context, cont func(Account) bool) } // AccountDecoder unmarshals account bytes diff --git a/x/auth/mapper.go b/x/auth/mapper.go index b815fada7a..fea98876d1 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -62,6 +62,23 @@ func (am accountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) { store.Set(addr, bz) } +// Implements sdk.AccountMapper. +func (am accountMapper) IterateAccounts(ctx sdk.Context, cont func(sdk.Account) bool) { + store := ctx.KVStore(am.key) + iter := store.Iterator(nil, nil) + for { + if !iter.Valid() { + return + } + val := iter.Value() + acc := am.decodeAccount(val) + if cont(acc) { + return + } + iter.Next() + } +} + //---------------------------------------- // misc. From 5759f6ab6037d5aa79cf0c45beae43917d8af963 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 27 Apr 2018 17:06:55 +0200 Subject: [PATCH 17/22] Use account store key --- cmd/gaia/app/app.go | 10 ++++++++-- examples/democoin/app/app.go | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 532a1e095c..b9a77cfc58 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -58,8 +58,14 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { keyStake: sdk.NewKVStoreKey("stake"), } - // add accountMapper/handlers - app.accountMapper = auth.NewAccountMapper(app.cdc, app.keyMain, &auth.BaseAccount{}) + // define the accountMapper + app.accountMapper = auth.NewAccountMapper( + app.cdc, + app.keyAccount, // target store + &auth.BaseAccount{}, // prototype + ) + + // add handlers app.coinKeeper = bank.NewKeeper(app.accountMapper) app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace)) app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 5f2cd32d80..f7da19f722 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -66,8 +66,8 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { // Define the accountMapper. app.accountMapper = auth.NewAccountMapper( cdc, - app.capKeyMainStore, // target store - &types.AppAccount{}, // prototype + app.capKeyAccountStore, // target store + &types.AppAccount{}, // prototype ) // Add handlers. From 67961476b460b4d6672f8c99034a1e440876c1a7 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 27 Apr 2018 17:14:08 +0200 Subject: [PATCH 18/22] Fix testsuite --- client/lcd/root.go | 2 +- cmd/gaia/cmd/gaiacli/main.go | 2 +- examples/basecoin/cmd/basecli/main.go | 6 ++++++ examples/democoin/cmd/democli/main.go | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/client/lcd/root.go b/client/lcd/root.go index b166d4ce46..a7be5079bf 100644 --- a/client/lcd/root.go +++ b/client/lcd/root.go @@ -80,7 +80,7 @@ func createHandler(cdc *wire.Codec) http.Handler { keys.RegisterRoutes(r) rpc.RegisterRoutes(ctx, r) tx.RegisterRoutes(ctx, r, cdc) - auth.RegisterRoutes(ctx, r, cdc, "main") + auth.RegisterRoutes(ctx, r, cdc, "acc") bank.RegisterRoutes(ctx, r, cdc, kb) ibc.RegisterRoutes(ctx, r, cdc, kb) return r diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index ab0a98c695..93d6b57b91 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -44,7 +44,7 @@ func main() { // add query/post commands (custom to binary) rootCmd.AddCommand( client.GetCommands( - authcmd.GetAccountCmd("main", cdc, authcmd.GetAccountDecoder(cdc)), + authcmd.GetAccountCmd("acc", cdc, authcmd.GetAccountDecoder(cdc)), stakecmd.GetCmdQueryCandidate("stake", cdc), //stakecmd.GetCmdQueryCandidates("stake", cdc), stakecmd.GetCmdQueryDelegatorBond("stake", cdc), diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index 50800450fe..1cc440995b 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -19,6 +19,7 @@ import ( stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" "github.com/cosmos/cosmos-sdk/examples/basecoin/app" + "github.com/cosmos/cosmos-sdk/examples/basecoin/types" ) // rootCmd is the entry point for this binary @@ -47,6 +48,11 @@ func main() { rootCmd.AddCommand(client.LineBreak) // add query/post commands (custom to binary) + rootCmd.AddCommand( + client.GetCommands( + authcmd.GetAccountCmd("acc", cdc, types.GetAccountDecoder(cdc)), + )...) + rootCmd.AddCommand( client.PostCommands( bankcmd.SendTxCmd(cdc), diff --git a/examples/democoin/cmd/democli/main.go b/examples/democoin/cmd/democli/main.go index 45a448c2ef..cdf9396d6c 100644 --- a/examples/democoin/cmd/democli/main.go +++ b/examples/democoin/cmd/democli/main.go @@ -54,7 +54,7 @@ func main() { // start with commands common to basecoin rootCmd.AddCommand( client.GetCommands( - authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)), + authcmd.GetAccountCmd("acc", cdc, types.GetAccountDecoder(cdc)), )...) rootCmd.AddCommand( client.PostCommands( From 10ddd7a3d32ea1b9b4a1e797afcc6e9290002560 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 27 Apr 2018 20:00:33 -0400 Subject: [PATCH 19/22] refactor export function, working --- baseapp/helpers.go | 7 ++++--- cmd/gaia/app/app.go | 22 +++++++++++++--------- cmd/gaia/app/genesis.go | 7 +++++++ server/export.go | 39 ++++++++++++--------------------------- server/util.go | 5 ++--- types/account.go | 2 +- x/auth/mapper.go | 4 ++-- 7 files changed, 41 insertions(+), 45 deletions(-) diff --git a/baseapp/helpers.go b/baseapp/helpers.go index e2007a1f51..7a7884677e 100644 --- a/baseapp/helpers.go +++ b/baseapp/helpers.go @@ -1,6 +1,7 @@ package baseapp import ( + "encoding/json" "path/filepath" "github.com/cosmos/cosmos-sdk/wire" @@ -49,14 +50,14 @@ func GenerateFn(appFn func(log.Logger, dbm.DB) abci.Application, name string) Ap } // ExportFn returns an application export function -func ExportFn(appFn func(log.Logger, dbm.DB) (interface{}, *wire.Codec), name string) AppExporter { - return func(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { +func ExportFn(appFn func(log.Logger, dbm.DB) json.RawMessage, name string) AppExporter { + return func(rootDir string, logger log.Logger) (interface{}, error) { dataDir := filepath.Join(rootDir, "data") db, err := dbm.NewGoLevelDB(name, dataDir) if err != nil { return nil, nil, err } - genesis, codec := appFn(logger, db) + genesis := appFn(logger, db) return genesis, codec, nil } } diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index b9a77cfc58..66f16e7ad9 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -1,6 +1,7 @@ package app import ( + "encoding/json" "os" abci "github.com/tendermint/abci/types" @@ -124,19 +125,22 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci return abci.ResponseInitChain{} } -// custom logic for export -func (app *GaiaApp) ExportGenesis() interface{} { +// export the state of gaia for a genesis f +func (app *GaiaApp) ExportAppStateJSON() (appState json.RawGenesis, err error) { ctx := app.NewContext(true, abci.Header{}) + + // iterate to get the accounts accounts := []GenesisAccount{} - app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { - accounts = append(accounts, GenesisAccount{ - Address: a.GetAddress(), - Coins: a.GetCoins(), - }) + appendAccount := func(acc sdk.Account) (stop bool) { + account := NewGenesisAccountI(acc) + accounts = append(accounts, account) return false - }) - return GenesisState{ + } + app.accountMapper.IterateAccounts(ctx, appendAccount) + + genState := GenesisState{ Accounts: accounts, StakeData: stake.WriteGenesis(ctx, app.stakeKeeper), } + return wire.MarshalJSONIndent(cdc, genState) } diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 513430ec9a..7d0fb01d0c 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -35,6 +35,13 @@ func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount { } } +func NewGenesisAccountI(acc sdk.Account) GenesisAccount { + return GenesisAccount{ + Address: acc.GetAddress(), + Coins: acc.GetCoins(), + } +} + // convert GenesisAccount to auth.BaseAccount func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { return &auth.BaseAccount{ diff --git a/server/export.go b/server/export.go index 3ca71217ba..8d464b3b1b 100644 --- a/server/export.go +++ b/server/export.go @@ -2,6 +2,7 @@ package server import ( "fmt" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -11,34 +12,18 @@ import ( ) // ExportCmd dumps app state to JSON -func ExportCmd(app baseapp.AppExporter, ctx *Context) *cobra.Command { - export := exportCmd{ - appExporter: app, - context: ctx, - } - cmd := &cobra.Command{ +func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter baseapp.AppExporter) *cobra.Command { + return &cobra.Command{ Use: "export", Short: "Export state to JSON", - RunE: export.run, + RunE: func(cmd *cobra.Command, args []string) error { + home := viper.GetString("home") + appState, err := appExporter(home, ctx.Logger) + if err != nil { + return errors.Errorf("Error exporting state: %v\n", err) + } + fmt.Println(string(output)) + return nil + }, } - return cmd -} - -type exportCmd struct { - appExporter baseapp.AppExporter - context *Context -} - -func (e exportCmd) run(cmd *cobra.Command, args []string) error { - home := viper.GetString("home") - genesis, cdc, err := e.appExporter(home, e.context.Logger) - if err != nil { - return errors.Errorf("Error exporting state: %v\n", err) - } - output, err := wire.MarshalJSONIndent(cdc, genesis) - if err != nil { - return errors.Errorf("Error marshalling state: %v\n", err) - } - fmt.Println(string(output)) - return nil } diff --git a/server/util.go b/server/util.go index 31e472839b..54377547d5 100644 --- a/server/util.go +++ b/server/util.go @@ -9,7 +9,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/wire" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" @@ -69,7 +68,7 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error func AddCommands( ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, appInit AppInit, - appCreator baseapp.AppCreator, appExporter baseapp.AppExporter) { + appCreator AppCreator) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") @@ -79,7 +78,7 @@ func AddCommands( UnsafeResetAllCmd(ctx), ShowNodeIDCmd(ctx), ShowValidatorCmd(ctx), - ExportCmd(appExporter, ctx), + ExportCmd(cts, cdc, appCreator), UnsafeResetAllCmd(ctx), version.VersionCmd, ) diff --git a/types/account.go b/types/account.go index 33332867c6..b47aea28af 100644 --- a/types/account.go +++ b/types/account.go @@ -48,7 +48,7 @@ type AccountMapper interface { NewAccountWithAddress(ctx Context, addr Address) Account GetAccount(ctx Context, addr Address) Account SetAccount(ctx Context, acc Account) - IterateAccounts(ctx Context, cont func(Account) bool) + IterateAccounts(ctx Context, process func(sdk.Account) (stop bool)) } // AccountDecoder unmarshals account bytes diff --git a/x/auth/mapper.go b/x/auth/mapper.go index fea98876d1..f9e202c8a2 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -63,7 +63,7 @@ func (am accountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) { } // Implements sdk.AccountMapper. -func (am accountMapper) IterateAccounts(ctx sdk.Context, cont func(sdk.Account) bool) { +func (am accountMapper) IterateAccounts(ctx sdk.Context, process func(sdk.Account) (stop bool)) { store := ctx.KVStore(am.key) iter := store.Iterator(nil, nil) for { @@ -72,7 +72,7 @@ func (am accountMapper) IterateAccounts(ctx sdk.Context, cont func(sdk.Account) } val := iter.Value() acc := am.decodeAccount(val) - if cont(acc) { + if process(acc) { return } iter.Next() From 318e92414528d87d06700caad71462024f315819 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 27 Apr 2018 20:36:11 -0400 Subject: [PATCH 20/22] refactor --- baseapp/baseapp.go | 6 ---- baseapp/helpers.go | 39 ----------------------- cmd/gaia/app/app.go | 4 +-- cmd/gaia/cmd/gaiad/main.go | 12 +++---- examples/basecoin/app/app.go | 13 +++----- examples/basecoin/cmd/basecli/main.go | 1 + examples/basecoin/cmd/basecoind/main.go | 11 +++---- examples/democoin/app/app.go | 24 +++++++++----- examples/democoin/cmd/democoind/main.go | 9 +++--- server/constructors.go | 42 +++++++++++++++++++++++++ server/export.go | 5 ++- server/start.go | 7 ++--- server/util.go | 4 +-- types/account.go | 2 +- 14 files changed, 89 insertions(+), 90 deletions(-) create mode 100644 server/constructors.go diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 515970d04f..84a18aa06d 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -242,12 +242,6 @@ func (app *BaseApp) setDeliverState(header abci.Header) { //______________________________________________________________________________ -// ExportGenesis returns the genesis state in a wire-serializable format -// should be overridden by applications extending baseapp -func (app *BaseApp) ExportGenesis() interface{} { - return nil -} - // ABCI // Implements ABCI diff --git a/baseapp/helpers.go b/baseapp/helpers.go index 7a7884677e..43bd654d67 100644 --- a/baseapp/helpers.go +++ b/baseapp/helpers.go @@ -1,15 +1,9 @@ package baseapp import ( - "encoding/json" - "path/filepath" - - "github.com/cosmos/cosmos-sdk/wire" "github.com/tendermint/abci/server" abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" ) // RunForever - BasecoinApp execution and cleanup @@ -28,36 +22,3 @@ func RunForever(app abci.Application) { srv.Stop() }) } - -// AppCreator lets us lazily initialize app, using home dir -// and other flags (?) to start -type AppCreator func(string, log.Logger) (abci.Application, error) - -// AppExporter dumps all app state to JSON-serializable structure -type AppExporter func(home string, log log.Logger) (interface{}, *wire.Codec, error) - -// GenerateFn returns an application generation function -func GenerateFn(appFn func(log.Logger, dbm.DB) abci.Application, name string) AppCreator { - return func(rootDir string, logger log.Logger) (abci.Application, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB(name, dataDir) - if err != nil { - return nil, err - } - app := appFn(logger, db) - return app, nil - } -} - -// ExportFn returns an application export function -func ExportFn(appFn func(log.Logger, dbm.DB) json.RawMessage, name string) AppExporter { - return func(rootDir string, logger log.Logger) (interface{}, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB(name, dataDir) - if err != nil { - return nil, nil, err - } - genesis := appFn(logger, db) - return genesis, codec, nil - } -} diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 66f16e7ad9..a9cf248e1c 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -126,7 +126,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // export the state of gaia for a genesis f -func (app *GaiaApp) ExportAppStateJSON() (appState json.RawGenesis, err error) { +func (app *GaiaApp) ExportAppStateJSON() (appState json.RawMessage, err error) { ctx := app.NewContext(true, abci.Header{}) // iterate to get the accounts @@ -142,5 +142,5 @@ func (app *GaiaApp) ExportAppStateJSON() (appState json.RawGenesis, err error) { Accounts: accounts, StakeData: stake.WriteGenesis(ctx, app.stakeKeeper), } - return wire.MarshalJSONIndent(cdc, genState) + return wire.MarshalJSONIndent(app.cdc, genState) } diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 9e6dfff05d..f64498d850 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -1,6 +1,8 @@ package main import ( + "encoding/json" + "github.com/spf13/cobra" abci "github.com/tendermint/abci/types" @@ -8,10 +10,8 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/wire" ) func main() { @@ -24,8 +24,8 @@ func main() { } server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), - baseapp.GenerateFn(newApp, "gaia"), - baseapp.ExportFn(exportApp, "gaia")) + server.ConstructAppCreator(newApp, "gaia"), + server.ConstructAppExporter(exportAppState, "gaia")) // prepare and add flags executor := cli.PrepareBaseCmd(rootCmd, "GA", app.DefaultNodeHome) @@ -36,7 +36,7 @@ func newApp(logger log.Logger, db dbm.DB) abci.Application { return app.NewGaiaApp(logger, db) } -func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { +func exportAppState(logger log.Logger, db dbm.DB) (json.RawMessage, error) { gapp := app.NewGaiaApp(logger, db) - return gapp.ExportGenesis(), app.MakeCodec() + return gapp.ExportAppStateJSON() } diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 532c25f764..b8f5346cd6 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -1,6 +1,8 @@ package app import ( + "encoding/json" + abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" @@ -15,7 +17,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" - "github.com/cosmos/cosmos-sdk/examples/democoin/x/simplestake" ) const ( @@ -33,11 +34,6 @@ type BasecoinApp struct { keyIBC *sdk.KVStoreKey keyStake *sdk.KVStoreKey - // keepers - coinKeeper bank.Keeper - ibcMapper ibc.Mapper - stakeKeeper simplestake.Keeper - // Manage getting and setting accounts accountMapper sdk.AccountMapper coinKeeper bank.Keeper @@ -127,7 +123,7 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) } // Custom logic for state export -func (app *BasecoinApp) ExportGenesis() interface{} { +func (app *BasecoinApp) ExportAppStateJSON() (appState json.RawMessage, err error) { ctx := app.NewContext(true, abci.Header{}) accounts := []*types.GenesisAccount{} app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { @@ -137,7 +133,8 @@ func (app *BasecoinApp) ExportGenesis() interface{} { }) return false }) - return types.GenesisState{ + genState := types.GenesisState{ Accounts: accounts, } + return wire.MarshalJSONIndent(app.cdc, genState) } diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index 1cc440995b..f5385b5596 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/version" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 4aa04a914f..4e6a30a086 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "os" "github.com/spf13/cobra" @@ -10,10 +11,8 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/wire" ) func main() { @@ -27,8 +26,8 @@ func main() { } server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, - baseapp.GenerateFn(newApp, "basecoin"), - baseapp.ExportFn(exportApp, "basecoin")) + server.ConstructAppCreator(newApp, "basecoin"), + server.ConstructAppExporter(exportAppState, "basecoin")) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.basecoind") @@ -40,7 +39,7 @@ func newApp(logger log.Logger, db dbm.DB) abci.Application { return app.NewBasecoinApp(logger, db) } -func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { +func exportAppState(logger log.Logger, db dbm.DB) (json.RawMessage, error) { bapp := app.NewBasecoinApp(logger, db) - return bapp.ExportGenesis(), app.MakeCodec() + return bapp.ExportAppStateJSON() } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index f7da19f722..7c8250b189 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -1,6 +1,8 @@ package app import ( + "encoding/json" + abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" @@ -151,19 +153,25 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep } // Custom logic for state export -func (app *DemocoinApp) ExportGenesis() interface{} { +func (app *DemocoinApp) ExportAppStateJSON() (appState json.RawMessage, err error) { ctx := app.NewContext(true, abci.Header{}) + + // iterate to get the accounts accounts := []*types.GenesisAccount{} - app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { - accounts = append(accounts, &types.GenesisAccount{ - Address: a.GetAddress(), - Coins: a.GetCoins(), - }) + appendAccount := func(acc sdk.Account) (stop bool) { + account := &types.GenesisAccount{ + Address: acc.GetAddress(), + Coins: acc.GetCoins(), + } + accounts = append(accounts, account) return false - }) - return types.GenesisState{ + } + app.accountMapper.IterateAccounts(ctx, appendAccount) + + genState := types.GenesisState{ Accounts: accounts, POWGenesis: pow.WriteGenesis(ctx, app.powKeeper), CoolGenesis: cool.WriteGenesis(ctx, app.coolKeeper), } + return wire.MarshalJSONIndent(app.cdc, genState) } diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 8dc01faaf6..3283da58ae 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -11,7 +11,6 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/examples/democoin/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/wire" @@ -47,9 +46,9 @@ func newApp(logger log.Logger, db dbm.DB) abci.Application { return app.NewDemocoinApp(logger, db) } -func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { +func exportAppState(logger log.Logger, db dbm.DB) (json.RawMessage, error) { dapp := app.NewDemocoinApp(logger, db) - return dapp.ExportGenesis(), app.MakeCodec() + return dapp.ExportAppStateJSON() } func main() { @@ -63,8 +62,8 @@ func main() { } server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, - baseapp.GenerateFn(newApp, "democoin"), - baseapp.ExportFn(exportApp, "democoin")) + server.ConstructAppCreator(newApp, "democoin"), + server.ConstructAppExporter(exportAppState, "democoin")) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.democoind") diff --git a/server/constructors.go b/server/constructors.go new file mode 100644 index 0000000000..3d6950062b --- /dev/null +++ b/server/constructors.go @@ -0,0 +1,42 @@ +package server + +import ( + "encoding/json" + "path/filepath" + + abci "github.com/tendermint/abci/types" + dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" +) + +// AppCreator lets us lazily initialize app, using home dir +// and other flags (?) to start +type AppCreator func(string, log.Logger) (abci.Application, error) + +// AppExporter dumps all app state to JSON-serializable structure +type AppExporter func(home string, log log.Logger) (json.RawMessage, error) + +// ConstructAppCreator returns an application generation function +func ConstructAppCreator(appFn func(log.Logger, dbm.DB) abci.Application, name string) AppCreator { + return func(rootDir string, logger log.Logger) (abci.Application, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB(name, dataDir) + if err != nil { + return nil, err + } + app := appFn(logger, db) + return app, nil + } +} + +// ConstructAppExporter returns an application export function +func ConstructAppExporter(appFn func(log.Logger, dbm.DB) (json.RawMessage, error), name string) AppExporter { + return func(rootDir string, logger log.Logger) (json.RawMessage, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB(name, dataDir) + if err != nil { + return nil, err + } + return appFn(logger, db) + } +} diff --git a/server/export.go b/server/export.go index 8d464b3b1b..3d0e49a126 100644 --- a/server/export.go +++ b/server/export.go @@ -7,12 +7,11 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/wire" ) // ExportCmd dumps app state to JSON -func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter baseapp.AppExporter) *cobra.Command { +func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter AppExporter) *cobra.Command { return &cobra.Command{ Use: "export", Short: "Export state to JSON", @@ -22,7 +21,7 @@ func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter baseapp.AppExporter) * if err != nil { return errors.Errorf("Error exporting state: %v\n", err) } - fmt.Println(string(output)) + fmt.Println(string(appState)) return nil }, } diff --git a/server/start.go b/server/start.go index 79f5e39803..23e38749be 100644 --- a/server/start.go +++ b/server/start.go @@ -7,7 +7,6 @@ import ( "github.com/tendermint/abci/server" - "github.com/cosmos/cosmos-sdk/baseapp" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/proxy" @@ -22,7 +21,7 @@ const ( // StartCmd runs the service passed in, either // stand-alone, or in-process with tendermint -func StartCmd(ctx *Context, appCreator baseapp.AppCreator) *cobra.Command { +func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command { cmd := &cobra.Command{ Use: "start", Short: "Run the full node", @@ -45,7 +44,7 @@ func StartCmd(ctx *Context, appCreator baseapp.AppCreator) *cobra.Command { return cmd } -func startStandAlone(ctx *Context, appCreator baseapp.AppCreator) error { +func startStandAlone(ctx *Context, appCreator AppCreator) error { // Generate the app in the proper dir addr := viper.GetString(flagAddress) home := viper.GetString("home") @@ -69,7 +68,7 @@ func startStandAlone(ctx *Context, appCreator baseapp.AppCreator) error { return nil } -func startInProcess(ctx *Context, appCreator baseapp.AppCreator) error { +func startInProcess(ctx *Context, appCreator AppCreator) error { cfg := ctx.Config home := cfg.RootDir app, err := appCreator(home, ctx.Logger) diff --git a/server/util.go b/server/util.go index 54377547d5..313d4fc5b2 100644 --- a/server/util.go +++ b/server/util.go @@ -68,7 +68,7 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error func AddCommands( ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, appInit AppInit, - appCreator AppCreator) { + appCreator AppCreator, appExport AppExporter) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") @@ -78,7 +78,7 @@ func AddCommands( UnsafeResetAllCmd(ctx), ShowNodeIDCmd(ctx), ShowValidatorCmd(ctx), - ExportCmd(cts, cdc, appCreator), + ExportCmd(ctx, cdc, appExport), UnsafeResetAllCmd(ctx), version.VersionCmd, ) diff --git a/types/account.go b/types/account.go index b47aea28af..7f4de12d30 100644 --- a/types/account.go +++ b/types/account.go @@ -48,7 +48,7 @@ type AccountMapper interface { NewAccountWithAddress(ctx Context, addr Address) Account GetAccount(ctx Context, addr Address) Account SetAccount(ctx Context, acc Account) - IterateAccounts(ctx Context, process func(sdk.Account) (stop bool)) + IterateAccounts(ctx Context, process func(Account) (stop bool)) } // AccountDecoder unmarshals account bytes From f7587f784704e0919b67e4b0cd459d855d3c932c Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 27 Apr 2018 20:47:35 -0400 Subject: [PATCH 21/22] export refactor, lcd tests borken --- examples/basecoin/app/app.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index b8f5346cd6..f5122c1307 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -125,14 +125,19 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) // Custom logic for state export func (app *BasecoinApp) ExportAppStateJSON() (appState json.RawMessage, err error) { ctx := app.NewContext(true, abci.Header{}) + + // iterate to get the accounts accounts := []*types.GenesisAccount{} - app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { - accounts = append(accounts, &types.GenesisAccount{ - Address: a.GetAddress(), - Coins: a.GetCoins(), - }) + appendAccount := func(acc sdk.Account) (stop bool) { + account := &types.GenesisAccount{ + Address: acc.GetAddress(), + Coins: acc.GetCoins(), + } + accounts = append(accounts, account) return false - }) + } + app.accountMapper.IterateAccounts(ctx, appendAccount) + genState := types.GenesisState{ Accounts: accounts, } From 81ac153e7d95856c217189135b283bbf1d82c4fd Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Sat, 28 Apr 2018 02:50:54 +0200 Subject: [PATCH 22/22] Fix testcase --- examples/basecoin/app/app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index f5122c1307..d3eae85c04 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -59,7 +59,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // Define the accountMapper. app.accountMapper = auth.NewAccountMapper( cdc, - app.keyMain, // target store + app.keyAccount, // target store &types.AppAccount{}, // prototype )