feat!: remove legacy handler (#9650)

<!--
The default pull request template is for types feat, fix, or refactor.
For other templates, add one of the following parameters to the url:
- template=docs.md
- template=other.md
-->

## Description

Closes: #7517 
ref: [comment](https://github.com/cosmos/cosmos-sdk/pull/9594#issuecomment-872859821)

<!-- Add a description of the changes that this PR introduces and the files that
are the most critical to review. -->

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [x] added `!` to the type prefix if API or client breaking change
- [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
- [x] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules)
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing)
- [x] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
This commit is contained in:
MD Aleem 2021-07-19 20:19:42 +05:30 committed by GitHub
parent 481aa2e589
commit 48cb9eab8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 137 additions and 2329 deletions

View File

@ -58,6 +58,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [\#9594](https://github.com/cosmos/cosmos-sdk/pull/9594) `types/rest` package moved to `testutil/rest`. * [\#9594](https://github.com/cosmos/cosmos-sdk/pull/9594) `types/rest` package moved to `testutil/rest`.
* [\#9432](https://github.com/cosmos/cosmos-sdk/pull/9432) `ConsensusParamsKeyTable` moved from `params/keeper` to `params/types` * [\#9432](https://github.com/cosmos/cosmos-sdk/pull/9432) `ConsensusParamsKeyTable` moved from `params/keeper` to `params/types`
* [\#9576](https://github.com/cosmos/cosmos-sdk/pull/9576) Add debug error message to `sdkerrors.QueryResult` when enabled * [\#9576](https://github.com/cosmos/cosmos-sdk/pull/9576) Add debug error message to `sdkerrors.QueryResult` when enabled
* [\#9650](https://github.com/cosmos/cosmos-sdk/pull/9650) Removed deprecated message handler implementation from the SDK modules.
### Client Breaking Changes ### Client Breaking Changes

View File

@ -111,8 +111,10 @@ func (AppModule) Name() string {
// RegisterInvariants performs a no-op. // RegisterInvariants performs a no-op.
func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// Route returns the message routing key for the auth module. // Deprecated: Route returns the message routing key for the auth module.
func (AppModule) Route() sdk.Route { return sdk.Route{} } func (AppModule) Route() sdk.Route {
return sdk.Route{}
}
// QuerierRoute returns the auth module's querier route name. // QuerierRoute returns the auth module's querier route name.
func (AppModule) QuerierRoute() string { func (AppModule) QuerierRoute() string {

View File

@ -1,26 +0,0 @@
package vesting
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/keeper"
"github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
)
// NewHandler returns a handler for x/auth message types.
func NewHandler(ak keeper.AccountKeeper, bk types.BankKeeper) sdk.Handler {
msgServer := NewMsgServerImpl(ak, bk)
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
case *types.MsgCreateVestingAccount:
res, err := msgServer.CreateVestingAccount(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
}
}
}

View File

@ -1,97 +0,0 @@
package vesting_test
import (
"testing"
"github.com/stretchr/testify/suite"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
"github.com/cosmos/cosmos-sdk/x/bank/testutil"
)
type HandlerTestSuite struct {
suite.Suite
handler sdk.Handler
app *simapp.SimApp
}
func (suite *HandlerTestSuite) SetupTest() {
checkTx := false
app := simapp.Setup(checkTx)
suite.handler = vesting.NewHandler(app.AccountKeeper, app.BankKeeper)
suite.app = app
}
func (suite *HandlerTestSuite) TestMsgCreateVestingAccount() {
ctx := suite.app.BaseApp.NewContext(false, tmproto.Header{Height: suite.app.LastBlockHeight() + 1})
balances := sdk.NewCoins(sdk.NewInt64Coin("test", 1000))
addr1 := sdk.AccAddress([]byte("addr1_______________"))
addr2 := sdk.AccAddress([]byte("addr2_______________"))
addr3 := sdk.AccAddress([]byte("addr3_______________"))
acc1 := suite.app.AccountKeeper.NewAccountWithAddress(ctx, addr1)
suite.app.AccountKeeper.SetAccount(ctx, acc1)
suite.Require().NoError(testutil.FundAccount(suite.app.BankKeeper, ctx, addr1, balances))
testCases := []struct {
name string
msg *types.MsgCreateVestingAccount
expectErr bool
}{
{
name: "create delayed vesting account",
msg: types.NewMsgCreateVestingAccount(addr1, addr2, sdk.NewCoins(sdk.NewInt64Coin("test", 100)), ctx.BlockTime().Unix()+10000, true),
expectErr: false,
},
{
name: "create continuous vesting account",
msg: types.NewMsgCreateVestingAccount(addr1, addr3, sdk.NewCoins(sdk.NewInt64Coin("test", 100)), ctx.BlockTime().Unix()+10000, false),
expectErr: false,
},
{
name: "continuous vesting account already exists",
msg: types.NewMsgCreateVestingAccount(addr1, addr3, sdk.NewCoins(sdk.NewInt64Coin("test", 100)), ctx.BlockTime().Unix()+10000, false),
expectErr: true,
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
res, err := suite.handler(ctx, tc.msg)
if tc.expectErr {
suite.Require().Error(err)
} else {
suite.Require().NoError(err)
suite.Require().NotNil(res)
toAddr, err := sdk.AccAddressFromBech32(tc.msg.ToAddress)
suite.Require().NoError(err)
accI := suite.app.AccountKeeper.GetAccount(ctx, toAddr)
suite.Require().NotNil(accI)
if tc.msg.Delayed {
acc, ok := accI.(*types.DelayedVestingAccount)
suite.Require().True(ok)
suite.Require().Equal(tc.msg.Amount, acc.GetVestingCoins(ctx.BlockTime()))
} else {
acc, ok := accI.(*types.ContinuousVestingAccount)
suite.Require().True(ok)
suite.Require().Equal(tc.msg.Amount, acc.GetVestingCoins(ctx.BlockTime()))
}
}
})
}
}
func TestHandlerTestSuite(t *testing.T) {
suite.Run(t, new(HandlerTestSuite))
}

View File

@ -92,9 +92,9 @@ func NewAppModule(ak keeper.AccountKeeper, bk types.BankKeeper) AppModule {
// RegisterInvariants performs a no-op; there are no invariants to enforce. // RegisterInvariants performs a no-op; there are no invariants to enforce.
func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// Route returns the module's message router and handler. // Deprecated: Route returns the module's message router and handler.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(types.RouterKey, NewHandler(am.accountKeeper, am.bankKeeper)) return sdk.Route{}
} }
// QuerierRoute returns an empty string as the module contains no query // QuerierRoute returns an empty string as the module contains no query

View File

@ -117,9 +117,9 @@ func (AppModule) Name() string {
// RegisterInvariants does nothing, there are no invariants to enforce // RegisterInvariants does nothing, there are no invariants to enforce
func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// Route returns the message routing key for the staking module. // Deprecated: Route returns the message routing key for the authz module.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(authz.RouterKey, nil) return sdk.Route{}
} }
func (am AppModule) NewHandler() sdk.Handler { func (am AppModule) NewHandler() sdk.Handler {

View File

@ -1,30 +0,0 @@
package bank
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/cosmos/cosmos-sdk/x/bank/types"
)
// NewHandler returns a handler for "bank" type messages.
func NewHandler(k keeper.Keeper) sdk.Handler {
msgServer := keeper.NewMsgServerImpl(k)
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
case *types.MsgSend:
res, err := msgServer.Send(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgMultiSend:
res, err := msgServer.MultiSend(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized bank message type: %T", msg)
}
}
}

View File

@ -1,88 +0,0 @@
package bank_test
import (
"strings"
"testing"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/cosmos/cosmos-sdk/x/bank/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
func TestInvalidMsg(t *testing.T) {
h := bank.NewHandler(nil)
res, err := h(sdk.NewContext(nil, tmproto.Header{}, false, nil), testdata.NewTestMsg())
require.Error(t, err)
require.Nil(t, res)
_, _, log := sdkerrors.ABCIInfo(err, false)
require.True(t, strings.Contains(log, "unrecognized bank message type"))
}
// A module account cannot be the recipient of bank sends unless it has been marked as such
func TestSendToModuleAccount(t *testing.T) {
priv1 := secp256k1.GenPrivKey()
addr1 := sdk.AccAddress(priv1.PubKey().Address())
moduleAccAddr := authtypes.NewModuleAddress(stakingtypes.BondedPoolName)
coins := sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}
tests := []struct {
name string
expectedError error
msg *types.MsgSend
}{
{
name: "not allowed module account",
msg: types.NewMsgSend(addr1, moduleAccAddr, coins),
expectedError: sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", moduleAccAddr),
},
{
name: "allowed module account",
msg: types.NewMsgSend(addr1, authtypes.NewModuleAddress(stakingtypes.ModuleName), coins),
expectedError: nil,
},
}
acc1 := &authtypes.BaseAccount{
Address: addr1.String(),
}
accs := authtypes.GenesisAccounts{acc1}
balances := []types.Balance{
{
Address: addr1.String(),
Coins: coins,
},
}
app := simapp.SetupWithGenesisAccounts(accs, balances...)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
app.BankKeeper = bankkeeper.NewBaseKeeper(
app.AppCodec(), app.GetKey(types.StoreKey), app.AccountKeeper, app.GetSubspace(types.ModuleName), map[string]bool{
moduleAccAddr.String(): true,
},
)
handler := bank.NewHandler(app.BankKeeper)
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
_, err := handler(ctx, tc.msg)
if tc.expectedError != nil {
require.EqualError(t, err, tc.expectedError.Error())
} else {
require.NoError(t, err)
}
})
}
}

View File

@ -123,9 +123,9 @@ func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
keeper.RegisterInvariants(ir, am.keeper) keeper.RegisterInvariants(ir, am.keeper)
} }
// Route returns the message routing key for the bank module. // Deprecated: Route returns the message routing key for the bank module.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) return sdk.Route{}
} }
// QuerierRoute returns the bank module's querier route name. // QuerierRoute returns the bank module's querier route name.

View File

@ -103,8 +103,10 @@ func (am AppModule) Name() string {
return am.AppModuleBasic.Name() return am.AppModuleBasic.Name()
} }
// Route returns the capability module's message routing key. // Deprecated: Route returns the capability module's message routing key.
func (AppModule) Route() sdk.Route { return sdk.Route{} } func (AppModule) Route() sdk.Route {
return sdk.Route{}
}
// QuerierRoute returns the capability module's query routing key. // QuerierRoute returns the capability module's query routing key.
func (AppModule) QuerierRoute() string { return "" } func (AppModule) QuerierRoute() string { return "" }

View File

@ -1,25 +0,0 @@
package crisis
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/crisis/types"
)
// RouterKey
const RouterKey = types.ModuleName
func NewHandler(k types.MsgServer) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
case *types.MsgVerifyInvariant:
res, err := k.VerifyInvariant(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized crisis message type: %T", msg)
}
}
}

View File

@ -1,116 +0,0 @@
package crisis_test
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/crisis"
"github.com/cosmos/cosmos-sdk/x/crisis/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
var (
testModuleName = "dummy"
dummyRouteWhichPasses = types.NewInvarRoute(testModuleName, "which-passes", func(_ sdk.Context) (string, bool) { return "", false })
dummyRouteWhichFails = types.NewInvarRoute(testModuleName, "which-fails", func(_ sdk.Context) (string, bool) { return "whoops", true })
)
func createTestApp() (*simapp.SimApp, sdk.Context, []sdk.AccAddress) {
app := simapp.Setup(false)
ctx := app.NewContext(false, tmproto.Header{})
constantFee := sdk.NewInt64Coin(sdk.DefaultBondDenom, 10)
app.CrisisKeeper.SetConstantFee(ctx, constantFee)
app.StakingKeeper.SetParams(ctx, stakingtypes.DefaultParams())
app.CrisisKeeper.RegisterRoute(testModuleName, dummyRouteWhichPasses.Route, dummyRouteWhichPasses.Invar)
app.CrisisKeeper.RegisterRoute(testModuleName, dummyRouteWhichFails.Route, dummyRouteWhichFails.Invar)
feePool := distrtypes.InitialFeePool()
feePool.CommunityPool = sdk.NewDecCoinsFromCoins(sdk.NewCoins(constantFee)...)
app.DistrKeeper.SetFeePool(ctx, feePool)
addrs := simapp.AddTestAddrs(app, ctx, 1, sdk.NewInt(10000))
return app, ctx, addrs
}
func TestHandleMsgVerifyInvariant(t *testing.T) {
app, ctx, addrs := createTestApp()
sender := addrs[0]
cases := []struct {
name string
msg sdk.Msg
expectedResult string
}{
{"bad invariant route", types.NewMsgVerifyInvariant(sender, testModuleName, "route-that-doesnt-exist"), "fail"},
{"invariant broken", types.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichFails.Route), "panic"},
{"invariant passing", types.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichPasses.Route), "pass"},
{"invalid msg", testdata.NewTestMsg(), "fail"},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
h := crisis.NewHandler(app.CrisisKeeper)
switch tc.expectedResult {
case "fail":
res, err := h(ctx, tc.msg)
require.Error(t, err)
require.Nil(t, res)
case "pass":
res, err := h(ctx, tc.msg)
require.NoError(t, err)
require.NotNil(t, res)
case "panic":
require.Panics(t, func() {
h(ctx, tc.msg) // nolint:errcheck
})
}
})
}
}
func TestHandleMsgVerifyInvariantWithNotEnoughSenderCoins(t *testing.T) {
app, ctx, addrs := createTestApp()
sender := addrs[0]
coin := app.BankKeeper.GetAllBalances(ctx, sender)[0]
excessCoins := sdk.NewCoin(coin.Denom, coin.Amount.AddRaw(1))
app.CrisisKeeper.SetConstantFee(ctx, excessCoins)
h := crisis.NewHandler(app.CrisisKeeper)
msg := types.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichPasses.Route)
res, err := h(ctx, msg)
require.Error(t, err)
require.Nil(t, res)
}
func TestHandleMsgVerifyInvariantWithInvariantBrokenAndNotEnoughPoolCoins(t *testing.T) {
app, ctx, addrs := createTestApp()
sender := addrs[0]
// set the community pool to empty
feePool := app.DistrKeeper.GetFeePool(ctx)
feePool.CommunityPool = sdk.DecCoins{}
app.DistrKeeper.SetFeePool(ctx, feePool)
h := crisis.NewHandler(app.CrisisKeeper)
msg := types.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichFails.Route)
var res *sdk.Result
require.Panics(t, func() {
res, _ = h(ctx, msg)
}, fmt.Sprintf("%v", res))
}

View File

@ -119,9 +119,9 @@ func (AppModule) Name() string {
// RegisterInvariants performs a no-op. // RegisterInvariants performs a no-op.
func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// Route returns the message routing key for the crisis module. // Deprecated: Route returns the message routing key for the crisis module.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(RouterKey, NewHandler(*am.keeper)) return sdk.Route{}
} }
// QuerierRoute returns no querier route. // QuerierRoute returns no querier route.

View File

@ -8,35 +8,6 @@ import (
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
) )
func NewHandler(k keeper.Keeper) sdk.Handler {
msgServer := keeper.NewMsgServerImpl(k)
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
case *types.MsgSetWithdrawAddress:
res, err := msgServer.SetWithdrawAddress(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgWithdrawDelegatorReward:
res, err := msgServer.WithdrawDelegatorReward(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgWithdrawValidatorCommission:
res, err := msgServer.WithdrawValidatorCommission(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgFundCommunityPool:
res, err := msgServer.FundCommunityPool(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized distribution message type: %T", msg)
}
}
}
func NewCommunityPoolSpendProposalHandler(k keeper.Keeper) govtypes.Handler { func NewCommunityPoolSpendProposalHandler(k keeper.Keeper) govtypes.Handler {
return func(ctx sdk.Context, content govtypes.Content) error { return func(ctx sdk.Context, content govtypes.Content) error {
switch c := content.(type) { switch c := content.(type) {

View File

@ -121,9 +121,9 @@ func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
keeper.RegisterInvariants(ir, am.keeper) keeper.RegisterInvariants(ir, am.keeper)
} }
// Route returns the message routing key for the distribution module. // Deprecated: Route returns the message routing key for the distribution module.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) return sdk.Route{}
} }
// QuerierRoute returns the distribution module's querier route name. // QuerierRoute returns the distribution module's querier route name.

View File

@ -1,26 +0,0 @@
package evidence
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/evidence/keeper"
"github.com/cosmos/cosmos-sdk/x/evidence/types"
)
// NewHandler returns a handler for evidence messages.
func NewHandler(k keeper.Keeper) sdk.Handler {
msgServer := keeper.NewMsgServerImpl(k)
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
case *types.MsgSubmitEvidence:
res, err := msgServer.SubmitEvidence(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
}
}
}

View File

@ -1,127 +0,0 @@
package evidence_test
import (
"fmt"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/evidence"
"github.com/cosmos/cosmos-sdk/x/evidence/exported"
"github.com/cosmos/cosmos-sdk/x/evidence/keeper"
"github.com/cosmos/cosmos-sdk/x/evidence/types"
)
type HandlerTestSuite struct {
suite.Suite
handler sdk.Handler
app *simapp.SimApp
}
func testMsgSubmitEvidence(r *require.Assertions, e exported.Evidence, s sdk.AccAddress) exported.MsgSubmitEvidenceI {
msg, err := types.NewMsgSubmitEvidence(s, e)
r.NoError(err)
return msg
}
func testEquivocationHandler(k interface{}) types.Handler {
return func(ctx sdk.Context, e exported.Evidence) error {
if err := e.ValidateBasic(); err != nil {
return err
}
ee, ok := e.(*types.Equivocation)
if !ok {
return fmt.Errorf("unexpected evidence type: %T", e)
}
if ee.Height%2 == 0 {
return fmt.Errorf("unexpected even evidence height: %d", ee.Height)
}
return nil
}
}
func (suite *HandlerTestSuite) SetupTest() {
checkTx := false
app := simapp.Setup(checkTx)
// recreate keeper in order to use custom testing types
evidenceKeeper := keeper.NewKeeper(
app.AppCodec(), app.GetKey(types.StoreKey), app.StakingKeeper, app.SlashingKeeper,
)
router := types.NewRouter()
router = router.AddRoute(types.RouteEquivocation, testEquivocationHandler(*evidenceKeeper))
evidenceKeeper.SetRouter(router)
app.EvidenceKeeper = *evidenceKeeper
suite.handler = evidence.NewHandler(*evidenceKeeper)
suite.app = app
}
func (suite *HandlerTestSuite) TestMsgSubmitEvidence() {
pk := ed25519.GenPrivKey()
s := sdk.AccAddress("test________________")
testCases := []struct {
msg sdk.Msg
expectErr bool
}{
{
testMsgSubmitEvidence(
suite.Require(),
&types.Equivocation{
Height: 11,
Time: time.Now().UTC(),
Power: 100,
ConsensusAddress: pk.PubKey().Address().String(),
},
s,
),
false,
},
{
testMsgSubmitEvidence(
suite.Require(),
&types.Equivocation{
Height: 10,
Time: time.Now().UTC(),
Power: 100,
ConsensusAddress: pk.PubKey().Address().String(),
},
s,
),
true,
},
}
for i, tc := range testCases {
ctx := suite.app.BaseApp.NewContext(false, tmproto.Header{Height: suite.app.LastBlockHeight() + 1})
res, err := suite.handler(ctx, tc.msg)
if tc.expectErr {
suite.Require().Error(err, "expected error; tc #%d", i)
} else {
suite.Require().NoError(err, "unexpected error; tc #%d", i)
suite.Require().NotNil(res, "expected non-nil result; tc #%d", i)
msg := tc.msg.(exported.MsgSubmitEvidenceI)
var resultData types.MsgSubmitEvidenceResponse
suite.app.AppCodec().Unmarshal(res.Data, &resultData)
suite.Require().Equal(msg.GetEvidence().Hash().Bytes(), resultData.Hash, "invalid hash; tc #%d", i)
}
}
}
func TestHandlerTestSuite(t *testing.T) {
suite.Run(t, new(HandlerTestSuite))
}

View File

@ -19,7 +19,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/evidence/exported"
"github.com/cosmos/cosmos-sdk/x/evidence/keeper" "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
"github.com/cosmos/cosmos-sdk/x/evidence/types" "github.com/cosmos/cosmos-sdk/x/evidence/types"
"github.com/cosmos/cosmos-sdk/x/staking"
) )
var ( var (
@ -77,7 +76,6 @@ type KeeperTestSuite struct {
app *simapp.SimApp app *simapp.SimApp
queryClient types.QueryClient queryClient types.QueryClient
stakingHdl sdk.Handler
} }
func (suite *KeeperTestSuite) SetupTest() { func (suite *KeeperTestSuite) SetupTest() {
@ -106,7 +104,6 @@ func (suite *KeeperTestSuite) SetupTest() {
queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, app.InterfaceRegistry()) queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, app.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, app.EvidenceKeeper) types.RegisterQueryServer(queryHelper, app.EvidenceKeeper)
suite.queryClient = types.NewQueryClient(queryHelper) suite.queryClient = types.NewQueryClient(queryHelper)
suite.stakingHdl = staking.NewHandler(app.StakingKeeper)
} }
func (suite *KeeperTestSuite) populateEvidence(ctx sdk.Context, numEvidence int) []exported.Evidence { func (suite *KeeperTestSuite) populateEvidence(ctx sdk.Context, numEvidence int) []exported.Evidence {

View File

@ -126,9 +126,9 @@ func (am AppModule) Name() string {
return am.AppModuleBasic.Name() return am.AppModuleBasic.Name()
} }
// Route returns the evidence module's message routing key. // Deprecated: Route returns the evidence module's message routing key.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) return sdk.Route{}
} }
// QuerierRoute returns the evidence module's query routing key. // QuerierRoute returns the evidence module's query routing key.

View File

@ -132,9 +132,9 @@ func (AppModule) Name() string {
// RegisterInvariants registers the feegrant module invariants. // RegisterInvariants registers the feegrant module invariants.
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {}
// Route returns the message routing key for the feegrant module. // Deprecated: Route returns the message routing key for the feegrant module.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(feegrant.RouterKey, nil) return sdk.Route{}
} }
// NewHandler returns an sdk.Handler for the feegrant module. // NewHandler returns an sdk.Handler for the feegrant module.

View File

@ -4,7 +4,6 @@ import (
"testing" "testing"
"time" "time"
"github.com/golang/protobuf/proto"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
@ -12,8 +11,11 @@ import (
"github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/gov/keeper"
"github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
) )
func TestTickExpiredDepositPeriod(t *testing.T) { func TestTickExpiredDepositPeriod(t *testing.T) {
@ -24,7 +26,7 @@ func TestTickExpiredDepositPeriod(t *testing.T) {
header := tmproto.Header{Height: app.LastBlockHeight() + 1} header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header}) app.BeginBlock(abci.RequestBeginBlock{Header: header})
govHandler := gov.NewHandler(app.GovKeeper) govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid()) require.False(t, inactiveQueue.Valid())
@ -37,7 +39,8 @@ func TestTickExpiredDepositPeriod(t *testing.T) {
) )
require.NoError(t, err) require.NoError(t, err)
res, err := govHandler(ctx, newProposalMsg) wrapCtx := sdk.WrapSDKContext(ctx)
res, err := govMsgSvr.SubmitProposal(wrapCtx, newProposalMsg)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, res) require.NotNil(t, res)
@ -76,7 +79,7 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
header := tmproto.Header{Height: app.LastBlockHeight() + 1} header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header}) app.BeginBlock(abci.RequestBeginBlock{Header: header})
govHandler := gov.NewHandler(app.GovKeeper) govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid()) require.False(t, inactiveQueue.Valid())
@ -89,7 +92,7 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
) )
require.NoError(t, err) require.NoError(t, err)
res, err := govHandler(ctx, newProposalMsg) res, err := govMsgSvr.SubmitProposal(sdk.WrapSDKContext(ctx), newProposalMsg)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, res) require.NotNil(t, res)
@ -112,7 +115,7 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
) )
require.NoError(t, err) require.NoError(t, err)
res, err = govHandler(ctx, newProposalMsg2) res, err = govMsgSvr.SubmitProposal(sdk.WrapSDKContext(ctx), newProposalMsg2)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, res) require.NotNil(t, res)
@ -153,7 +156,7 @@ func TestTickPassedDepositPeriod(t *testing.T) {
header := tmproto.Header{Height: app.LastBlockHeight() + 1} header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header}) app.BeginBlock(abci.RequestBeginBlock{Header: header})
govHandler := gov.NewHandler(app.GovKeeper) govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid()) require.False(t, inactiveQueue.Valid())
@ -169,15 +172,11 @@ func TestTickPassedDepositPeriod(t *testing.T) {
) )
require.NoError(t, err) require.NoError(t, err)
res, err := govHandler(ctx, newProposalMsg) res, err := govMsgSvr.SubmitProposal(sdk.WrapSDKContext(ctx), newProposalMsg)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, res) require.NotNil(t, res)
var proposalData types.MsgSubmitProposalResponse proposalID := res.ProposalId
err = proto.Unmarshal(res.Data, &proposalData)
require.NoError(t, err)
proposalID := proposalData.ProposalId
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid()) require.False(t, inactiveQueue.Valid())
@ -193,9 +192,9 @@ func TestTickPassedDepositPeriod(t *testing.T) {
newDepositMsg := types.NewMsgDeposit(addrs[1], proposalID, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)}) newDepositMsg := types.NewMsgDeposit(addrs[1], proposalID, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)})
res, err = govHandler(ctx, newDepositMsg) res1, err := govMsgSvr.Deposit(sdk.WrapSDKContext(ctx), newDepositMsg)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, res) require.NotNil(t, res1)
activeQueue = app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) activeQueue = app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, activeQueue.Valid()) require.False(t, activeQueue.Valid())
@ -212,7 +211,7 @@ func TestTickPassedVotingPeriod(t *testing.T) {
header := tmproto.Header{Height: app.LastBlockHeight() + 1} header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header}) app.BeginBlock(abci.RequestBeginBlock{Header: header})
govHandler := gov.NewHandler(app.GovKeeper) govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid()) require.False(t, inactiveQueue.Valid())
@ -225,15 +224,13 @@ func TestTickPassedVotingPeriod(t *testing.T) {
newProposalMsg, err := types.NewMsgSubmitProposal(TestProposal, proposalCoins, addrs[0]) newProposalMsg, err := types.NewMsgSubmitProposal(TestProposal, proposalCoins, addrs[0])
require.NoError(t, err) require.NoError(t, err)
res, err := govHandler(ctx, newProposalMsg) wrapCtx := sdk.WrapSDKContext(ctx)
res, err := govMsgSvr.SubmitProposal(wrapCtx, newProposalMsg)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, res) require.NotNil(t, res)
var proposalData types.MsgSubmitProposalResponse proposalID := res.ProposalId
err = proto.Unmarshal(res.Data, &proposalData)
require.NoError(t, err)
proposalID := proposalData.ProposalId
newHeader := ctx.BlockHeader() newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second) newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
@ -241,9 +238,9 @@ func TestTickPassedVotingPeriod(t *testing.T) {
newDepositMsg := types.NewMsgDeposit(addrs[1], proposalID, proposalCoins) newDepositMsg := types.NewMsgDeposit(addrs[1], proposalID, proposalCoins)
res, err = govHandler(ctx, newDepositMsg) res1, err := govMsgSvr.Deposit(wrapCtx, newDepositMsg)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, res) require.NotNil(t, res1)
newHeader = ctx.BlockHeader() newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod).Add(app.GovKeeper.GetVotingParams(ctx).VotingPeriod) newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod).Add(app.GovKeeper.GetVotingParams(ctx).VotingPeriod)
@ -277,15 +274,15 @@ func TestProposalPassedEndblocker(t *testing.T) {
SortAddresses(addrs) SortAddresses(addrs)
handler := gov.NewHandler(app.GovKeeper) govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
stakingHandler := staking.NewHandler(app.StakingKeeper) stakingMsgSvr := stakingkeeper.NewMsgServerImpl(app.StakingKeeper)
header := tmproto.Header{Height: app.LastBlockHeight() + 1} header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header}) app.BeginBlock(abci.RequestBeginBlock{Header: header})
valAddr := sdk.ValAddress(addrs[0]) valAddr := sdk.ValAddress(addrs[0])
createValidators(t, stakingHandler, ctx, []sdk.ValAddress{valAddr}, []int64{10}) createValidators(t, stakingMsgSvr, ctx, []sdk.ValAddress{valAddr}, []int64{10})
staking.EndBlocker(ctx, app.StakingKeeper) staking.EndBlocker(ctx, app.StakingKeeper)
macc := app.GovKeeper.GetGovernanceAccount(ctx) macc := app.GovKeeper.GetGovernanceAccount(ctx)
@ -298,7 +295,9 @@ func TestProposalPassedEndblocker(t *testing.T) {
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 10))} proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 10))}
newDepositMsg := types.NewMsgDeposit(addrs[0], proposal.ProposalId, proposalCoins) newDepositMsg := types.NewMsgDeposit(addrs[0], proposal.ProposalId, proposalCoins)
handleAndCheck(t, handler, ctx, newDepositMsg) res, err := govMsgSvr.Deposit(sdk.WrapSDKContext(ctx), newDepositMsg)
require.NoError(t, err)
require.NotNil(t, res)
macc = app.GovKeeper.GetGovernanceAccount(ctx) macc = app.GovKeeper.GetGovernanceAccount(ctx)
require.NotNil(t, macc) require.NotNil(t, macc)
@ -328,13 +327,13 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) {
SortAddresses(addrs) SortAddresses(addrs)
stakingHandler := staking.NewHandler(app.StakingKeeper) stakingMsgSvr := stakingkeeper.NewMsgServerImpl(app.StakingKeeper)
header := tmproto.Header{Height: app.LastBlockHeight() + 1} header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header}) app.BeginBlock(abci.RequestBeginBlock{Header: header})
valAddr := sdk.ValAddress(addrs[0]) valAddr := sdk.ValAddress(addrs[0])
createValidators(t, stakingHandler, ctx, []sdk.ValAddress{valAddr}, []int64{10}) createValidators(t, stakingMsgSvr, ctx, []sdk.ValAddress{valAddr}, []int64{10})
staking.EndBlocker(ctx, app.StakingKeeper) staking.EndBlocker(ctx, app.StakingKeeper)
// Create a proposal where the handler will pass for the test proposal // Create a proposal where the handler will pass for the test proposal
@ -346,7 +345,10 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) {
proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 10))) proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 10)))
newDepositMsg := types.NewMsgDeposit(addrs[0], proposal.ProposalId, proposalCoins) newDepositMsg := types.NewMsgDeposit(addrs[0], proposal.ProposalId, proposalCoins)
handleAndCheck(t, gov.NewHandler(app.GovKeeper), ctx, newDepositMsg) govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
res, err := govMsgSvr.Deposit(sdk.WrapSDKContext(ctx), newDepositMsg)
require.NoError(t, err)
require.NotNil(t, res)
err = app.GovKeeper.AddVote(ctx, proposal.ProposalId, addrs[0], types.NewNonSplitVoteOption(types.OptionYes)) err = app.GovKeeper.AddVote(ctx, proposal.ProposalId, addrs[0], types.NewNonSplitVoteOption(types.OptionYes))
require.NoError(t, err) require.NoError(t, err)
@ -362,3 +364,19 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) {
// validate that the proposal fails/has been rejected // validate that the proposal fails/has been rejected
gov.EndBlocker(ctx, app.GovKeeper) gov.EndBlocker(ctx, app.GovKeeper)
} }
func createValidators(t *testing.T, stakingMsgSvr stakingtypes.MsgServer, ctx sdk.Context, addrs []sdk.ValAddress, powerAmt []int64) {
require.True(t, len(addrs) <= len(pubkeys), "Not enough pubkeys specified at top of file.")
for i := 0; i < len(addrs); i++ {
valTokens := sdk.TokensFromConsensusPower(powerAmt[i], sdk.DefaultPowerReduction)
valCreateMsg, err := stakingtypes.NewMsgCreateValidator(
addrs[i], pubkeys[i], sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
TestDescription, TestCommissionRates, sdk.OneInt(),
)
require.NoError(t, err)
res, err := stakingMsgSvr.CreateValidator(sdk.WrapSDKContext(ctx), valCreateMsg)
require.NoError(t, err)
require.NotNil(t, res)
}
}

View File

@ -4,9 +4,6 @@ import (
"bytes" "bytes"
"log" "log"
"sort" "sort"
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
@ -77,23 +74,3 @@ var (
ed25519.GenPrivKey().PubKey(), ed25519.GenPrivKey().PubKey(),
} }
) )
func createValidators(t *testing.T, stakingHandler sdk.Handler, ctx sdk.Context, addrs []sdk.ValAddress, powerAmt []int64) {
require.True(t, len(addrs) <= len(pubkeys), "Not enough pubkeys specified at top of file.")
for i := 0; i < len(addrs); i++ {
valTokens := sdk.TokensFromConsensusPower(powerAmt[i], sdk.DefaultPowerReduction)
valCreateMsg, err := stakingtypes.NewMsgCreateValidator(
addrs[i], pubkeys[i], sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
TestDescription, TestCommissionRates, sdk.OneInt(),
)
require.NoError(t, err)
handleAndCheck(t, stakingHandler, ctx, valCreateMsg)
}
}
func handleAndCheck(t *testing.T, h sdk.Handler, ctx sdk.Context, msg sdk.Msg) {
res, err := h(ctx, msg)
require.NoError(t, err)
require.NotNil(t, res)
}

View File

@ -1,38 +0,0 @@
package gov
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/gov/keeper"
"github.com/cosmos/cosmos-sdk/x/gov/types"
)
// NewHandler creates an sdk.Handler for all the gov type messages
func NewHandler(k keeper.Keeper) sdk.Handler {
msgServer := keeper.NewMsgServerImpl(k)
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
case *types.MsgDeposit:
res, err := msgServer.Deposit(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgSubmitProposal:
res, err := msgServer.SubmitProposal(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgVote:
res, err := msgServer.Vote(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgVoteWeighted:
res, err := msgServer.VoteWeighted(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
}
}
}

View File

@ -1,26 +0,0 @@
package gov_test
import (
"strings"
"testing"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
"github.com/stretchr/testify/require"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/gov/keeper"
)
func TestInvalidMsg(t *testing.T) {
k := keeper.Keeper{}
h := gov.NewHandler(k)
res, err := h(sdk.NewContext(nil, tmproto.Header{}, false, nil), testdata.NewTestMsg())
require.Error(t, err)
require.Nil(t, res)
require.True(t, strings.Contains(err.Error(), "unrecognized gov message type"))
}

View File

@ -130,9 +130,9 @@ func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
keeper.RegisterInvariants(ir, am.keeper, am.bankKeeper) keeper.RegisterInvariants(ir, am.keeper, am.bankKeeper)
} }
// Route returns the message routing key for the gov module. // Deprecated: Route returns the message routing key for the gov module.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) return sdk.Route{}
} }
// QuerierRoute returns the gov module's querier route name. // QuerierRoute returns the gov module's querier route name.

View File

@ -107,7 +107,7 @@ func (AppModule) Name() string {
// RegisterInvariants registers the mint module invariants. // RegisterInvariants registers the mint module invariants.
func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// Route returns the message routing key for the mint module. // Deprecated: Route returns the message routing key for the mint module.
func (AppModule) Route() sdk.Route { return sdk.Route{} } func (AppModule) Route() sdk.Route { return sdk.Route{} }
// QuerierRoute returns the mint module's querier route name. // QuerierRoute returns the mint module's querier route name.

View File

@ -95,7 +95,10 @@ func (am AppModule) InitGenesis(_ sdk.Context, _ codec.JSONCodec, _ json.RawMess
return []abci.ValidatorUpdate{} return []abci.ValidatorUpdate{}
} }
func (AppModule) Route() sdk.Route { return sdk.Route{} } // Deprecated: Route returns the message routing key for the params module.
func (AppModule) Route() sdk.Route {
return sdk.Route{}
}
// GenerateGenesisState performs a no-op. // GenerateGenesisState performs a no-op.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {} func (AppModule) GenerateGenesisState(simState *module.SimulationState) {}

View File

@ -1,26 +0,0 @@
package slashing
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/slashing/keeper"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
)
// NewHandler creates an sdk.Handler for all the slashing type messages
func NewHandler(k keeper.Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
msgServer := keeper.NewMsgServerImpl(k)
switch msg := msg.(type) {
case *types.MsgUnjail:
res, err := msgServer.Unjail(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
}
}
}

View File

@ -1,295 +0,0 @@
package slashing_test
import (
"errors"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/slashing/keeper"
"github.com/cosmos/cosmos-sdk/x/slashing/testslashing"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/teststaking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
func TestCannotUnjailUnlessJailed(t *testing.T) {
// initial setup
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
pks := simapp.CreateTestPubKeys(1)
simapp.AddTestAddrsFromPubKeys(app, ctx, pks, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper)
slh := slashing.NewHandler(app.SlashingKeeper)
addr, val := sdk.ValAddress(pks[0].Address()), pks[0]
amt := tstaking.CreateValidatorWithValPower(addr, val, 100, true)
staking.EndBlocker(ctx, app.StakingKeeper)
require.Equal(
t, app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)),
sdk.Coins{sdk.NewCoin(app.StakingKeeper.GetParams(ctx).BondDenom, InitTokens.Sub(amt))},
)
require.Equal(t, amt, app.StakingKeeper.Validator(ctx, addr).GetBondedTokens())
// assert non-jailed validator can't be unjailed
res, err := slh(ctx, types.NewMsgUnjail(addr))
require.Error(t, err)
require.Nil(t, res)
require.True(t, errors.Is(types.ErrValidatorNotJailed, err))
}
func TestCannotUnjailUnlessMeetMinSelfDelegation(t *testing.T) {
// initial setup
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
pks := simapp.CreateTestPubKeys(1)
simapp.AddTestAddrsFromPubKeys(app, ctx, pks, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper)
slh := slashing.NewHandler(app.SlashingKeeper)
addr, val := sdk.ValAddress(pks[0].Address()), pks[0]
amt := app.StakingKeeper.TokensFromConsensusPower(ctx, 100)
msg := tstaking.CreateValidatorMsg(addr, val, amt)
msg.MinSelfDelegation = amt
tstaking.Handle(msg, true)
staking.EndBlocker(ctx, app.StakingKeeper)
require.Equal(
t, app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)),
sdk.Coins{sdk.NewCoin(app.StakingKeeper.GetParams(ctx).BondDenom, InitTokens.Sub(amt))},
)
tstaking.Undelegate(sdk.AccAddress(addr), addr, sdk.OneInt(), true)
require.True(t, app.StakingKeeper.Validator(ctx, addr).IsJailed())
// assert non-jailed validator can't be unjailed
res, err := slh(ctx, types.NewMsgUnjail(addr))
require.Error(t, err)
require.Nil(t, res)
require.True(t, errors.Is(types.ErrSelfDelegationTooLowToUnjail, err))
}
func TestJailedValidatorDelegations(t *testing.T) {
// initial setup
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{Time: time.Unix(0, 0)})
pks := simapp.CreateTestPubKeys(3)
simapp.AddTestAddrsFromPubKeys(app, ctx, pks, app.StakingKeeper.TokensFromConsensusPower(ctx, 20))
app.SlashingKeeper.SetParams(ctx, testslashing.TestParams())
tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper)
stakingParams := app.StakingKeeper.GetParams(ctx)
app.StakingKeeper.SetParams(ctx, stakingParams)
valAddr, consAddr := sdk.ValAddress(pks[1].Address()), sdk.ConsAddress(pks[0].Address())
amt := tstaking.CreateValidatorWithValPower(valAddr, pks[1], 10, true)
staking.EndBlocker(ctx, app.StakingKeeper)
// set dummy signing info
newInfo := types.NewValidatorSigningInfo(consAddr, 0, 0, time.Unix(0, 0), false, 0)
app.SlashingKeeper.SetValidatorSigningInfo(ctx, consAddr, newInfo)
// delegate tokens to the validator
delAddr := sdk.AccAddress(pks[2].Address())
tstaking.Delegate(delAddr, valAddr, amt)
// unbond validator total self-delegations (which should jail the validator)
valAcc := sdk.AccAddress(valAddr)
tstaking.Undelegate(valAcc, valAddr, amt, true)
_, err := app.StakingKeeper.CompleteUnbonding(ctx, sdk.AccAddress(valAddr), valAddr)
require.Nil(t, err, "expected complete unbonding validator to be ok, got: %v", err)
// verify validator still exists and is jailed
validator, found := app.StakingKeeper.GetValidator(ctx, valAddr)
require.True(t, found)
require.True(t, validator.IsJailed())
// verify the validator cannot unjail itself
res, err := slashing.NewHandler(app.SlashingKeeper)(ctx, types.NewMsgUnjail(valAddr))
require.Error(t, err)
require.Nil(t, res)
// self-delegate to validator
tstaking.Delegate(valAcc, valAddr, amt)
// verify the validator can now unjail itself
res, err = slashing.NewHandler(app.SlashingKeeper)(ctx, types.NewMsgUnjail(valAddr))
require.NoError(t, err)
require.NotNil(t, res)
}
func TestInvalidMsg(t *testing.T) {
k := keeper.Keeper{}
h := slashing.NewHandler(k)
res, err := h(sdk.NewContext(nil, tmproto.Header{}, false, nil), testdata.NewTestMsg())
require.Error(t, err)
require.Nil(t, res)
require.True(t, strings.Contains(err.Error(), "unrecognized slashing message type"))
}
// Test a validator through uptime, downtime, revocation,
// unrevocation, starting height reset, and revocation again
func TestHandleAbsentValidator(t *testing.T) {
// initial setup
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{Time: time.Unix(0, 0)})
pks := simapp.CreateTestPubKeys(1)
simapp.AddTestAddrsFromPubKeys(app, ctx, pks, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
app.SlashingKeeper.SetParams(ctx, testslashing.TestParams())
power := int64(100)
addr, val := sdk.ValAddress(pks[0].Address()), pks[0]
slh := slashing.NewHandler(app.SlashingKeeper)
tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper)
amt := tstaking.CreateValidatorWithValPower(addr, val, power, true)
staking.EndBlocker(ctx, app.StakingKeeper)
require.Equal(
t, app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)),
sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.GetParams(ctx).BondDenom, InitTokens.Sub(amt))),
)
require.Equal(t, amt, app.StakingKeeper.Validator(ctx, addr).GetBondedTokens())
// will exist since the validator has been bonded
info, found := app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
require.Equal(t, int64(0), info.StartHeight)
require.Equal(t, int64(0), info.IndexOffset)
require.Equal(t, int64(0), info.MissedBlocksCounter)
require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil)
height := int64(0)
// 1000 first blocks OK
for ; height < app.SlashingKeeper.SignedBlocksWindow(ctx); height++ {
ctx = ctx.WithBlockHeight(height)
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true)
}
info, found = app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
require.Equal(t, int64(0), info.StartHeight)
require.Equal(t, int64(0), info.MissedBlocksCounter)
// 500 blocks missed
for ; height < app.SlashingKeeper.SignedBlocksWindow(ctx)+(app.SlashingKeeper.SignedBlocksWindow(ctx)-app.SlashingKeeper.MinSignedPerWindow(ctx)); height++ {
ctx = ctx.WithBlockHeight(height)
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
}
info, found = app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
require.Equal(t, int64(0), info.StartHeight)
require.Equal(t, app.SlashingKeeper.SignedBlocksWindow(ctx)-app.SlashingKeeper.MinSignedPerWindow(ctx), info.MissedBlocksCounter)
// validator should be bonded still
validator, _ := app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.Equal(t, stakingtypes.Bonded, validator.GetStatus())
bondPool := app.StakingKeeper.GetBondedPool(ctx)
require.True(sdk.IntEq(t, amt, app.BankKeeper.GetBalance(ctx, bondPool.GetAddress(), app.StakingKeeper.BondDenom(ctx)).Amount))
// 501st block missed
ctx = ctx.WithBlockHeight(height)
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
info, found = app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
require.Equal(t, int64(0), info.StartHeight)
// counter now reset to zero
require.Equal(t, int64(0), info.MissedBlocksCounter)
// end block
staking.EndBlocker(ctx, app.StakingKeeper)
// validator should have been jailed
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.Equal(t, stakingtypes.Unbonding, validator.GetStatus())
slashAmt := amt.ToDec().Mul(app.SlashingKeeper.SlashFractionDowntime(ctx)).RoundInt()
// validator should have been slashed
require.True(t, amt.Sub(slashAmt).Equal(validator.GetTokens()))
// 502nd block *also* missed (since the LastCommit would have still included the just-unbonded validator)
height++
ctx = ctx.WithBlockHeight(height)
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
info, found = app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
require.Equal(t, int64(0), info.StartHeight)
require.Equal(t, int64(1), info.MissedBlocksCounter)
// end block
staking.EndBlocker(ctx, app.StakingKeeper)
// validator should not have been slashed any more, since it was already jailed
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.True(t, amt.Sub(slashAmt).Equal(validator.GetTokens()))
// unrevocation should fail prior to jail expiration
res, err := slh(ctx, types.NewMsgUnjail(addr))
require.Error(t, err)
require.Nil(t, res)
// unrevocation should succeed after jail expiration
ctx = ctx.WithBlockHeader(tmproto.Header{Time: time.Unix(1, 0).Add(app.SlashingKeeper.DowntimeJailDuration(ctx))})
res, err = slh(ctx, types.NewMsgUnjail(addr))
require.NoError(t, err)
require.NotNil(t, res)
// end block
staking.EndBlocker(ctx, app.StakingKeeper)
// validator should be rebonded now
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.Equal(t, stakingtypes.Bonded, validator.GetStatus())
// validator should have been slashed
require.True(t, amt.Sub(slashAmt).Equal(app.BankKeeper.GetBalance(ctx, bondPool.GetAddress(), app.StakingKeeper.BondDenom(ctx)).Amount))
// Validator start height should not have been changed
info, found = app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
require.Equal(t, int64(0), info.StartHeight)
// we've missed 2 blocks more than the maximum, so the counter was reset to 0 at 1 block more and is now 1
require.Equal(t, int64(1), info.MissedBlocksCounter)
// validator should not be immediately jailed again
height++
ctx = ctx.WithBlockHeight(height)
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.Equal(t, stakingtypes.Bonded, validator.GetStatus())
// 500 signed blocks
nextHeight := height + app.SlashingKeeper.MinSignedPerWindow(ctx) + 1
for ; height < nextHeight; height++ {
ctx = ctx.WithBlockHeight(height)
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
}
// end block
staking.EndBlocker(ctx, app.StakingKeeper)
// validator should be jailed again after 500 unsigned blocks
nextHeight = height + app.SlashingKeeper.MinSignedPerWindow(ctx) + 1
for ; height <= nextHeight; height++ {
ctx = ctx.WithBlockHeight(height)
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
}
// end block
staking.EndBlocker(ctx, app.StakingKeeper)
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.Equal(t, stakingtypes.Unbonding, validator.GetStatus())
}

View File

@ -42,7 +42,9 @@ func TestUnJailNotBonded(t *testing.T) {
amt := app.StakingKeeper.TokensFromConsensusPower(ctx, 50) amt := app.StakingKeeper.TokensFromConsensusPower(ctx, 50)
msg := tstaking.CreateValidatorMsg(addr, val, amt) msg := tstaking.CreateValidatorMsg(addr, val, amt)
msg.MinSelfDelegation = amt msg.MinSelfDelegation = amt
tstaking.Handle(msg, true) res, err := tstaking.CreateValidatorWithMsg(sdk.WrapSDKContext(ctx), msg)
require.NoError(t, err)
require.NotNil(t, res)
staking.EndBlocker(ctx, app.StakingKeeper) staking.EndBlocker(ctx, app.StakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)

View File

@ -119,9 +119,9 @@ func (AppModule) Name() string {
// RegisterInvariants registers the slashing module invariants. // RegisterInvariants registers the slashing module invariants.
func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// Route returns the message routing key for the slashing module. // Deprecated: Route returns the message routing key for the slashing module.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) return sdk.Route{}
} }
// QuerierRoute returns the slashing module's querier route name. // QuerierRoute returns the slashing module's querier route name.

View File

@ -1,41 +0,0 @@
package staking
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func NewHandler(k keeper.Keeper) sdk.Handler {
msgServer := keeper.NewMsgServerImpl(k)
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
case *types.MsgCreateValidator:
res, err := msgServer.CreateValidator(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgEditValidator:
res, err := msgServer.EditValidator(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgDelegate:
res, err := msgServer.Delegate(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgBeginRedelegate:
res, err := msgServer.BeginRedelegate(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgUndelegate:
res, err := msgServer.Undelegate(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -117,9 +117,9 @@ func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
keeper.RegisterInvariants(ir, am.keeper) keeper.RegisterInvariants(ir, am.keeper)
} }
// Route returns the message routing key for the staking module. // Deprecated: Route returns the message routing key for the staking module.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) return sdk.Route{}
} }
// QuerierRoute returns the staking module's querier route name. // QuerierRoute returns the staking module's querier route name.

View File

@ -1,6 +1,7 @@
package teststaking package teststaking
import ( import (
"context"
"testing" "testing"
"time" "time"
@ -13,12 +14,12 @@ import (
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
) )
// Helper is a structure which wraps the staking handler // Helper is a structure which wraps the staking message server
// and provides methods useful in tests // and provides methods useful in tests
type Helper struct { type Helper struct {
t *testing.T t *testing.T
h sdk.Handler msgSrvr stakingtypes.MsgServer
k keeper.Keeper k keeper.Keeper
Ctx sdk.Context Ctx sdk.Context
Commission stakingtypes.CommissionRates Commission stakingtypes.CommissionRates
@ -26,18 +27,18 @@ type Helper struct {
Denom string Denom string
} }
// NewHelper creates staking Handler wrapper for tests // NewHelper creates a new instance of Helper.
func NewHelper(t *testing.T, ctx sdk.Context, k keeper.Keeper) *Helper { func NewHelper(t *testing.T, ctx sdk.Context, k keeper.Keeper) *Helper {
return &Helper{t, staking.NewHandler(k), k, ctx, ZeroCommission(), sdk.DefaultBondDenom} return &Helper{t, keeper.NewMsgServerImpl(k), k, ctx, ZeroCommission(), sdk.DefaultBondDenom}
} }
// CreateValidator calls handler to create a new staking validator // CreateValidator calls staking module `MsgServer/CreateValidator` to create a new validator
func (sh *Helper) CreateValidator(addr sdk.ValAddress, pk cryptotypes.PubKey, stakeAmount sdk.Int, ok bool) { func (sh *Helper) CreateValidator(addr sdk.ValAddress, pk cryptotypes.PubKey, stakeAmount sdk.Int, ok bool) {
coin := sdk.NewCoin(sh.Denom, stakeAmount) coin := sdk.NewCoin(sh.Denom, stakeAmount)
sh.createValidator(addr, pk, coin, ok) sh.createValidator(addr, pk, coin, ok)
} }
// CreateValidatorWithValPower calls handler to create a new staking validator with zero // CreateValidatorWithValPower calls staking module `MsgServer/CreateValidator` to create a new validator with zero
// commission // commission
func (sh *Helper) CreateValidatorWithValPower(addr sdk.ValAddress, pk cryptotypes.PubKey, valPower int64, ok bool) sdk.Int { func (sh *Helper) CreateValidatorWithValPower(addr sdk.ValAddress, pk cryptotypes.PubKey, valPower int64, ok bool) sdk.Int {
amount := sh.k.TokensFromConsensusPower(sh.Ctx, valPower) amount := sh.k.TokensFromConsensusPower(sh.Ctx, valPower)
@ -54,36 +55,47 @@ func (sh *Helper) CreateValidatorMsg(addr sdk.ValAddress, pk cryptotypes.PubKey,
return msg return msg
} }
// CreateValidatorWithMsg calls staking module `MsgServer/CreateValidator`
func (sh *Helper) CreateValidatorWithMsg(ctx context.Context, msg *stakingtypes.MsgCreateValidator) (*stakingtypes.MsgCreateValidatorResponse, error) {
return sh.msgSrvr.CreateValidator(ctx, msg)
}
func (sh *Helper) createValidator(addr sdk.ValAddress, pk cryptotypes.PubKey, coin sdk.Coin, ok bool) { func (sh *Helper) createValidator(addr sdk.ValAddress, pk cryptotypes.PubKey, coin sdk.Coin, ok bool) {
msg, err := stakingtypes.NewMsgCreateValidator(addr, pk, coin, stakingtypes.Description{}, sh.Commission, sdk.OneInt()) msg, err := stakingtypes.NewMsgCreateValidator(addr, pk, coin, stakingtypes.Description{}, sh.Commission, sdk.OneInt())
require.NoError(sh.t, err) require.NoError(sh.t, err)
sh.Handle(msg, ok) res, err := sh.msgSrvr.CreateValidator(sdk.WrapSDKContext(sh.Ctx), msg)
} if ok {
require.NoError(sh.t, err)
// Delegate calls handler to delegate stake for a validator require.NotNil(sh.t, res)
func (sh *Helper) Delegate(delegator sdk.AccAddress, val sdk.ValAddress, amount sdk.Int) { } else {
coin := sdk.NewCoin(sh.Denom, amount) require.Error(sh.t, err)
msg := stakingtypes.NewMsgDelegate(delegator, val, coin) require.Nil(sh.t, res)
sh.Handle(msg, true) }
} }
// DelegateWithPower calls handler to delegate stake for a validator // Delegate calls staking module staking module `MsgServer/Delegate` to delegate stake for a validator
func (sh *Helper) DelegateWithPower(delegator sdk.AccAddress, val sdk.ValAddress, power int64) { func (sh *Helper) Delegate(delegator sdk.AccAddress, val sdk.ValAddress, amount sdk.Int) {
coin := sdk.NewCoin(sh.Denom, sh.k.TokensFromConsensusPower(sh.Ctx, power)) coin := sdk.NewCoin(sh.Denom, amount)
msg := stakingtypes.NewMsgDelegate(delegator, val, coin) msg := stakingtypes.NewMsgDelegate(delegator, val, coin)
sh.Handle(msg, true) res, err := sh.msgSrvr.Delegate(sdk.WrapSDKContext(sh.Ctx), msg)
} require.NoError(sh.t, err)
require.NotNil(sh.t, res)
// Undelegate calls handler to unbound some stake from a validator. }
func (sh *Helper) Undelegate(delegator sdk.AccAddress, val sdk.ValAddress, amount sdk.Int, ok bool) *sdk.Result {
unbondAmt := sdk.NewCoin(sh.Denom, amount) // DelegateWithPower calls staking module `MsgServer/Delegate` to delegate stake for a validator
msg := stakingtypes.NewMsgUndelegate(delegator, val, unbondAmt) func (sh *Helper) DelegateWithPower(delegator sdk.AccAddress, val sdk.ValAddress, power int64) {
return sh.Handle(msg, ok) coin := sdk.NewCoin(sh.Denom, sh.k.TokensFromConsensusPower(sh.Ctx, power))
} msg := stakingtypes.NewMsgDelegate(delegator, val, coin)
res, err := sh.msgSrvr.Delegate(sdk.WrapSDKContext(sh.Ctx), msg)
// Handle calls staking handler on a given message require.NoError(sh.t, err)
func (sh *Helper) Handle(msg sdk.Msg, ok bool) *sdk.Result { require.NotNil(sh.t, res)
res, err := sh.h(sh.Ctx, msg) }
// Undelegate calls staking module `MsgServer/Undelegate` to unbound some stake from a validator.
func (sh *Helper) Undelegate(delegator sdk.AccAddress, val sdk.ValAddress, amount sdk.Int, ok bool) {
unbondAmt := sdk.NewCoin(sh.Denom, amount)
msg := stakingtypes.NewMsgUndelegate(delegator, val, unbondAmt)
res, err := sh.msgSrvr.Undelegate(sdk.WrapSDKContext(sh.Ctx), msg)
if ok { if ok {
require.NoError(sh.t, err) require.NoError(sh.t, err)
require.NotNil(sh.t, res) require.NotNil(sh.t, res)
@ -91,7 +103,6 @@ func (sh *Helper) Handle(msg sdk.Msg, ok bool) *sdk.Result {
require.Error(sh.t, err) require.Error(sh.t, err)
require.Nil(sh.t, res) require.Nil(sh.t, res)
} }
return res
} }
// CheckValidator asserts that a validor exists and has a given status (if status!="") // CheckValidator asserts that a validor exists and has a given status (if status!="")

View File

@ -82,8 +82,10 @@ func NewAppModule(keeper keeper.Keeper) AppModule {
// RegisterInvariants does nothing, there are no invariants to enforce // RegisterInvariants does nothing, there are no invariants to enforce
func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// Route is empty, as we do not handle Messages (just proposals) // Deprecated: Route returns the message routing key for the upgrade module.
func (AppModule) Route() sdk.Route { return sdk.Route{} } func (AppModule) Route() sdk.Route {
return sdk.Route{}
}
// QuerierRoute returns the route we respond to for abci queries // QuerierRoute returns the route we respond to for abci queries
func (AppModule) QuerierRoute() string { return types.QuerierKey } func (AppModule) QuerierRoute() string { return types.QuerierKey }