diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 27ca7a1458..2ee79bd5bf 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -77,7 +77,7 @@ func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp { // initialize BaseApp app.SetTxDecoder(app.txDecoder) - app.SetInitChainer(app.initChainerFn(coolKeeper)) + app.SetInitChainer(app.initChainerFn(coolKeeper, powKeeper)) app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"]) app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"]) app.MountStoreWithDB(app.capKeyPowStore, sdk.StoreTypeIAVL, dbs["pow"]) @@ -151,7 +151,7 @@ func (app *DemocoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { } // custom logic for democoin initialization -func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper) sdk.InitChainer { +func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keeper) sdk.InitChainer { return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { stateJSON := req.AppStateBytes @@ -172,7 +172,13 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper) sdk.InitChainer { } // Application specific genesis handling - err = coolKeeper.InitGenesis(ctx, stateJSON) + err = coolKeeper.InitGenesis(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) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index 74b789bea0..1cc56bd6bf 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -260,6 +260,10 @@ func TestMineMsg(t *testing.T) { "cool": map[string]string{ "trend": "ice-cold", }, + "pow": map[string]uint64{ + "difficulty": 1, + "count": 0, + }, } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") require.Nil(t, err) @@ -279,11 +283,12 @@ func TestMineMsg(t *testing.T) { SignCheckDeliver(t, bapp, mineMsg1, 0, true) CheckBalance(t, bapp, "1pow") // Mine again and check for reward - /* - mineMsg2 := pow.GenerateMineMsg(addr1, 2, 2) - SignCheckDeliver(t, bapp, mineMsg2, 1, true) - CheckBalance(t, bapp, "2pow") - */ + mineMsg2 := pow.GenerateMineMsg(addr1, 2, 3) + SignCheckDeliver(t, bapp, mineMsg2, 1, true) + CheckBalance(t, bapp, "2pow") + // Mine again - should be invalid + SignCheckDeliver(t, bapp, mineMsg2, 1, false) + CheckBalance(t, bapp, "2pow") } diff --git a/examples/democoin/types/account.go b/examples/democoin/types/account.go index f34113fc65..ce2d6da348 100644 --- a/examples/democoin/types/account.go +++ b/examples/democoin/types/account.go @@ -4,6 +4,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" + + "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool" + "github.com/cosmos/cosmos-sdk/examples/democoin/x/pow" ) var _ sdk.Account = (*AppAccount)(nil) @@ -41,7 +44,9 @@ func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { // State to Unmarshal type GenesisState struct { - Accounts []*GenesisAccount `json:"accounts"` + Accounts []*GenesisAccount `json:"accounts"` + PowGenesis pow.PowGenesis `json:"pow"` + CoolGenesis cool.CoolGenesis `json:"cool"` } // GenesisAccount doesn't need pubkey or sequence diff --git a/examples/democoin/x/cool/keeper.go b/examples/democoin/x/cool/keeper.go index 1bf342fdc2..0a4fc81e1c 100644 --- a/examples/democoin/x/cool/keeper.go +++ b/examples/democoin/x/cool/keeper.go @@ -1,17 +1,10 @@ package cool import ( - "encoding/json" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank" ) -// Cool genesis state, containing the genesis trend -type GenesisState struct { - trend string -} - // Keeper - handlers sets/gets of custom variables for your module type Keeper struct { ck bank.CoinKeeper @@ -49,11 +42,7 @@ func (k Keeper) CheckTrend(ctx sdk.Context, guessedTrend string) bool { } // InitGenesis - store the genesis trend -func (k Keeper) InitGenesis(ctx sdk.Context, data json.RawMessage) error { - var state GenesisState - if err := json.Unmarshal(data, &state); err != nil { - return err - } - k.setTrend(ctx, state.trend) +func (k Keeper) InitGenesis(ctx sdk.Context, data CoolGenesis) error { + k.setTrend(ctx, data.Trend) return nil } diff --git a/examples/democoin/x/cool/types.go b/examples/democoin/x/cool/types.go index a3fa6ca48e..e24c363ace 100644 --- a/examples/democoin/x/cool/types.go +++ b/examples/democoin/x/cool/types.go @@ -15,6 +15,11 @@ type SetTrendMsg struct { Cool string } +// Genesis state - specify genesis trend +type CoolGenesis struct { + Trend string `json:"trend"` +} + // New cool message func NewSetTrendMsg(sender sdk.Address, cool string) SetTrendMsg { return SetTrendMsg{ diff --git a/examples/democoin/x/pow/handler.go b/examples/democoin/x/pow/handler.go index 82c8a19c35..d1a691139d 100644 --- a/examples/democoin/x/pow/handler.go +++ b/examples/democoin/x/pow/handler.go @@ -25,9 +25,13 @@ func handleMineMsg(ctx sdk.Context, pk Keeper, msg MineMsg) sdk.Result { return err.Result() } - if ctx.IsCheckTx() { - return sdk.Result{} // TODO - } + // commented for now, makes testing difficult + // TODO figure out a better test method that allows early CheckTx return + /* + if ctx.IsCheckTx() { + return sdk.Result{} // TODO + } + */ err = pk.ApplyValid(ctx, msg.Sender, newDiff, newCount) if err != nil { diff --git a/examples/democoin/x/pow/handler_test.go b/examples/democoin/x/pow/handler_test.go index f9db01d0c0..2de2853713 100644 --- a/examples/democoin/x/pow/handler_test.go +++ b/examples/democoin/x/pow/handler_test.go @@ -26,6 +26,10 @@ func TestPowHandler(t *testing.T) { addr := sdk.Address([]byte("sender")) count := uint64(1) difficulty := uint64(2) + + err := keeper.InitGenesis(ctx, PowGenesis{uint64(1), uint64(0)}) + assert.Nil(t, err) + nonce, proof := mine(addr, count, difficulty) msg := NewMineMsg(addr, difficulty, count, nonce, proof) diff --git a/examples/democoin/x/pow/keeper.go b/examples/democoin/x/pow/keeper.go index dc4494c698..73558632c4 100644 --- a/examples/democoin/x/pow/keeper.go +++ b/examples/democoin/x/pow/keeper.go @@ -14,8 +14,10 @@ type PowConfig struct { Reward int64 } -func NewPowConfig(denomination string, reward int64) PowConfig { - return PowConfig{denomination, reward} +// genesis info must specify starting difficulty and starting count +type PowGenesis struct { + Difficulty uint64 `json:"difficulty"` + Count uint64 `json:"count"` } type Keeper struct { @@ -24,19 +26,27 @@ type Keeper struct { ck bank.CoinKeeper } +func NewPowConfig(denomination string, reward int64) PowConfig { + return PowConfig{denomination, reward} +} + func NewKeeper(key sdk.StoreKey, config PowConfig, ck bank.CoinKeeper) Keeper { return Keeper{key, config, ck} } +func (pk Keeper) InitGenesis(ctx sdk.Context, genesis PowGenesis) error { + pk.SetLastDifficulty(ctx, genesis.Difficulty) + pk.SetLastCount(ctx, genesis.Count) + return nil +} + var lastDifficultyKey = []byte("lastDifficultyKey") func (pk Keeper) GetLastDifficulty(ctx sdk.Context) (uint64, error) { store := ctx.KVStore(pk.key) stored := store.Get(lastDifficultyKey) if stored == nil { - // return the default difficulty of 1 if not set - // this works OK for this module, but a way to initalize the store (a "genesis block" for the module) might be better in general - return uint64(1), nil + panic("no stored difficulty") } else { return strconv.ParseUint(string(stored), 0, 64) } @@ -53,7 +63,7 @@ func (pk Keeper) GetLastCount(ctx sdk.Context) (uint64, error) { store := ctx.KVStore(pk.key) stored := store.Get(countKey) if stored == nil { - return uint64(0), nil + panic("no stored count") } else { return strconv.ParseUint(string(stored), 0, 64) } diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index e9ec9c6d34..6e0d526496 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -34,6 +34,9 @@ func TestPowKeeperGetSet(t *testing.T) { ck := bank.NewCoinKeeper(am) keeper := NewKeeper(capKey, config, ck) + err := keeper.InitGenesis(ctx, PowGenesis{uint64(1), uint64(0)}) + assert.Nil(t, err) + res, err := keeper.GetLastDifficulty(ctx) assert.Nil(t, err) assert.Equal(t, res, uint64(1))