refactor: use mocks for x/slashing (#12937)

* move integration tests

* add unit testing

* refactor module import

* add hooks test

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
Co-authored-by: Jeancarlo Barrios <JeancarloBarrios@users.noreply.github.com>
This commit is contained in:
cool-developer 2022-08-17 14:40:41 -04:00 committed by GitHub
parent d5d6e8bf0a
commit b51537260f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1103 additions and 513 deletions

View File

@ -20,3 +20,4 @@ $mockgen_cmd -source=x/auth/ante/expected_keepers.go -package testutil -destinat
$mockgen_cmd -source=x/authz/expected_keepers.go -package testutil -destination x/authz/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/bank/types/expected_keepers.go -package testutil -destination x/bank/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/evidence/types/expected_keepers.go -package testutil -destination x/evidence/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/slashing/types/expected_keepers.go -package testutil -destination x/slashing/testutil/expected_keepers_mocks.go

View File

@ -8,13 +8,12 @@ import (
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil/network"
clienttestutil "github.com/cosmos/cosmos-sdk/x/slashing/client/testutil"
"github.com/stretchr/testify/suite"
)
func TestIntegrationTestSuite(t *testing.T) {
func TestEndToEndTestSuite(t *testing.T) {
cfg := network.DefaultConfig(simapp.NewTestNetworkFixture)
cfg.NumValidators = 1
suite.Run(t, clienttestutil.NewIntegrationTestSuite(cfg))
suite.Run(t, NewEndToEndTestSuite(cfg))
}

View File

@ -13,7 +13,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/slashing/types"
)
func (s *IntegrationTestSuite) TestGRPCQueries() {
func (s *EndToEndTestSuite) TestGRPCQueries() {
val := s.network.Validators[0]
baseURL := val.APIAddress

View File

@ -15,20 +15,20 @@ import (
"github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
)
type IntegrationTestSuite struct {
type EndToEndTestSuite struct {
suite.Suite
cfg network.Config
network *network.Network
}
func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite {
return &IntegrationTestSuite{cfg: cfg}
func NewEndToEndTestSuite(cfg network.Config) *EndToEndTestSuite {
return &EndToEndTestSuite{cfg: cfg}
}
// SetupSuite executes bootstrapping logic before all the tests, i.e. once before
// the entire suite, start executing.
func (s *IntegrationTestSuite) SetupSuite() {
func (s *EndToEndTestSuite) SetupSuite() {
s.T().Log("setting up integration test suite")
var err error
@ -41,12 +41,12 @@ func (s *IntegrationTestSuite) SetupSuite() {
// TearDownSuite performs cleanup logic after all the tests, i.e. once after the
// entire suite, has finished executing.
func (s *IntegrationTestSuite) TearDownSuite() {
func (s *EndToEndTestSuite) TearDownSuite() {
s.T().Log("tearing down integration test suite")
s.network.Cleanup()
}
func (s *IntegrationTestSuite) TestGetCmdQuerySigningInfo() {
func (s *EndToEndTestSuite) TestGetCmdQuerySigningInfo() {
val := s.network.Validators[0]
pubKeyBz, err := s.cfg.Codec.MarshalInterfaceJSON(val.PubKey)
s.Require().NoError(err)
@ -104,7 +104,7 @@ tombstoned: false`, sdk.ConsAddress(val.PubKey.Address())),
}
}
func (s *IntegrationTestSuite) TestGetCmdQueryParams() {
func (s *EndToEndTestSuite) TestGetCmdQueryParams() {
val := s.network.Validators[0]
testCases := []struct {
@ -142,7 +142,7 @@ slash_fraction_downtime: "0.010000000000000000"`,
}
}
func (s *IntegrationTestSuite) TestNewUnjailTxCmd() {
func (s *EndToEndTestSuite) TestNewUnjailTxCmd() {
val := s.network.Validators[0]
testCases := []struct {
name string

View File

@ -0,0 +1,353 @@
package keeper_test
import (
"testing"
"time"
"github.com/stretchr/testify/suite"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/baseapp"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing/testslashing"
"github.com/cosmos/cosmos-sdk/x/slashing/testutil"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/teststaking"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
// The default power validators are initialized to have within tests
var InitTokens = sdk.TokensFromConsensusPower(200, sdk.DefaultPowerReduction)
type KeeperTestSuite struct {
suite.Suite
ctx sdk.Context
slashingKeeper slashingkeeper.Keeper
stakingKeeper *stakingkeeper.Keeper
bankKeeper bankkeeper.Keeper
accountKeeper authkeeper.AccountKeeper
interfaceRegistry codectypes.InterfaceRegistry
addrDels []sdk.AccAddress
queryClient slashingtypes.QueryClient
msgServer slashingtypes.MsgServer
}
func (s *KeeperTestSuite) SetupTest() {
app, err := simtestutil.Setup(
testutil.AppConfig,
&s.bankKeeper,
&s.accountKeeper,
&s.slashingKeeper,
&s.stakingKeeper,
&s.interfaceRegistry,
)
s.Require().NoError(err)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
s.accountKeeper.SetParams(ctx, authtypes.DefaultParams())
s.bankKeeper.SetParams(ctx, banktypes.DefaultParams())
s.slashingKeeper.SetParams(ctx, testslashing.TestParams())
addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 5, s.stakingKeeper.TokensFromConsensusPower(ctx, 200))
info1 := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addrDels[0]), int64(4), int64(3),
time.Unix(2, 0), false, int64(10))
info2 := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addrDels[1]), int64(5), int64(4),
time.Unix(2, 0), false, int64(10))
s.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), info1)
s.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[1]), info2)
queryHelper := baseapp.NewQueryServerTestHelper(ctx, s.interfaceRegistry)
slashingtypes.RegisterQueryServer(queryHelper, s.slashingKeeper)
queryClient := slashingtypes.NewQueryClient(queryHelper)
s.queryClient = queryClient
s.addrDels = addrDels
s.ctx = ctx
s.msgServer = slashingkeeper.NewMsgServerImpl(s.slashingKeeper)
}
func (s *KeeperTestSuite) TestUnJailNotBonded() {
ctx := s.ctx
p := s.stakingKeeper.GetParams(ctx)
p.MaxValidators = 5
s.stakingKeeper.SetParams(ctx, p)
addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 6, s.stakingKeeper.TokensFromConsensusPower(ctx, 200))
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrDels)
pks := simtestutil.CreateTestPubKeys(6)
tstaking := teststaking.NewHelper(s.T(), ctx, s.stakingKeeper)
// create max (5) validators all with the same power
for i := uint32(0); i < p.MaxValidators; i++ {
addr, val := valAddrs[i], pks[i]
tstaking.CreateValidatorWithValPower(addr, val, 100, true)
}
staking.EndBlocker(ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
// create a 6th validator with less power than the cliff validator (won't be bonded)
addr, val := valAddrs[5], pks[5]
amt := s.stakingKeeper.TokensFromConsensusPower(ctx, 50)
msg := tstaking.CreateValidatorMsg(addr, val, amt)
msg.MinSelfDelegation = amt
res, err := tstaking.CreateValidatorWithMsg(sdk.WrapSDKContext(ctx), msg)
s.Require().NoError(err)
s.Require().NotNil(res)
staking.EndBlocker(ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
tstaking.CheckValidator(addr, stakingtypes.Unbonded, false)
// unbond below minimum self-delegation
s.Require().Equal(p.BondDenom, tstaking.Denom)
tstaking.Undelegate(sdk.AccAddress(addr), addr, s.stakingKeeper.TokensFromConsensusPower(ctx, 1), true)
staking.EndBlocker(ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
// verify that validator is jailed
tstaking.CheckValidator(addr, -1, true)
// verify we cannot unjail (yet)
s.Require().Error(s.slashingKeeper.Unjail(ctx, addr))
staking.EndBlocker(ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
// bond to meet minimum self-delegation
tstaking.DelegateWithPower(sdk.AccAddress(addr), addr, 1)
staking.EndBlocker(ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
// verify we can immediately unjail
s.Require().NoError(s.slashingKeeper.Unjail(ctx, addr))
tstaking.CheckValidator(addr, -1, false)
}
// Test a new validator entering the validator set
// Ensure that SigningInfo.StartHeight is set correctly
// and that they are not immediately jailed
func (s *KeeperTestSuite) TestHandleNewValidator() {
ctx := s.ctx
addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 1, s.stakingKeeper.TokensFromConsensusPower(ctx, 0))
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrDels)
pks := simtestutil.CreateTestPubKeys(1)
addr, val := valAddrs[0], pks[0]
tstaking := teststaking.NewHelper(s.T(), ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(s.slashingKeeper.SignedBlocksWindow(ctx) + 1)
// Validator created
amt := tstaking.CreateValidatorWithValPower(addr, val, 100, true)
staking.EndBlocker(ctx, s.stakingKeeper)
s.Require().Equal(
s.bankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)),
sdk.NewCoins(sdk.NewCoin(s.stakingKeeper.GetParams(ctx).BondDenom, InitTokens.Sub(amt))),
)
s.Require().Equal(amt, s.stakingKeeper.Validator(ctx, addr).GetBondedTokens())
// Now a validator, for two blocks
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), 100, true)
ctx = ctx.WithBlockHeight(s.slashingKeeper.SignedBlocksWindow(ctx) + 2)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), 100, false)
info, found := s.slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
s.Require().True(found)
s.Require().Equal(s.slashingKeeper.SignedBlocksWindow(ctx)+1, info.StartHeight)
s.Require().Equal(int64(2), info.IndexOffset)
s.Require().Equal(int64(1), info.MissedBlocksCounter)
s.Require().Equal(time.Unix(0, 0).UTC(), info.JailedUntil)
// validator should be bonded still, should not have been jailed or slashed
validator, _ := s.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
s.Require().Equal(stakingtypes.Bonded, validator.GetStatus())
bondPool := s.stakingKeeper.GetBondedPool(ctx)
expTokens := s.stakingKeeper.TokensFromConsensusPower(ctx, 100)
// adding genesis validator tokens
expTokens = expTokens.Add(s.stakingKeeper.TokensFromConsensusPower(ctx, 1))
s.Require().True(expTokens.Equal(s.bankKeeper.GetBalance(ctx, bondPool.GetAddress(), s.stakingKeeper.BondDenom(ctx)).Amount))
}
// Test a jailed validator being "down" twice
// Ensure that they're only slashed once
func (s *KeeperTestSuite) TestHandleAlreadyJailed() {
// initial setup
ctx := s.ctx
addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 1, s.stakingKeeper.TokensFromConsensusPower(ctx, 200))
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrDels)
pks := simtestutil.CreateTestPubKeys(1)
addr, val := valAddrs[0], pks[0]
power := int64(100)
tstaking := teststaking.NewHelper(s.T(), ctx, s.stakingKeeper)
amt := tstaking.CreateValidatorWithValPower(addr, val, power, true)
staking.EndBlocker(ctx, s.stakingKeeper)
// 1000 first blocks OK
height := int64(0)
for ; height < s.slashingKeeper.SignedBlocksWindow(ctx); height++ {
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true)
}
// 501 blocks missed
for ; height < s.slashingKeeper.SignedBlocksWindow(ctx)+(s.slashingKeeper.SignedBlocksWindow(ctx)-s.slashingKeeper.MinSignedPerWindow(ctx))+1; height++ {
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
}
// end block
staking.EndBlocker(ctx, s.stakingKeeper)
// validator should have been jailed and slashed
validator, _ := s.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
s.Require().Equal(stakingtypes.Unbonding, validator.GetStatus())
// validator should have been slashed
resultingTokens := amt.Sub(s.stakingKeeper.TokensFromConsensusPower(ctx, 1))
s.Require().Equal(resultingTokens, validator.GetTokens())
// another block missed
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
// validator should not have been slashed twice
validator, _ = s.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
s.Require().Equal(resultingTokens, validator.GetTokens())
}
// Test a validator dipping in and out of the validator set
// Ensure that missed blocks are tracked correctly and that
// the start height of the signing info is reset correctly
func (s *KeeperTestSuite) TestValidatorDippingInAndOut() {
// initial setup
// TestParams set the SignedBlocksWindow to 1000 and MaxMissedBlocksPerWindow to 500
ctx := s.ctx
s.slashingKeeper.SetParams(ctx, testslashing.TestParams())
params := s.stakingKeeper.GetParams(ctx)
params.MaxValidators = 1
s.stakingKeeper.SetParams(ctx, params)
power := int64(100)
pks := simtestutil.CreateTestPubKeys(3)
simtestutil.AddTestAddrsFromPubKeys(s.bankKeeper, s.stakingKeeper, ctx, pks, s.stakingKeeper.TokensFromConsensusPower(ctx, 200))
addr, val := pks[0].Address(), pks[0]
consAddr := sdk.ConsAddress(addr)
tstaking := teststaking.NewHelper(s.T(), ctx, s.stakingKeeper)
valAddr := sdk.ValAddress(addr)
tstaking.CreateValidatorWithValPower(valAddr, val, power, true)
validatorUpdates := staking.EndBlocker(ctx, s.stakingKeeper)
s.Require().Equal(2, len(validatorUpdates))
tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false)
// 100 first blocks OK
height := int64(0)
for ; height < int64(100); height++ {
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true)
}
// kick first validator out of validator set
tstaking.CreateValidatorWithValPower(sdk.ValAddress(pks[1].Address()), pks[1], power+1, true)
validatorUpdates = staking.EndBlocker(ctx, s.stakingKeeper)
s.Require().Equal(2, len(validatorUpdates))
tstaking.CheckValidator(sdk.ValAddress(pks[1].Address()), stakingtypes.Bonded, false)
tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, false)
// 600 more blocks happened
height = height + 600
ctx = ctx.WithBlockHeight(height)
// validator added back in
tstaking.DelegateWithPower(sdk.AccAddress(pks[2].Address()), valAddr, 50)
validatorUpdates = staking.EndBlocker(ctx, s.stakingKeeper)
s.Require().Equal(2, len(validatorUpdates))
tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false)
newPower := power + 50
// validator misses a block
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
height++
// shouldn't be jailed/kicked yet
tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false)
// validator misses an additional 500 more blocks, after the cooling off period of SignedBlockWindow (here 1000 blocks).
latest := s.slashingKeeper.SignedBlocksWindow(ctx) + height
for ; height < latest+s.slashingKeeper.MinSignedPerWindow(ctx); height++ {
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
}
// should now be jailed & kicked
staking.EndBlocker(ctx, s.stakingKeeper)
tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, true)
// check all the signing information
signInfo, found := s.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr)
s.Require().True(found)
s.Require().Equal(int64(700), signInfo.StartHeight)
s.Require().Equal(int64(499), signInfo.MissedBlocksCounter)
s.Require().Equal(int64(499), signInfo.IndexOffset)
// some blocks pass
height = int64(5000)
ctx = ctx.WithBlockHeight(height)
// validator rejoins and starts signing again
s.stakingKeeper.Unjail(ctx, consAddr)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, true)
// validator should not be kicked since we reset counter/array when it was jailed
staking.EndBlocker(ctx, s.stakingKeeper)
tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false)
// check start height is correctly set
signInfo, found = s.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr)
s.Require().True(found)
s.Require().Equal(height, signInfo.StartHeight)
// validator misses 501 blocks after SignedBlockWindow period (1000 blocks)
latest = s.slashingKeeper.SignedBlocksWindow(ctx) + height
for ; height < latest+s.slashingKeeper.MinSignedPerWindow(ctx); height++ {
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
}
// validator should now be jailed & kicked
staking.EndBlocker(ctx, s.stakingKeeper)
tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, true)
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}

View File

@ -1,6 +0,0 @@
package keeper_test
import sdk "github.com/cosmos/cosmos-sdk/types"
// The default power validators are initialized to have within tests
var InitTokens = sdk.TokensFromConsensusPower(200, sdk.DefaultPowerReduction)

View File

@ -1,74 +1,57 @@
package keeper_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/golang/mock/gomock"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
"github.com/cosmos/cosmos-sdk/x/slashing/testslashing"
"github.com/cosmos/cosmos-sdk/x/slashing/testutil"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
)
func TestExportAndInitGenesis(t *testing.T) {
var slashingKeeper slashingkeeper.Keeper
var stakingKeeper *stakingkeeper.Keeper
var bankKeeper bankkeeper.Keeper
func (s *KeeperTestSuite) TestExportAndInitGenesis() {
ctx, keeper := s.ctx, s.slashingKeeper
require := s.Require()
app, err := simtestutil.Setup(
testutil.AppConfig,
&slashingKeeper,
&stakingKeeper,
&bankKeeper,
)
require.NoError(t, err)
keeper.SetParams(ctx, testslashing.TestParams())
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
consAddr1 := sdk.ConsAddress(sdk.AccAddress([]byte("addr1_______________")))
consAddr2 := sdk.ConsAddress(sdk.AccAddress([]byte("addr2_______________")))
slashingKeeper.SetParams(ctx, testslashing.TestParams())
addrDels := simtestutil.AddTestAddrsIncremental(bankKeeper, stakingKeeper, ctx, 2, stakingKeeper.TokensFromConsensusPower(ctx, 200))
info1 := types.NewValidatorSigningInfo(sdk.ConsAddress(addrDels[0]), int64(4), int64(3),
info1 := types.NewValidatorSigningInfo(consAddr1, int64(4), int64(3),
time.Now().UTC().Add(100000000000), false, int64(10))
info2 := types.NewValidatorSigningInfo(sdk.ConsAddress(addrDels[1]), int64(5), int64(4),
info2 := types.NewValidatorSigningInfo(consAddr2, int64(5), int64(4),
time.Now().UTC().Add(10000000000), false, int64(10))
slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), info1)
slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[1]), info2)
genesisState := slashingKeeper.ExportGenesis(ctx)
keeper.SetValidatorSigningInfo(ctx, consAddr1, info1)
keeper.SetValidatorSigningInfo(ctx, consAddr2, info2)
genesisState := keeper.ExportGenesis(ctx)
require.Equal(t, genesisState.Params, testslashing.TestParams())
require.Len(t, genesisState.SigningInfos, 2)
require.Equal(t, genesisState.SigningInfos[0].ValidatorSigningInfo, info1)
require.Equal(genesisState.Params, testslashing.TestParams())
require.Len(genesisState.SigningInfos, 2)
require.Equal(genesisState.SigningInfos[0].ValidatorSigningInfo, info1)
// Tombstone validators after genesis shouldn't effect genesis state
slashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[0]))
slashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[1]))
keeper.Tombstone(ctx, consAddr1)
keeper.Tombstone(ctx, consAddr2)
ok := slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[0]))
require.True(t, ok)
ok := keeper.IsTombstoned(ctx, consAddr1)
require.True(ok)
newInfo1, _ := keeper.GetValidatorSigningInfo(ctx, consAddr1)
require.NotEqual(info1, newInfo1)
newInfo1, ok := slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]))
require.NotEqual(t, info1, newInfo1)
// Initialise genesis with genesis state before tombstone
slashingKeeper.InitGenesis(ctx, stakingKeeper, genesisState)
s.stakingKeeper.EXPECT().IterateValidators(ctx, gomock.Any()).Return()
keeper.InitGenesis(ctx, s.stakingKeeper, genesisState)
// Validator isTombstoned should return false as GenesisState is initialised
ok = slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[0]))
require.False(t, ok)
ok = keeper.IsTombstoned(ctx, consAddr1)
require.False(ok)
newInfo1, ok = slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]))
newInfo2, ok := slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[1]))
require.True(t, ok)
require.Equal(t, info1, newInfo1)
require.Equal(t, info2, newInfo2)
newInfo1, _ = keeper.GetValidatorSigningInfo(ctx, consAddr1)
newInfo2, _ := keeper.GetValidatorSigningInfo(ctx, consAddr2)
require.Equal(info1, newInfo1)
require.Equal(info2, newInfo2)
}

View File

@ -2,59 +2,89 @@ package keeper_test
import (
gocontext "context"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/x/slashing/testslashing"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
)
func (suite *KeeperTestSuite) TestGRPCQueryParams() {
queryClient := suite.queryClient
paramsResp, err := queryClient.Params(gocontext.Background(), &types.QueryParamsRequest{})
func (s *KeeperTestSuite) TestGRPCQueryParams() {
queryClient := s.queryClient
require := s.Require()
suite.NoError(err)
suite.Equal(testslashing.TestParams(), paramsResp.Params)
paramsResp, err := queryClient.Params(gocontext.Background(), &slashingtypes.QueryParamsRequest{})
require.NoError(err)
require.Equal(testslashing.TestParams(), paramsResp.Params)
}
func (suite *KeeperTestSuite) TestGRPCSigningInfo() {
queryClient := suite.queryClient
func (s *KeeperTestSuite) TestGRPCSigningInfo() {
queryClient, ctx, keeper := s.queryClient, s.ctx, s.slashingKeeper
require := s.Require()
infoResp, err := queryClient.SigningInfo(gocontext.Background(), &types.QuerySigningInfoRequest{ConsAddress: ""})
suite.Error(err)
suite.Nil(infoResp)
infoResp, err := queryClient.SigningInfo(gocontext.Background(), &slashingtypes.QuerySigningInfoRequest{ConsAddress: ""})
require.Error(err)
require.Nil(infoResp)
consAddr := sdk.ConsAddress(suite.addrDels[0])
info, found := suite.slashingKeeper.GetValidatorSigningInfo(suite.ctx, consAddr)
suite.True(found)
signingInfo := slashingtypes.NewValidatorSigningInfo(
consAddr,
0,
int64(0),
time.Unix(2, 0),
false,
int64(0),
)
keeper.SetValidatorSigningInfo(ctx, consAddr, signingInfo)
info, found := keeper.GetValidatorSigningInfo(ctx, consAddr)
require.True(found)
infoResp, err = queryClient.SigningInfo(gocontext.Background(),
&types.QuerySigningInfoRequest{ConsAddress: consAddr.String()})
suite.NoError(err)
suite.Equal(info, infoResp.ValSigningInfo)
&slashingtypes.QuerySigningInfoRequest{ConsAddress: consAddr.String()})
require.NoError(err)
require.Equal(info, infoResp.ValSigningInfo)
}
func (suite *KeeperTestSuite) TestGRPCSigningInfos() {
queryClient := suite.queryClient
func (s *KeeperTestSuite) TestGRPCSigningInfos() {
queryClient, ctx, keeper := s.queryClient, s.ctx, s.slashingKeeper
require := s.Require()
var signingInfos []types.ValidatorSigningInfo
// set two validator signing information
consAddr1 := sdk.ConsAddress(sdk.AccAddress([]byte("addr1_______________")))
consAddr2 := sdk.ConsAddress(sdk.AccAddress([]byte("addr2_______________")))
signingInfo := slashingtypes.NewValidatorSigningInfo(
consAddr1,
0,
int64(0),
time.Unix(2, 0),
false,
int64(0),
)
suite.slashingKeeper.IterateValidatorSigningInfos(suite.ctx, func(consAddr sdk.ConsAddress, info types.ValidatorSigningInfo) (stop bool) {
keeper.SetValidatorSigningInfo(ctx, consAddr1, signingInfo)
signingInfo.Address = string(consAddr2)
keeper.SetValidatorSigningInfo(ctx, consAddr2, signingInfo)
var signingInfos []slashingtypes.ValidatorSigningInfo
keeper.IterateValidatorSigningInfos(ctx, func(consAddr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) {
signingInfos = append(signingInfos, info)
return false
})
// verify all values are returned without pagination
infoResp, err := queryClient.SigningInfos(gocontext.Background(),
&types.QuerySigningInfosRequest{Pagination: nil})
suite.NoError(err)
suite.Equal(signingInfos, infoResp.Info)
&slashingtypes.QuerySigningInfosRequest{Pagination: nil})
require.NoError(err)
require.Equal(signingInfos, infoResp.Info)
infoResp, err = queryClient.SigningInfos(gocontext.Background(),
&types.QuerySigningInfosRequest{Pagination: &query.PageRequest{Limit: 1, CountTotal: true}})
suite.NoError(err)
suite.Len(infoResp.Info, 1)
suite.Equal(signingInfos[0], infoResp.Info[0])
suite.NotNil(infoResp.Pagination.NextKey)
suite.Equal(uint64(2), infoResp.Pagination.Total)
&slashingtypes.QuerySigningInfosRequest{Pagination: &query.PageRequest{Limit: 1, CountTotal: true}})
require.NoError(err)
require.Len(infoResp.Info, 1)
require.Equal(signingInfos[0], infoResp.Info[0])
require.NotNil(infoResp.Pagination.NextKey)
require.Equal(uint64(2), infoResp.Pagination.Total)
}

View File

@ -0,0 +1,43 @@
package keeper_test
import (
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
func (s *KeeperTestSuite) TestAfterValidatorBonded() {
ctx, keeper := s.ctx, s.slashingKeeper
require := s.Require()
valAddr := sdk.ValAddress(consAddr.Bytes())
keeper.AfterValidatorBonded(ctx, consAddr, valAddr)
_, ok := keeper.GetValidatorSigningInfo(ctx, consAddr)
require.True(ok)
}
func (s *KeeperTestSuite) TestAfterValidatorCreatedOrRemoved() {
ctx, keeper := s.ctx, s.slashingKeeper
require := s.Require()
_, pubKey, addr := testdata.KeyTestPubAddr()
valAddr := sdk.ValAddress(addr)
validator, err := stakingtypes.NewValidator(sdk.ValAddress(addr), pubKey, stakingtypes.Description{})
require.NoError(err)
s.stakingKeeper.EXPECT().Validator(ctx, valAddr).Return(validator)
err = keeper.AfterValidatorCreated(ctx, valAddr)
require.NoError(err)
ePubKey, err := keeper.GetPubkey(ctx, addr.Bytes())
require.NoError(err)
require.Equal(ePubKey, pubKey)
err = keeper.AfterValidatorRemoved(ctx, sdk.ConsAddress(addr))
require.NoError(err)
_, err = keeper.GetPubkey(ctx, addr.Bytes())
require.Error(err)
}

View File

@ -2,346 +2,79 @@ package keeper_test
import (
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/suite"
"github.com/tendermint/tendermint/crypto"
tmtime "github.com/tendermint/tendermint/libs/time"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/baseapp"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/slashing/testslashing"
"github.com/cosmos/cosmos-sdk/x/slashing/testutil"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
slashingtestutil "github.com/cosmos/cosmos-sdk/x/slashing/testutil"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/teststaking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
var consAddr = sdk.ConsAddress(sdk.AccAddress([]byte("addr1_______________")))
type KeeperTestSuite struct {
suite.Suite
ctx sdk.Context
slashingKeeper slashingkeeper.Keeper
stakingKeeper *stakingkeeper.Keeper
bankKeeper bankkeeper.Keeper
accountKeeper authkeeper.AccountKeeper
interfaceRegistry codectypes.InterfaceRegistry
addrDels []sdk.AccAddress
queryClient slashingtypes.QueryClient
msgServer types.MsgServer
ctx sdk.Context
stakingKeeper *slashingtestutil.MockStakingKeeper
slashingKeeper slashingkeeper.Keeper
queryClient slashingtypes.QueryClient
msgServer slashingtypes.MsgServer
}
func (s *KeeperTestSuite) SetupTest() {
app, err := simtestutil.Setup(
testutil.AppConfig,
&s.bankKeeper,
&s.accountKeeper,
&s.slashingKeeper,
&s.stakingKeeper,
&s.interfaceRegistry,
key := sdk.NewKVStoreKey(slashingtypes.StoreKey)
testCtx := testutil.DefaultContextWithDB(s.T(), key, sdk.NewTransientStoreKey("transient_test"))
ctx := testCtx.Ctx.WithBlockHeader(tmproto.Header{Time: tmtime.Now()})
encCfg := moduletestutil.MakeTestEncodingConfig()
// gomock initializations
ctrl := gomock.NewController(s.T())
s.stakingKeeper = slashingtestutil.NewMockStakingKeeper(ctrl)
s.ctx = ctx
s.slashingKeeper = slashingkeeper.NewKeeper(
encCfg.Codec,
encCfg.Amino,
key,
s.stakingKeeper,
sdk.AccAddress(crypto.AddressHash([]byte(govtypes.ModuleName))).String(),
)
s.Require().NoError(err)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
s.accountKeeper.SetParams(ctx, authtypes.DefaultParams())
s.bankKeeper.SetParams(ctx, banktypes.DefaultParams())
// set test params
s.slashingKeeper.SetParams(ctx, testslashing.TestParams())
addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 5, s.stakingKeeper.TokensFromConsensusPower(ctx, 200))
slashingtypes.RegisterInterfaces(encCfg.InterfaceRegistry)
queryHelper := baseapp.NewQueryServerTestHelper(ctx, encCfg.InterfaceRegistry)
slashingtypes.RegisterQueryServer(queryHelper, s.slashingKeeper)
info1 := types.NewValidatorSigningInfo(sdk.ConsAddress(addrDels[0]), int64(4), int64(3),
time.Unix(2, 0), false, int64(10))
info2 := types.NewValidatorSigningInfo(sdk.ConsAddress(addrDels[1]), int64(5), int64(4),
time.Unix(2, 0), false, int64(10))
s.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), info1)
s.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[1]), info2)
queryHelper := baseapp.NewQueryServerTestHelper(ctx, s.interfaceRegistry)
types.RegisterQueryServer(queryHelper, s.slashingKeeper)
queryClient := types.NewQueryClient(queryHelper)
s.queryClient = queryClient
s.addrDels = addrDels
s.ctx = ctx
s.queryClient = slashingtypes.NewQueryClient(queryHelper)
s.msgServer = slashingkeeper.NewMsgServerImpl(s.slashingKeeper)
}
func (s *KeeperTestSuite) TestUnJailNotBonded() {
ctx := s.ctx
func (s *KeeperTestSuite) TestPubkey() {
ctx, keeper := s.ctx, s.slashingKeeper
require := s.Require()
p := s.stakingKeeper.GetParams(ctx)
p.MaxValidators = 5
s.stakingKeeper.SetParams(ctx, p)
_, pubKey, addr := testdata.KeyTestPubAddr()
require.NoError(keeper.AddPubkey(ctx, pubKey))
addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 6, s.stakingKeeper.TokensFromConsensusPower(ctx, 200))
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrDels)
pks := simtestutil.CreateTestPubKeys(6)
tstaking := teststaking.NewHelper(s.T(), ctx, s.stakingKeeper)
// create max (5) validators all with the same power
for i := uint32(0); i < p.MaxValidators; i++ {
addr, val := valAddrs[i], pks[i]
tstaking.CreateValidatorWithValPower(addr, val, 100, true)
}
staking.EndBlocker(ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
// create a 6th validator with less power than the cliff validator (won't be bonded)
addr, val := valAddrs[5], pks[5]
amt := s.stakingKeeper.TokensFromConsensusPower(ctx, 50)
msg := tstaking.CreateValidatorMsg(addr, val, amt)
msg.MinSelfDelegation = amt
res, err := tstaking.CreateValidatorWithMsg(sdk.WrapSDKContext(ctx), msg)
s.Require().NoError(err)
s.Require().NotNil(res)
staking.EndBlocker(ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
tstaking.CheckValidator(addr, stakingtypes.Unbonded, false)
// unbond below minimum self-delegation
s.Require().Equal(p.BondDenom, tstaking.Denom)
tstaking.Undelegate(sdk.AccAddress(addr), addr, s.stakingKeeper.TokensFromConsensusPower(ctx, 1), true)
staking.EndBlocker(ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
// verify that validator is jailed
tstaking.CheckValidator(addr, -1, true)
// verify we cannot unjail (yet)
s.Require().Error(s.slashingKeeper.Unjail(ctx, addr))
staking.EndBlocker(ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
// bond to meet minimum self-delegation
tstaking.DelegateWithPower(sdk.AccAddress(addr), addr, 1)
staking.EndBlocker(ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
// verify we can immediately unjail
s.Require().NoError(s.slashingKeeper.Unjail(ctx, addr))
tstaking.CheckValidator(addr, -1, false)
}
// Test a new validator entering the validator set
// Ensure that SigningInfo.StartHeight is set correctly
// and that they are not immediately jailed
func (s *KeeperTestSuite) TestHandleNewValidator() {
ctx := s.ctx
addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 1, s.stakingKeeper.TokensFromConsensusPower(ctx, 0))
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrDels)
pks := simtestutil.CreateTestPubKeys(1)
addr, val := valAddrs[0], pks[0]
tstaking := teststaking.NewHelper(s.T(), ctx, s.stakingKeeper)
ctx = ctx.WithBlockHeight(s.slashingKeeper.SignedBlocksWindow(ctx) + 1)
// Validator created
amt := tstaking.CreateValidatorWithValPower(addr, val, 100, true)
staking.EndBlocker(ctx, s.stakingKeeper)
s.Require().Equal(
s.bankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)),
sdk.NewCoins(sdk.NewCoin(s.stakingKeeper.GetParams(ctx).BondDenom, InitTokens.Sub(amt))),
)
s.Require().Equal(amt, s.stakingKeeper.Validator(ctx, addr).GetBondedTokens())
// Now a validator, for two blocks
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), 100, true)
ctx = ctx.WithBlockHeight(s.slashingKeeper.SignedBlocksWindow(ctx) + 2)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), 100, false)
info, found := s.slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
s.Require().True(found)
s.Require().Equal(s.slashingKeeper.SignedBlocksWindow(ctx)+1, info.StartHeight)
s.Require().Equal(int64(2), info.IndexOffset)
s.Require().Equal(int64(1), info.MissedBlocksCounter)
s.Require().Equal(time.Unix(0, 0).UTC(), info.JailedUntil)
// validator should be bonded still, should not have been jailed or slashed
validator, _ := s.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
s.Require().Equal(stakingtypes.Bonded, validator.GetStatus())
bondPool := s.stakingKeeper.GetBondedPool(ctx)
expTokens := s.stakingKeeper.TokensFromConsensusPower(ctx, 100)
// adding genesis validator tokens
expTokens = expTokens.Add(s.stakingKeeper.TokensFromConsensusPower(ctx, 1))
s.Require().True(expTokens.Equal(s.bankKeeper.GetBalance(ctx, bondPool.GetAddress(), s.stakingKeeper.BondDenom(ctx)).Amount))
}
// Test a jailed validator being "down" twice
// Ensure that they're only slashed once
func (s *KeeperTestSuite) TestHandleAlreadyJailed() {
// initial setup
ctx := s.ctx
addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 1, s.stakingKeeper.TokensFromConsensusPower(ctx, 200))
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrDels)
pks := simtestutil.CreateTestPubKeys(1)
addr, val := valAddrs[0], pks[0]
power := int64(100)
tstaking := teststaking.NewHelper(s.T(), ctx, s.stakingKeeper)
amt := tstaking.CreateValidatorWithValPower(addr, val, power, true)
staking.EndBlocker(ctx, s.stakingKeeper)
// 1000 first blocks OK
height := int64(0)
for ; height < s.slashingKeeper.SignedBlocksWindow(ctx); height++ {
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true)
}
// 501 blocks missed
for ; height < s.slashingKeeper.SignedBlocksWindow(ctx)+(s.slashingKeeper.SignedBlocksWindow(ctx)-s.slashingKeeper.MinSignedPerWindow(ctx))+1; height++ {
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
}
// end block
staking.EndBlocker(ctx, s.stakingKeeper)
// validator should have been jailed and slashed
validator, _ := s.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
s.Require().Equal(stakingtypes.Unbonding, validator.GetStatus())
// validator should have been slashed
resultingTokens := amt.Sub(s.stakingKeeper.TokensFromConsensusPower(ctx, 1))
s.Require().Equal(resultingTokens, validator.GetTokens())
// another block missed
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
// validator should not have been slashed twice
validator, _ = s.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
s.Require().Equal(resultingTokens, validator.GetTokens())
}
// Test a validator dipping in and out of the validator set
// Ensure that missed blocks are tracked correctly and that
// the start height of the signing info is reset correctly
func (s *KeeperTestSuite) TestValidatorDippingInAndOut() {
// initial setup
// TestParams set the SignedBlocksWindow to 1000 and MaxMissedBlocksPerWindow to 500
ctx := s.ctx
s.slashingKeeper.SetParams(ctx, testslashing.TestParams())
params := s.stakingKeeper.GetParams(ctx)
params.MaxValidators = 1
s.stakingKeeper.SetParams(ctx, params)
power := int64(100)
pks := simtestutil.CreateTestPubKeys(3)
simtestutil.AddTestAddrsFromPubKeys(s.bankKeeper, s.stakingKeeper, ctx, pks, s.stakingKeeper.TokensFromConsensusPower(ctx, 200))
addr, val := pks[0].Address(), pks[0]
consAddr := sdk.ConsAddress(addr)
tstaking := teststaking.NewHelper(s.T(), ctx, s.stakingKeeper)
valAddr := sdk.ValAddress(addr)
tstaking.CreateValidatorWithValPower(valAddr, val, power, true)
validatorUpdates := staking.EndBlocker(ctx, s.stakingKeeper)
s.Require().Equal(2, len(validatorUpdates))
tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false)
// 100 first blocks OK
height := int64(0)
for ; height < int64(100); height++ {
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true)
}
// kick first validator out of validator set
tstaking.CreateValidatorWithValPower(sdk.ValAddress(pks[1].Address()), pks[1], power+1, true)
validatorUpdates = staking.EndBlocker(ctx, s.stakingKeeper)
s.Require().Equal(2, len(validatorUpdates))
tstaking.CheckValidator(sdk.ValAddress(pks[1].Address()), stakingtypes.Bonded, false)
tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, false)
// 600 more blocks happened
height = height + 600
ctx = ctx.WithBlockHeight(height)
// validator added back in
tstaking.DelegateWithPower(sdk.AccAddress(pks[2].Address()), valAddr, 50)
validatorUpdates = staking.EndBlocker(ctx, s.stakingKeeper)
s.Require().Equal(2, len(validatorUpdates))
tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false)
newPower := power + 50
// validator misses a block
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
height++
// shouldn't be jailed/kicked yet
tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false)
// validator misses an additional 500 more blocks, after the cooling off period of SignedBlockWindow (here 1000 blocks).
latest := s.slashingKeeper.SignedBlocksWindow(ctx) + height
for ; height < latest+s.slashingKeeper.MinSignedPerWindow(ctx); height++ {
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
}
// should now be jailed & kicked
staking.EndBlocker(ctx, s.stakingKeeper)
tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, true)
// check all the signing information
signInfo, found := s.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr)
s.Require().True(found)
s.Require().Equal(int64(700), signInfo.StartHeight)
s.Require().Equal(int64(499), signInfo.MissedBlocksCounter)
s.Require().Equal(int64(499), signInfo.IndexOffset)
// some blocks pass
height = int64(5000)
ctx = ctx.WithBlockHeight(height)
// validator rejoins and starts signing again
s.stakingKeeper.Unjail(ctx, consAddr)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, true)
// validator should not be kicked since we reset counter/array when it was jailed
staking.EndBlocker(ctx, s.stakingKeeper)
tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false)
// check start height is correctly set
signInfo, found = s.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr)
s.Require().True(found)
s.Require().Equal(height, signInfo.StartHeight)
// validator misses 501 blocks after SignedBlockWindow period (1000 blocks)
latest = s.slashingKeeper.SignedBlocksWindow(ctx) + height
for ; height < latest+s.slashingKeeper.MinSignedPerWindow(ctx); height++ {
ctx = ctx.WithBlockHeight(height)
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
}
// validator should now be jailed & kicked
staking.EndBlocker(ctx, s.stakingKeeper)
tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, true)
expectedPubKey, err := keeper.GetPubkey(ctx, addr.Bytes())
require.NoError(err)
require.Equal(pubKey, expectedPubKey)
}
func TestKeeperTestSuite(t *testing.T) {

View File

@ -3,32 +3,36 @@ package keeper_test
import (
"time"
"github.com/golang/mock/gomock"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
)
func (s *KeeperTestSuite) TestUpdateParams() {
require := s.Require()
minSignedPerWindow, err := sdk.NewDecFromStr("0.60")
s.Require().NoError(err)
require.NoError(err)
slashFractionDoubleSign, err := sdk.NewDecFromStr("0.022")
s.Require().NoError(err)
require.NoError(err)
slashFractionDowntime, err := sdk.NewDecFromStr("0.0089")
s.Require().NoError(err)
require.NoError(err)
invalidVal, err := sdk.NewDecFromStr("-1")
s.Require().NoError(err)
require.NoError(err)
testCases := []struct {
name string
request *types.MsgUpdateParams
request *slashingtypes.MsgUpdateParams
expectErr bool
expErrMsg string
}{
{
name: "set invalid authority",
request: &types.MsgUpdateParams{
request: &slashingtypes.MsgUpdateParams{
Authority: "foo",
},
expectErr: true,
@ -36,9 +40,9 @@ func (s *KeeperTestSuite) TestUpdateParams() {
},
{
name: "set invalid signed blocks window",
request: &types.MsgUpdateParams{
request: &slashingtypes.MsgUpdateParams{
Authority: s.slashingKeeper.GetAuthority(),
Params: types.Params{
Params: slashingtypes.Params{
SignedBlocksWindow: 0,
MinSignedPerWindow: minSignedPerWindow,
DowntimeJailDuration: time.Duration(34800000000000),
@ -51,9 +55,9 @@ func (s *KeeperTestSuite) TestUpdateParams() {
},
{
name: "set invalid min signed per window",
request: &types.MsgUpdateParams{
request: &slashingtypes.MsgUpdateParams{
Authority: s.slashingKeeper.GetAuthority(),
Params: types.Params{
Params: slashingtypes.Params{
SignedBlocksWindow: int64(750),
MinSignedPerWindow: invalidVal,
DowntimeJailDuration: time.Duration(34800000000000),
@ -66,9 +70,9 @@ func (s *KeeperTestSuite) TestUpdateParams() {
},
{
name: "set invalid downtime jail duration",
request: &types.MsgUpdateParams{
request: &slashingtypes.MsgUpdateParams{
Authority: s.slashingKeeper.GetAuthority(),
Params: types.Params{
Params: slashingtypes.Params{
SignedBlocksWindow: int64(750),
MinSignedPerWindow: minSignedPerWindow,
DowntimeJailDuration: time.Duration(0),
@ -81,9 +85,9 @@ func (s *KeeperTestSuite) TestUpdateParams() {
},
{
name: "set invalid slash fraction double sign",
request: &types.MsgUpdateParams{
request: &slashingtypes.MsgUpdateParams{
Authority: s.slashingKeeper.GetAuthority(),
Params: types.Params{
Params: slashingtypes.Params{
SignedBlocksWindow: int64(750),
MinSignedPerWindow: minSignedPerWindow,
DowntimeJailDuration: time.Duration(10),
@ -96,9 +100,9 @@ func (s *KeeperTestSuite) TestUpdateParams() {
},
{
name: "set invalid slash fraction downtime",
request: &types.MsgUpdateParams{
request: &slashingtypes.MsgUpdateParams{
Authority: s.slashingKeeper.GetAuthority(),
Params: types.Params{
Params: slashingtypes.Params{
SignedBlocksWindow: int64(750),
MinSignedPerWindow: minSignedPerWindow,
DowntimeJailDuration: time.Duration(10),
@ -111,9 +115,9 @@ func (s *KeeperTestSuite) TestUpdateParams() {
},
{
name: "set full valid params",
request: &types.MsgUpdateParams{
request: &slashingtypes.MsgUpdateParams{
Authority: s.slashingKeeper.GetAuthority(),
Params: types.Params{
Params: slashingtypes.Params{
SignedBlocksWindow: int64(750),
MinSignedPerWindow: minSignedPerWindow,
DowntimeJailDuration: time.Duration(34800000000000),
@ -130,11 +134,23 @@ func (s *KeeperTestSuite) TestUpdateParams() {
s.Run(tc.name, func() {
_, err := s.msgServer.UpdateParams(s.ctx, tc.request)
if tc.expectErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.expErrMsg)
require.Error(err)
require.Contains(err.Error(), tc.expErrMsg)
} else {
s.Require().NoError(err)
require.NoError(err)
}
})
}
}
func (s *KeeperTestSuite) TestUnjail() {
addr := sdk.AccAddress([]byte("val1_______________"))
request := &slashingtypes.MsgUnjail{
ValidatorAddr: sdk.ValAddress(addr).String(),
}
s.stakingKeeper.EXPECT().Validator(gomock.Any(), gomock.Any()).Return(nil)
_, err := s.msgServer.Unjail(s.ctx, request)
s.Require().Error(err)
s.Require().Equal(err, slashingtypes.ErrNoValidatorForAddress)
}

View File

@ -8,17 +8,20 @@ import (
)
func (s *KeeperTestSuite) TestParams() {
ctx, keeper := s.ctx, s.slashingKeeper
require := s.Require()
minSignedPerWindow, err := sdk.NewDecFromStr("0.60")
s.Require().NoError(err)
require.NoError(err)
slashFractionDoubleSign, err := sdk.NewDecFromStr("0.022")
s.Require().NoError(err)
require.NoError(err)
slashFractionDowntime, err := sdk.NewDecFromStr("0.0089")
s.Require().NoError(err)
require.NoError(err)
invalidVal, err := sdk.NewDecFromStr("-1")
s.Require().NoError(err)
require.NoError(err)
testCases := []struct {
name string
@ -101,19 +104,24 @@ func (s *KeeperTestSuite) TestParams() {
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
expected := s.slashingKeeper.GetParams(s.ctx)
err := s.slashingKeeper.SetParams(s.ctx, tc.input)
expected := keeper.GetParams(ctx)
err := keeper.SetParams(ctx, tc.input)
if tc.expectErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.expErrMsg)
require.Error(err)
require.Contains(err.Error(), tc.expErrMsg)
} else {
expected = tc.input
s.Require().NoError(err)
require.NoError(err)
}
params := s.slashingKeeper.GetParams(s.ctx)
s.Require().Equal(expected, params)
params := keeper.GetParams(ctx)
require.Equal(params, expected)
require.Equal(keeper.SignedBlocksWindow(ctx), expected.SignedBlocksWindow)
require.Equal(keeper.MinSignedPerWindow(ctx), expected.MinSignedPerWindow.MulInt64(expected.SignedBlocksWindow).RoundInt64())
require.Equal(keeper.DowntimeJailDuration(ctx), expected.DowntimeJailDuration)
require.Equal(keeper.SlashFractionDoubleSign(ctx), expected.SlashFractionDoubleSign)
require.Equal(keeper.SlashFractionDowntime(ctx), expected.SlashFractionDowntime)
})
}
}

View File

@ -3,86 +3,91 @@ package keeper_test
import (
"time"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/slashing/testslashing"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
)
func (suite *KeeperTestSuite) TestGetSetValidatorSigningInfo() {
ctx := suite.ctx
func (s *KeeperTestSuite) TestValidatorSigningInfo() {
ctx, keeper := s.ctx, s.slashingKeeper
require := s.Require()
addrDels := suite.addrDels
info, found := suite.slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[2]))
suite.Require().False(found)
newInfo := types.NewValidatorSigningInfo(
sdk.ConsAddress(addrDels[2]),
int64(4),
signingInfo := slashingtypes.NewValidatorSigningInfo(
consAddr,
ctx.BlockHeight(),
int64(3),
time.Unix(2, 0),
false,
int64(10),
)
suite.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[2]), newInfo)
info, found = suite.slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[2]))
suite.Require().True(found)
suite.Require().Equal(info.StartHeight, int64(4))
suite.Require().Equal(info.IndexOffset, int64(3))
suite.Require().Equal(info.JailedUntil, time.Unix(2, 0).UTC())
suite.Require().Equal(info.MissedBlocksCounter, int64(10))
// set the validator signing information
keeper.SetValidatorSigningInfo(ctx, consAddr, signingInfo)
require.True(keeper.HasValidatorSigningInfo(ctx, consAddr))
info, found := keeper.GetValidatorSigningInfo(ctx, consAddr)
require.True(found)
require.Equal(info.StartHeight, ctx.BlockHeight())
require.Equal(info.IndexOffset, int64(3))
require.Equal(info.JailedUntil, time.Unix(2, 0).UTC())
require.Equal(info.MissedBlocksCounter, int64(10))
var signingInfos []slashingtypes.ValidatorSigningInfo
keeper.IterateValidatorSigningInfos(ctx, func(consAddr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) {
signingInfos = append(signingInfos, info)
return false
})
require.Equal(signingInfos[0].Address, signingInfo.Address)
// test Tombstone
keeper.Tombstone(ctx, consAddr)
require.True(keeper.IsTombstoned(ctx, consAddr))
// test JailUntil
jailTime := time.Now().Add(time.Hour).UTC()
keeper.JailUntil(ctx, consAddr, jailTime)
sInfo, _ := keeper.GetValidatorSigningInfo(ctx, consAddr)
require.Equal(sInfo.JailedUntil, jailTime)
}
func (suite *KeeperTestSuite) TestGetSetValidatorMissedBlockBitArray() {
ctx := suite.ctx
addrDels := simtestutil.AddTestAddrsIncremental(suite.bankKeeper, suite.stakingKeeper, ctx, 1, suite.stakingKeeper.TokensFromConsensusPower(ctx, 200))
func (s *KeeperTestSuite) TestValidatorMissedBlockBitArray() {
ctx, keeper := s.ctx, s.slashingKeeper
require := s.Require()
missed := suite.slashingKeeper.GetValidatorMissedBlockBitArray(ctx, sdk.ConsAddress(addrDels[0]), 0)
suite.Require().False(missed) // treat empty key as not missed
suite.slashingKeeper.SetValidatorMissedBlockBitArray(ctx, sdk.ConsAddress(addrDels[0]), 0, true)
missed = suite.slashingKeeper.GetValidatorMissedBlockBitArray(ctx, sdk.ConsAddress(addrDels[0]), 0)
suite.Require().True(missed) // now should be missed
}
func (suite *KeeperTestSuite) TestTombstoned() {
ctx := suite.ctx
addrDels := suite.addrDels
suite.Require().Panics(func() { suite.slashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[4])) })
suite.Require().False(suite.slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[4])))
newInfo := types.NewValidatorSigningInfo(
sdk.ConsAddress(addrDels[4]),
int64(4),
int64(3),
time.Unix(2, 0),
false,
int64(10),
)
suite.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[4]), newInfo)
suite.Require().False(suite.slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[4])))
suite.slashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[4]))
suite.Require().True(suite.slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[4])))
suite.Require().Panics(func() { suite.slashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[4])) })
}
func (suite *KeeperTestSuite) TestJailUntil() {
ctx := suite.ctx
addrDels := suite.addrDels
suite.Require().Panics(func() { suite.slashingKeeper.JailUntil(ctx, sdk.ConsAddress(addrDels[3]), time.Now()) })
newInfo := types.NewValidatorSigningInfo(
sdk.ConsAddress(addrDels[3]),
int64(4),
int64(3),
time.Unix(2, 0),
false,
int64(10),
)
suite.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[3]), newInfo)
suite.slashingKeeper.JailUntil(ctx, sdk.ConsAddress(addrDels[3]), time.Unix(253402300799, 0).UTC())
info, ok := suite.slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[3]))
suite.Require().True(ok)
suite.Require().Equal(time.Unix(253402300799, 0).UTC(), info.JailedUntil)
params := testslashing.TestParams()
params.SignedBlocksWindow = 100
require.NoError(keeper.SetParams(ctx, params))
testCases := []struct {
name string
index int64
missed bool
}{
{
name: "missed block with false",
index: 50,
missed: false,
},
{
name: "missed block with true",
index: 51,
missed: true,
},
}
for ind, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
keeper.SetValidatorMissedBlockBitArray(ctx, consAddr, tc.index, tc.missed)
missed := keeper.GetValidatorMissedBlockBitArray(ctx, consAddr, tc.index)
require.Equal(missed, tc.missed)
missedBlocks := keeper.GetValidatorMissedBlocks(ctx, consAddr)
require.Equal(len(missedBlocks), ind+1)
require.Equal(missedBlocks[ind].Index, tc.index)
require.Equal(missedBlocks[ind].Missed, tc.missed)
})
}
}

View File

@ -0,0 +1,425 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: x/slashing/types/expected_keepers.go
// Package testutil is a generated GoMock package.
package testutil
import (
reflect "reflect"
math "cosmossdk.io/math"
types "github.com/cosmos/cosmos-sdk/types"
types0 "github.com/cosmos/cosmos-sdk/x/auth/types"
types1 "github.com/cosmos/cosmos-sdk/x/params/types"
types2 "github.com/cosmos/cosmos-sdk/x/staking/types"
gomock "github.com/golang/mock/gomock"
)
// MockAccountKeeper is a mock of AccountKeeper interface.
type MockAccountKeeper struct {
ctrl *gomock.Controller
recorder *MockAccountKeeperMockRecorder
}
// MockAccountKeeperMockRecorder is the mock recorder for MockAccountKeeper.
type MockAccountKeeperMockRecorder struct {
mock *MockAccountKeeper
}
// NewMockAccountKeeper creates a new mock instance.
func NewMockAccountKeeper(ctrl *gomock.Controller) *MockAccountKeeper {
mock := &MockAccountKeeper{ctrl: ctrl}
mock.recorder = &MockAccountKeeperMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockAccountKeeper) EXPECT() *MockAccountKeeperMockRecorder {
return m.recorder
}
// GetAccount mocks base method.
func (m *MockAccountKeeper) GetAccount(ctx types.Context, addr types.AccAddress) types0.AccountI {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAccount", ctx, addr)
ret0, _ := ret[0].(types0.AccountI)
return ret0
}
// GetAccount indicates an expected call of GetAccount.
func (mr *MockAccountKeeperMockRecorder) GetAccount(ctx, addr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccount", reflect.TypeOf((*MockAccountKeeper)(nil).GetAccount), ctx, addr)
}
// IterateAccounts mocks base method.
func (m *MockAccountKeeper) IterateAccounts(ctx types.Context, process func(types0.AccountI) bool) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "IterateAccounts", ctx, process)
}
// IterateAccounts indicates an expected call of IterateAccounts.
func (mr *MockAccountKeeperMockRecorder) IterateAccounts(ctx, process interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateAccounts", reflect.TypeOf((*MockAccountKeeper)(nil).IterateAccounts), ctx, process)
}
// MockBankKeeper is a mock of BankKeeper interface.
type MockBankKeeper struct {
ctrl *gomock.Controller
recorder *MockBankKeeperMockRecorder
}
// MockBankKeeperMockRecorder is the mock recorder for MockBankKeeper.
type MockBankKeeperMockRecorder struct {
mock *MockBankKeeper
}
// NewMockBankKeeper creates a new mock instance.
func NewMockBankKeeper(ctrl *gomock.Controller) *MockBankKeeper {
mock := &MockBankKeeper{ctrl: ctrl}
mock.recorder = &MockBankKeeperMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockBankKeeper) EXPECT() *MockBankKeeperMockRecorder {
return m.recorder
}
// GetAllBalances mocks base method.
func (m *MockBankKeeper) GetAllBalances(ctx types.Context, addr types.AccAddress) types.Coins {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAllBalances", ctx, addr)
ret0, _ := ret[0].(types.Coins)
return ret0
}
// GetAllBalances indicates an expected call of GetAllBalances.
func (mr *MockBankKeeperMockRecorder) GetAllBalances(ctx, addr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllBalances", reflect.TypeOf((*MockBankKeeper)(nil).GetAllBalances), ctx, addr)
}
// GetBalance mocks base method.
func (m *MockBankKeeper) GetBalance(ctx types.Context, addr types.AccAddress, denom string) types.Coin {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBalance", ctx, addr, denom)
ret0, _ := ret[0].(types.Coin)
return ret0
}
// GetBalance indicates an expected call of GetBalance.
func (mr *MockBankKeeperMockRecorder) GetBalance(ctx, addr, denom interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalance", reflect.TypeOf((*MockBankKeeper)(nil).GetBalance), ctx, addr, denom)
}
// LockedCoins mocks base method.
func (m *MockBankKeeper) LockedCoins(ctx types.Context, addr types.AccAddress) types.Coins {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "LockedCoins", ctx, addr)
ret0, _ := ret[0].(types.Coins)
return ret0
}
// LockedCoins indicates an expected call of LockedCoins.
func (mr *MockBankKeeperMockRecorder) LockedCoins(ctx, addr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedCoins", reflect.TypeOf((*MockBankKeeper)(nil).LockedCoins), ctx, addr)
}
// SpendableCoins mocks base method.
func (m *MockBankKeeper) SpendableCoins(ctx types.Context, addr types.AccAddress) types.Coins {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SpendableCoins", ctx, addr)
ret0, _ := ret[0].(types.Coins)
return ret0
}
// SpendableCoins indicates an expected call of SpendableCoins.
func (mr *MockBankKeeperMockRecorder) SpendableCoins(ctx, addr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpendableCoins", reflect.TypeOf((*MockBankKeeper)(nil).SpendableCoins), ctx, addr)
}
// MockParamSubspace is a mock of ParamSubspace interface.
type MockParamSubspace struct {
ctrl *gomock.Controller
recorder *MockParamSubspaceMockRecorder
}
// MockParamSubspaceMockRecorder is the mock recorder for MockParamSubspace.
type MockParamSubspaceMockRecorder struct {
mock *MockParamSubspace
}
// NewMockParamSubspace creates a new mock instance.
func NewMockParamSubspace(ctrl *gomock.Controller) *MockParamSubspace {
mock := &MockParamSubspace{ctrl: ctrl}
mock.recorder = &MockParamSubspaceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockParamSubspace) EXPECT() *MockParamSubspaceMockRecorder {
return m.recorder
}
// Get mocks base method.
func (m *MockParamSubspace) Get(ctx types.Context, key []byte, ptr interface{}) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "Get", ctx, key, ptr)
}
// Get indicates an expected call of Get.
func (mr *MockParamSubspaceMockRecorder) Get(ctx, key, ptr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockParamSubspace)(nil).Get), ctx, key, ptr)
}
// GetParamSet mocks base method.
func (m *MockParamSubspace) GetParamSet(ctx types.Context, ps types1.ParamSet) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "GetParamSet", ctx, ps)
}
// GetParamSet indicates an expected call of GetParamSet.
func (mr *MockParamSubspaceMockRecorder) GetParamSet(ctx, ps interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParamSet", reflect.TypeOf((*MockParamSubspace)(nil).GetParamSet), ctx, ps)
}
// HasKeyTable mocks base method.
func (m *MockParamSubspace) HasKeyTable() bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HasKeyTable")
ret0, _ := ret[0].(bool)
return ret0
}
// HasKeyTable indicates an expected call of HasKeyTable.
func (mr *MockParamSubspaceMockRecorder) HasKeyTable() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasKeyTable", reflect.TypeOf((*MockParamSubspace)(nil).HasKeyTable))
}
// SetParamSet mocks base method.
func (m *MockParamSubspace) SetParamSet(ctx types.Context, ps types1.ParamSet) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "SetParamSet", ctx, ps)
}
// SetParamSet indicates an expected call of SetParamSet.
func (mr *MockParamSubspaceMockRecorder) SetParamSet(ctx, ps interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetParamSet", reflect.TypeOf((*MockParamSubspace)(nil).SetParamSet), ctx, ps)
}
// WithKeyTable mocks base method.
func (m *MockParamSubspace) WithKeyTable(table types1.KeyTable) types1.Subspace {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "WithKeyTable", table)
ret0, _ := ret[0].(types1.Subspace)
return ret0
}
// WithKeyTable indicates an expected call of WithKeyTable.
func (mr *MockParamSubspaceMockRecorder) WithKeyTable(table interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithKeyTable", reflect.TypeOf((*MockParamSubspace)(nil).WithKeyTable), table)
}
// MockStakingKeeper is a mock of StakingKeeper interface.
type MockStakingKeeper struct {
ctrl *gomock.Controller
recorder *MockStakingKeeperMockRecorder
}
// MockStakingKeeperMockRecorder is the mock recorder for MockStakingKeeper.
type MockStakingKeeperMockRecorder struct {
mock *MockStakingKeeper
}
// NewMockStakingKeeper creates a new mock instance.
func NewMockStakingKeeper(ctrl *gomock.Controller) *MockStakingKeeper {
mock := &MockStakingKeeper{ctrl: ctrl}
mock.recorder = &MockStakingKeeperMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder {
return m.recorder
}
// Delegation mocks base method.
func (m *MockStakingKeeper) Delegation(arg0 types.Context, arg1 types.AccAddress, arg2 types.ValAddress) types2.DelegationI {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delegation", arg0, arg1, arg2)
ret0, _ := ret[0].(types2.DelegationI)
return ret0
}
// Delegation indicates an expected call of Delegation.
func (mr *MockStakingKeeperMockRecorder) Delegation(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delegation", reflect.TypeOf((*MockStakingKeeper)(nil).Delegation), arg0, arg1, arg2)
}
// IterateValidators mocks base method.
func (m *MockStakingKeeper) IterateValidators(arg0 types.Context, arg1 func(int64, types2.ValidatorI) bool) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "IterateValidators", arg0, arg1)
}
// IterateValidators indicates an expected call of IterateValidators.
func (mr *MockStakingKeeperMockRecorder) IterateValidators(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateValidators", reflect.TypeOf((*MockStakingKeeper)(nil).IterateValidators), arg0, arg1)
}
// Jail mocks base method.
func (m *MockStakingKeeper) Jail(arg0 types.Context, arg1 types.ConsAddress) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "Jail", arg0, arg1)
}
// Jail indicates an expected call of Jail.
func (mr *MockStakingKeeperMockRecorder) Jail(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Jail", reflect.TypeOf((*MockStakingKeeper)(nil).Jail), arg0, arg1)
}
// MaxValidators mocks base method.
func (m *MockStakingKeeper) MaxValidators(arg0 types.Context) uint32 {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "MaxValidators", arg0)
ret0, _ := ret[0].(uint32)
return ret0
}
// MaxValidators indicates an expected call of MaxValidators.
func (mr *MockStakingKeeperMockRecorder) MaxValidators(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaxValidators", reflect.TypeOf((*MockStakingKeeper)(nil).MaxValidators), arg0)
}
// Slash mocks base method.
func (m *MockStakingKeeper) Slash(arg0 types.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 types.Dec) math.Int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Slash", arg0, arg1, arg2, arg3, arg4)
ret0, _ := ret[0].(math.Int)
return ret0
}
// Slash indicates an expected call of Slash.
func (mr *MockStakingKeeperMockRecorder) Slash(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Slash", reflect.TypeOf((*MockStakingKeeper)(nil).Slash), arg0, arg1, arg2, arg3, arg4)
}
// Unjail mocks base method.
func (m *MockStakingKeeper) Unjail(arg0 types.Context, arg1 types.ConsAddress) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "Unjail", arg0, arg1)
}
// Unjail indicates an expected call of Unjail.
func (mr *MockStakingKeeperMockRecorder) Unjail(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unjail", reflect.TypeOf((*MockStakingKeeper)(nil).Unjail), arg0, arg1)
}
// Validator mocks base method.
func (m *MockStakingKeeper) Validator(arg0 types.Context, arg1 types.ValAddress) types2.ValidatorI {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Validator", arg0, arg1)
ret0, _ := ret[0].(types2.ValidatorI)
return ret0
}
// Validator indicates an expected call of Validator.
func (mr *MockStakingKeeperMockRecorder) Validator(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validator", reflect.TypeOf((*MockStakingKeeper)(nil).Validator), arg0, arg1)
}
// ValidatorByConsAddr mocks base method.
func (m *MockStakingKeeper) ValidatorByConsAddr(arg0 types.Context, arg1 types.ConsAddress) types2.ValidatorI {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ValidatorByConsAddr", arg0, arg1)
ret0, _ := ret[0].(types2.ValidatorI)
return ret0
}
// ValidatorByConsAddr indicates an expected call of ValidatorByConsAddr.
func (mr *MockStakingKeeperMockRecorder) ValidatorByConsAddr(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorByConsAddr", reflect.TypeOf((*MockStakingKeeper)(nil).ValidatorByConsAddr), arg0, arg1)
}
// MockStakingHooks is a mock of StakingHooks interface.
type MockStakingHooks struct {
ctrl *gomock.Controller
recorder *MockStakingHooksMockRecorder
}
// MockStakingHooksMockRecorder is the mock recorder for MockStakingHooks.
type MockStakingHooksMockRecorder struct {
mock *MockStakingHooks
}
// NewMockStakingHooks creates a new mock instance.
func NewMockStakingHooks(ctrl *gomock.Controller) *MockStakingHooks {
mock := &MockStakingHooks{ctrl: ctrl}
mock.recorder = &MockStakingHooksMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockStakingHooks) EXPECT() *MockStakingHooksMockRecorder {
return m.recorder
}
// AfterValidatorBonded mocks base method.
func (m *MockStakingHooks) AfterValidatorBonded(ctx types.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AfterValidatorBonded", ctx, consAddr, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// AfterValidatorBonded indicates an expected call of AfterValidatorBonded.
func (mr *MockStakingHooksMockRecorder) AfterValidatorBonded(ctx, consAddr, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterValidatorBonded", reflect.TypeOf((*MockStakingHooks)(nil).AfterValidatorBonded), ctx, consAddr, valAddr)
}
// AfterValidatorCreated mocks base method.
func (m *MockStakingHooks) AfterValidatorCreated(ctx types.Context, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AfterValidatorCreated", ctx, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// AfterValidatorCreated indicates an expected call of AfterValidatorCreated.
func (mr *MockStakingHooksMockRecorder) AfterValidatorCreated(ctx, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterValidatorCreated", reflect.TypeOf((*MockStakingHooks)(nil).AfterValidatorCreated), ctx, valAddr)
}
// AfterValidatorRemoved mocks base method.
func (m *MockStakingHooks) AfterValidatorRemoved(ctx types.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AfterValidatorRemoved", ctx, consAddr, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// AfterValidatorRemoved indicates an expected call of AfterValidatorRemoved.
func (mr *MockStakingHooksMockRecorder) AfterValidatorRemoved(ctx, consAddr, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterValidatorRemoved", reflect.TypeOf((*MockStakingHooks)(nil).AfterValidatorRemoved), ctx, consAddr, valAddr)
}