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:
parent
481aa2e589
commit
48cb9eab8c
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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))
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 "" }
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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))
|
|
||||||
}
|
|
|
@ -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.
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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))
|
|
||||||
}
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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"))
|
|
||||||
}
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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) {}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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())
|
|
||||||
}
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
@ -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.
|
||||||
|
|
|
@ -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!="")
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
Loading…
Reference in New Issue