From 0ef3259a399f1cda30c38486233f4474d2ef683e Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 1 Jun 2018 14:24:48 -0700 Subject: [PATCH 1/2] revised use of EndBlock/BeginBlock, basecoin updated for staking/slashing --- .github/PULL_REQUEST_TEMPLATE.md | 1 + CHANGELOG.md | 3 + cmd/gaia/app/app.go | 24 +++++- cmd/gaia/app/app_test.go | 27 +------ cmd/gaia/app/genesis.go | 2 +- examples/basecoin/app/app.go | 52 ++++++++++--- examples/basecoin/app/app_test.go | 86 +++++++++++++++------ examples/basecoin/types/account.go | 4 +- x/slashing/client/cli/query.go | 2 +- x/slashing/client/cli/tx.go | 2 +- x/slashing/keeper_test.go | 4 +- x/slashing/tick.go | 76 +++++++++--------- x/stake/handler.go | 26 +++++-- x/stake/{tick.go => inflation.go} | 25 ------ x/stake/{tick_test.go => inflation_test.go} | 0 x/stake/keeper.go | 4 +- 16 files changed, 194 insertions(+), 144 deletions(-) rename x/stake/{tick.go => inflation.go} (74%) rename x/stake/{tick_test.go => inflation_test.go} (100%) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 902469b41..3ddec8d33 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,3 +4,4 @@ * [ ] Updated all code comments where relevant * [ ] Wrote tests * [ ] Updated CHANGELOG.md +* [ ] Updated Basecoin / other examples diff --git a/CHANGELOG.md b/CHANGELOG.md index e23165799..86a344654 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,16 +4,19 @@ BREAKING CHANGES * [cli] rearranged commands under subcommands +* [stake] remove Tick and add EndBlocker FEATURES IMPROVEMENTS * bank module uses go-wire codec instead of 'encoding/json' * auth module uses go-wire codec instead of 'encoding/json' +* revised use of endblock and beginblock FIXES * [cli] fixed cli-bash tests * [ci] added cli-bash tests +* [basecoin] updated basecoin for stake and slashing ## 0.18.1 diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 4fdb6a6c9..f8e71be29 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -85,8 +85,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { // initialize BaseApp app.SetInitChainer(app.initChainer) - app.SetBeginBlocker(slashing.NewBeginBlocker(app.slashingKeeper)) - app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper)) + app.SetBeginBlocker(app.BeginBlocker) + app.SetEndBlocker(app.EndBlocker) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake, app.keySlashing) err := app.LoadLatestVersion(app.keyMain) @@ -110,6 +110,24 @@ func MakeCodec() *wire.Codec { return cdc } +// application updates every end block +func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { + tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper) + + return abci.ResponseBeginBlock{ + Tags: tags.ToKVPairs(), + } +} + +// application updates every end block +func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper) + + return abci.ResponseEndBlock{ + ValidatorUpdates: validatorUpdates, + } +} + // custom logic for gaia initialization func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { stateJSON := req.GenesisBytes @@ -134,7 +152,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci return abci.ResponseInitChain{} } -// export the state of gaia for a genesis f +// export the state of gaia for a genesis file func (app *GaiaApp) ExportAppStateJSON() (appState json.RawMessage, err error) { ctx := app.NewContext(true, abci.Header{}) diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 13ffdc33b..7ba975236 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -1,7 +1,6 @@ package app import ( - "encoding/json" "fmt" "os" "testing" @@ -139,30 +138,6 @@ func TestMsgs(t *testing.T) { } } -func setGenesisAccounts(gapp *GaiaApp, accs ...*auth.BaseAccount) error { - genaccs := make([]GenesisAccount, len(accs)) - for i, acc := range accs { - genaccs[i] = NewGenesisAccount(acc) - } - - genesisState := GenesisState{ - Accounts: genaccs, - StakeData: stake.DefaultGenesisState(), - } - - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - if err != nil { - return err - } - - // Initialize the chain - vals := []abci.Validator{} - gapp.InitChain(abci.RequestInitChain{vals, stateBytes}) - gapp.Commit() - - return nil -} - func TestGenesis(t *testing.T) { logger, dbs := loggerAndDB() gapp := NewGaiaApp(logger, dbs) @@ -178,7 +153,7 @@ func TestGenesis(t *testing.T) { } err = setGenesis(gapp, baseAcc) - assert.Nil(t, err) + require.Nil(t, err) // A checkTx context ctx := gapp.BaseApp.NewContext(true, abci.Header{}) diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 4f76d6073..813796c0d 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -95,7 +95,7 @@ func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( return nil, nil, tmtypes.GenesisValidator{}, errors.New("Must specify --name (validator moniker)") } - var addr sdk.Address + var addr sdk.Address var secret string addr, secret, err = server.GenerateSaveCoinKey(clientRoot, name, "1234567890", overwrite) if err != nil { diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index a0b1f86ad..f07901092 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/ibc" + "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" @@ -29,10 +30,11 @@ type BasecoinApp struct { cdc *wire.Codec // keys to access the substores - keyMain *sdk.KVStoreKey - keyAccount *sdk.KVStoreKey - keyIBC *sdk.KVStoreKey - keyStake *sdk.KVStoreKey + keyMain *sdk.KVStoreKey + keyAccount *sdk.KVStoreKey + keyIBC *sdk.KVStoreKey + keyStake *sdk.KVStoreKey + keySlashing *sdk.KVStoreKey // Manage getting and setting accounts accountMapper auth.AccountMapper @@ -40,6 +42,7 @@ type BasecoinApp struct { coinKeeper bank.Keeper ibcMapper ibc.Mapper stakeKeeper stake.Keeper + slashingKeeper slashing.Keeper } func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { @@ -49,12 +52,13 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // Create your application object. var app = &BasecoinApp{ - BaseApp: bam.NewBaseApp(appName, cdc, logger, db), - cdc: cdc, - keyMain: sdk.NewKVStoreKey("main"), - keyAccount: sdk.NewKVStoreKey("acc"), - keyIBC: sdk.NewKVStoreKey("ibc"), - keyStake: sdk.NewKVStoreKey("stake"), + BaseApp: bam.NewBaseApp(appName, cdc, logger, db), + cdc: cdc, + keyMain: sdk.NewKVStoreKey("main"), + keyAccount: sdk.NewKVStoreKey("acc"), + keyIBC: sdk.NewKVStoreKey("ibc"), + keyStake: sdk.NewKVStoreKey("stake"), + keySlashing: sdk.NewKVStoreKey("slashing"), } // Define the accountMapper. @@ -68,6 +72,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { 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)) + app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.RegisterCodespace(slashing.DefaultCodespace)) // register message routes app.Router(). @@ -78,8 +83,10 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // Initialize BaseApp. app.SetInitChainer(app.initChainer) - app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake) + app.SetBeginBlocker(app.BeginBlocker) + app.SetEndBlocker(app.EndBlocker) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) + app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake, app.keySlashing) err := app.LoadLatestVersion(app.keyMain) if err != nil { cmn.Exit(err.Error()) @@ -94,6 +101,7 @@ func MakeCodec() *wire.Codec { sdk.RegisterWire(cdc) // Register Msgs bank.RegisterWire(cdc) stake.RegisterWire(cdc) + slashing.RegisterWire(cdc) ibc.RegisterWire(cdc) // register custom AppAccount @@ -102,6 +110,24 @@ func MakeCodec() *wire.Codec { return cdc } +// application updates every end block +func (app *BasecoinApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { + tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper) + + return abci.ResponseBeginBlock{ + Tags: tags.ToKVPairs(), + } +} + +// application updates every end block +func (app *BasecoinApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper) + + return abci.ResponseEndBlock{ + ValidatorUpdates: validatorUpdates, + } +} + // Custom logic for basecoin initialization func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { stateJSON := req.GenesisBytes @@ -121,6 +147,10 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) } app.accountMapper.SetAccount(ctx, acc) } + + // load the initial stake information + stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) + return abci.ResponseInitChain{} } diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index e297288d3..4d445bda1 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -11,9 +11,11 @@ import ( "github.com/cosmos/cosmos-sdk/examples/basecoin/types" 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/x/bank" "github.com/cosmos/cosmos-sdk/x/ibc" + "github.com/cosmos/cosmos-sdk/x/stake" abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" @@ -85,28 +87,18 @@ var ( } ) -func loggerAndDB() (log.Logger, dbm.DB) { - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - db := dbm.NewMemDB() - return logger, db -} - -func newBasecoinApp() *BasecoinApp { - logger, db := loggerAndDB() - return NewBasecoinApp(logger, db) -} - -func setGenesisAccounts(bapp *BasecoinApp, accs ...auth.BaseAccount) error { +func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { genaccs := make([]*types.GenesisAccount, len(accs)) for i, acc := range accs { genaccs[i] = types.NewGenesisAccount(&types.AppAccount{acc, accName}) } genesisState := types.GenesisState{ - Accounts: genaccs, + Accounts: genaccs, + StakeData: stake.DefaultGenesisState(), } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + stateBytes, err := wire.MarshalJSONIndent(bapp.cdc, genesisState) if err != nil { return err } @@ -119,10 +111,46 @@ func setGenesisAccounts(bapp *BasecoinApp, accs ...auth.BaseAccount) error { return nil } +func loggerAndDB() (log.Logger, dbm.DB) { + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") + db := dbm.NewMemDB() + return logger, db +} + +func newBasecoinApp() *BasecoinApp { + logger, db := loggerAndDB() + return NewBasecoinApp(logger, db) +} + +//func setGenesisAccounts(bapp *BasecoinApp, accs ...auth.BaseAccount) error { +//genaccs := make([]*types.GenesisAccount, len(accs)) +//for i, acc := range accs { +//genaccs[i] = types.NewGenesisAccount(&types.AppAccount{acc, accName}) +//} + +//genesisState := types.GenesisState{ +//Accounts: genaccs, +//StakeData: stake.DefaultGenesisState(), +//} + +//stateBytes, err := json.MarshalIndent(genesisState, "", "\t") +//if err != nil { +//return err +//} + +//// Initialize the chain +//vals := []abci.Validator{} +//bapp.InitChain(abci.RequestInitChain{vals, stateBytes}) +//bapp.Commit() + +//return nil +//} + //_______________________________________________________________________ func TestMsgs(t *testing.T) { bapp := newBasecoinApp() + require.Nil(t, setGenesis(bapp)) msgs := []struct { msg sdk.Msg @@ -193,8 +221,8 @@ func TestGenesis(t *testing.T) { } acc := &types.AppAccount{baseAcc, "foobart"} - err = setGenesisAccounts(bapp, baseAcc) - assert.Nil(t, err) + err = setGenesis(bapp, baseAcc) + require.Nil(t, err) // A checkTx context ctx := bapp.BaseApp.NewContext(true, abci.Header{}) @@ -222,8 +250,9 @@ func TestMsgChangePubKey(t *testing.T) { } // Construct genesis state - err = setGenesisAccounts(bapp, baseAcc) - assert.Nil(t, err) + err = setGenesis(bapp, baseAcc) + require.Nil(t, err) + // A checkTx context (true) ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) @@ -276,8 +305,9 @@ func TestMsgSendWithAccounts(t *testing.T) { } // Construct genesis state - err = setGenesisAccounts(bapp, baseAcc) - assert.Nil(t, err) + err = setGenesis(bapp, baseAcc) + require.Nil(t, err) + // A checkTx context (true) ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) @@ -320,8 +350,9 @@ func TestMsgSendMultipleOut(t *testing.T) { Coins: genCoins, } - err = setGenesisAccounts(bapp, acc1, acc2) - assert.Nil(t, err) + // Construct genesis state + err = setGenesis(bapp, acc1, acc2) + require.Nil(t, err) // Simulate a Block SignCheckDeliver(t, bapp, sendMsg2, []int64{0}, true, priv1) @@ -353,7 +384,7 @@ func TestSengMsgMultipleInOut(t *testing.T) { Coins: genCoins, } - err = setGenesisAccounts(bapp, acc1, acc2, acc4) + err = setGenesis(bapp, acc1, acc2, acc4) assert.Nil(t, err) // CheckDeliver @@ -377,7 +408,11 @@ func TestMsgSendDependent(t *testing.T) { Coins: genCoins, } - err = setGenesisAccounts(bapp, acc1) + // Construct genesis state + err = setGenesis(bapp, acc1) + require.Nil(t, err) + + err = setGenesis(bapp, acc1) assert.Nil(t, err) // CheckDeliver @@ -438,8 +473,9 @@ func TestIBCMsgs(t *testing.T) { } acc1 := &types.AppAccount{baseAcc, "foobart"} - err := setGenesisAccounts(bapp, baseAcc) + err := setGenesis(bapp, baseAcc) assert.Nil(t, err) + // A checkTx context (true) ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) diff --git a/examples/basecoin/types/account.go b/examples/basecoin/types/account.go index 223e0b9eb..43a8e2e38 100644 --- a/examples/basecoin/types/account.go +++ b/examples/basecoin/types/account.go @@ -4,6 +4,7 @@ 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/x/stake" ) var _ auth.Account = (*AppAccount)(nil) @@ -41,7 +42,8 @@ func GetAccountDecoder(cdc *wire.Codec) auth.AccountDecoder { // State to Unmarshal type GenesisState struct { - Accounts []*GenesisAccount `json:"accounts"` + Accounts []*GenesisAccount `json:"accounts"` + StakeData stake.GenesisState `json:"stake"` } // GenesisAccount doesn't need pubkey or sequence diff --git a/x/slashing/client/cli/query.go b/x/slashing/client/cli/query.go index 42c02cab0..35f99d2fa 100644 --- a/x/slashing/client/cli/query.go +++ b/x/slashing/client/cli/query.go @@ -21,7 +21,7 @@ func GetCmdQuerySigningInfo(storeName string, cdc *wire.Codec) *cobra.Command { Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - pk, err := sdk.GetValPubKeyBech32Cosmos(args[0]) + pk, err := sdk.GetValPubKeyBech32(args[0]) if err != nil { return err } diff --git a/x/slashing/client/cli/tx.go b/x/slashing/client/cli/tx.go index 13a5cb666..19b1225ba 100644 --- a/x/slashing/client/cli/tx.go +++ b/x/slashing/client/cli/tx.go @@ -21,7 +21,7 @@ func GetCmdUnrevoke(cdc *wire.Codec) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - validatorAddr, err := sdk.GetAccAddressBech32Cosmos(args[0]) + validatorAddr, err := sdk.GetAccAddressBech32(args[0]) if err != nil { return err } diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index a38562773..25ae1686d 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -18,7 +18,7 @@ func TestHandleDoubleSign(t *testing.T) { addr, val, amt := addrs[0], pks[0], int64(100) got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, val, amt)) require.True(t, got.IsOK()) - sk.Tick(ctx) + stake.EndBlocker(ctx, sk) require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins - amt}}) require.Equal(t, sdk.NewRat(amt), sk.Validator(ctx, addr).GetPower()) @@ -41,7 +41,7 @@ func TestHandleAbsentValidator(t *testing.T) { slh := NewHandler(keeper) got := sh(ctx, newTestMsgCreateValidator(addr, val, amt)) require.True(t, got.IsOK()) - sk.Tick(ctx) + stake.EndBlocker(ctx, sk) require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins - amt}}) require.Equal(t, sdk.NewRat(amt), sk.Validator(ctx, addr).GetPower()) info, found := keeper.getValidatorSigningInfo(ctx, val.Address()) diff --git a/x/slashing/tick.go b/x/slashing/tick.go index 82f76d802..c77e96887 100644 --- a/x/slashing/tick.go +++ b/x/slashing/tick.go @@ -10,49 +10,45 @@ import ( tmtypes "github.com/tendermint/tendermint/types" ) -func NewBeginBlocker(sk Keeper) sdk.BeginBlocker { - return func(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - // Tag the height - heightBytes := make([]byte, 8) - binary.LittleEndian.PutUint64(heightBytes, uint64(req.Header.Height)) - tags := sdk.NewTags("height", heightBytes) +// slash begin blocker functionality +func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags sdk.Tags) { - // Deal with any equivocation evidence - for _, evidence := range req.ByzantineValidators { - var pk crypto.PubKey - sk.cdc.MustUnmarshalBinaryBare(evidence.PubKey, &pk) - switch string(evidence.Type) { - case tmtypes.DUPLICATE_VOTE: - sk.handleDoubleSign(ctx, evidence.Height, evidence.Time, pk) - default: - ctx.Logger().With("module", "x/slashing").Error(fmt.Sprintf("Ignored unknown evidence type: %s", string(evidence.Type))) - } - } + // Tag the height + heightBytes := make([]byte, 8) + binary.LittleEndian.PutUint64(heightBytes, uint64(req.Header.Height)) - // Figure out which validators were absent - absent := make(map[crypto.PubKey]struct{}) - for _, pubkey := range req.AbsentValidators { - var pk crypto.PubKey - sk.cdc.MustUnmarshalBinaryBare(pubkey, &pk) - absent[pk] = struct{}{} - } + // TODO Add some more tags so clients can track slashing events + tags = sdk.NewTags("height", heightBytes) - // Iterate over all the validators which *should* have signed this block - sk.stakeKeeper.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) (stop bool) { - pubkey := validator.GetPubKey() - present := true - if _, ok := absent[pubkey]; ok { - present = false - } - sk.handleValidatorSignature(ctx, pubkey, present) - return false - }) - - // Return the begin block response - // TODO Return something composable, so other modules can also have BeginBlockers - // TODO Add some more tags so clients can track slashing events - return abci.ResponseBeginBlock{ - Tags: tags.ToKVPairs(), + // Deal with any equivocation evidence + for _, evidence := range req.ByzantineValidators { + var pk crypto.PubKey + sk.cdc.MustUnmarshalBinaryBare(evidence.PubKey, &pk) + switch string(evidence.Type) { + case tmtypes.DUPLICATE_VOTE: + sk.handleDoubleSign(ctx, evidence.Height, evidence.Time, pk) + default: + ctx.Logger().With("module", "x/slashing").Error(fmt.Sprintf("Ignored unknown evidence type: %s", string(evidence.Type))) } } + + // Figure out which validators were absent + absent := make(map[crypto.PubKey]struct{}) + for _, pubkey := range req.AbsentValidators { + var pk crypto.PubKey + sk.cdc.MustUnmarshalBinaryBare(pubkey, &pk) + absent[pk] = struct{}{} + } + + // Iterate over all the validators which *should* have signed this block + sk.stakeKeeper.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) (stop bool) { + pubkey := validator.GetPubKey() + present := true + if _, ok := absent[pubkey]; ok { + present = false + } + sk.handleValidatorSignature(ctx, pubkey, present) + return false + }) + return } diff --git a/x/stake/handler.go b/x/stake/handler.go index b1c6a95b5..f366989b6 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -25,13 +25,27 @@ func NewHandler(k Keeper) sdk.Handler { } } -// NewEndBlocker generates sdk.EndBlocker -// Performs tick functionality -func NewEndBlocker(k Keeper) sdk.EndBlocker { - return func(ctx sdk.Context, req abci.RequestEndBlock) (res abci.ResponseEndBlock) { - res.ValidatorUpdates = k.Tick(ctx) - return +// Called every block, process inflation, update validator set +func EndBlocker(ctx sdk.Context, k Keeper) (ValidatorUpdates []abci.Validator) { + pool := k.GetPool(ctx) + + // Process Validator Provisions + blockTime := ctx.BlockHeader().Time // XXX assuming in seconds, confirm + if pool.InflationLastTime+blockTime >= 3600 { + pool.InflationLastTime = blockTime + pool = k.processProvisions(ctx) } + + // save the params + k.setPool(ctx, pool) + + // reset the intra-transaction counter + k.setIntraTxCounter(ctx, 0) + + // calculate validator set changes + ValidatorUpdates = k.getTendermintUpdates(ctx) + k.clearTendermintUpdates(ctx) + return } //_____________________________________________________________________ diff --git a/x/stake/tick.go b/x/stake/inflation.go similarity index 74% rename from x/stake/tick.go rename to x/stake/inflation.go index a8d945734..f385e9d82 100644 --- a/x/stake/tick.go +++ b/x/stake/inflation.go @@ -2,7 +2,6 @@ package stake import ( sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/abci/types" ) const ( @@ -12,30 +11,6 @@ const ( var hrsPerYrRat = sdk.NewRat(hrsPerYr) // as defined by a julian year of 365.25 days -// Tick - called at the end of every block -func (k Keeper) Tick(ctx sdk.Context) (change []abci.Validator) { - p := k.GetPool(ctx) - - // Process Validator Provisions - blockTime := ctx.BlockHeader().Time // XXX assuming in seconds, confirm - if p.InflationLastTime+blockTime >= 3600 { - p.InflationLastTime = blockTime - p = k.processProvisions(ctx) - } - - // save the params - k.setPool(ctx, p) - - // reset the intra-transaction counter - k.setIntraTxCounter(ctx, 0) - - // calculate validator set changes - change = k.getTendermintUpdates(ctx) - k.clearTendermintUpdates(ctx) - - return change -} - // process provisions for an hour period func (k Keeper) processProvisions(ctx sdk.Context) Pool { diff --git a/x/stake/tick_test.go b/x/stake/inflation_test.go similarity index 100% rename from x/stake/tick_test.go rename to x/stake/inflation_test.go diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 9fd902053..9f554c764 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -636,9 +636,9 @@ func (k Keeper) getPool(store sdk.KVStore) (pool Pool) { return } -func (k Keeper) setPool(ctx sdk.Context, p Pool) { +func (k Keeper) setPool(ctx sdk.Context, pool Pool) { store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshalBinary(p) + b := k.cdc.MustMarshalBinary(pool) store.Set(PoolKey, b) } From f2cf0bee14626211104b2f20371245b169e32a57 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 1 Jun 2018 23:45:30 +0200 Subject: [PATCH 2/2] Remove commented-out testcode --- examples/basecoin/app/app_test.go | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 4d445bda1..8054baab2 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -122,30 +122,6 @@ func newBasecoinApp() *BasecoinApp { return NewBasecoinApp(logger, db) } -//func setGenesisAccounts(bapp *BasecoinApp, accs ...auth.BaseAccount) error { -//genaccs := make([]*types.GenesisAccount, len(accs)) -//for i, acc := range accs { -//genaccs[i] = types.NewGenesisAccount(&types.AppAccount{acc, accName}) -//} - -//genesisState := types.GenesisState{ -//Accounts: genaccs, -//StakeData: stake.DefaultGenesisState(), -//} - -//stateBytes, err := json.MarshalIndent(genesisState, "", "\t") -//if err != nil { -//return err -//} - -//// Initialize the chain -//vals := []abci.Validator{} -//bapp.InitChain(abci.RequestInitChain{vals, stateBytes}) -//bapp.Commit() - -//return nil -//} - //_______________________________________________________________________ func TestMsgs(t *testing.T) {