feat: decouple x/slashing from simapp (#12315)
## Description Closes: #12195 --- ### 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... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing) - [ ] 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:
@@ -18,6 +18,15 @@ import (
|
||||
|
||||
type GenerateAccountStrategy func(int) []sdk.AccAddress
|
||||
|
||||
// AddTestAddrsFromPubKeys adds the addresses into the SimApp providing only the public keys.
|
||||
func AddTestAddrsFromPubKeys(bankKeeper bankkeeper.Keeper, stakingKeeper *stakingkeeper.Keeper, ctx sdk.Context, pubKeys []cryptotypes.PubKey, accAmt math.Int) {
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), accAmt))
|
||||
|
||||
for _, pk := range pubKeys {
|
||||
initAccountWithCoins(bankKeeper, ctx, sdk.AccAddress(pk.Address()), initCoins)
|
||||
}
|
||||
}
|
||||
|
||||
// AddTestAddrs constructs and returns accNum amount of accounts with an
|
||||
// initial balance of accAmt in random order
|
||||
func AddTestAddrs(bankKeeper bankkeeper.Keeper, stakingKeeper *stakingkeeper.Keeper, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress {
|
||||
|
||||
+33
-16
@@ -8,33 +8,50 @@ import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/testutil"
|
||||
"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"
|
||||
)
|
||||
|
||||
func TestBeginBlocker(t *testing.T) {
|
||||
app := simapp.Setup(t, false)
|
||||
var interfaceRegistry codectypes.InterfaceRegistry
|
||||
var bankKeeper bankkeeper.Keeper
|
||||
var stakingKeeper *stakingkeeper.Keeper
|
||||
var slashingKeeper slashingkeeper.Keeper
|
||||
|
||||
app, err := simtestutil.Setup(
|
||||
testutil.AppConfig,
|
||||
&interfaceRegistry,
|
||||
&bankKeeper,
|
||||
&stakingKeeper,
|
||||
&slashingKeeper,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
pks := simtestutil.CreateTestPubKeys(1)
|
||||
simapp.AddTestAddrsFromPubKeys(app, ctx, pks, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
simtestutil.AddTestAddrsFromPubKeys(bankKeeper, stakingKeeper, ctx, pks, stakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
addr, pk := sdk.ValAddress(pks[0].Address()), pks[0]
|
||||
tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper)
|
||||
tstaking := teststaking.NewHelper(t, ctx, stakingKeeper)
|
||||
|
||||
// bond the validator
|
||||
power := int64(100)
|
||||
amt := tstaking.CreateValidatorWithValPower(addr, pk, power, true)
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
require.Equal(
|
||||
t, app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)),
|
||||
sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.GetParams(ctx).BondDenom, InitTokens.Sub(amt))),
|
||||
t, bankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)),
|
||||
sdk.NewCoins(sdk.NewCoin(stakingKeeper.GetParams(ctx).BondDenom, InitTokens.Sub(amt))),
|
||||
)
|
||||
require.Equal(t, amt, app.StakingKeeper.Validator(ctx, addr).GetBondedTokens())
|
||||
require.Equal(t, amt, stakingKeeper.Validator(ctx, addr).GetBondedTokens())
|
||||
|
||||
val := abci.Validator{
|
||||
Address: pk.Address(),
|
||||
@@ -51,9 +68,9 @@ func TestBeginBlocker(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
slashing.BeginBlocker(ctx, req, app.SlashingKeeper)
|
||||
slashing.BeginBlocker(ctx, req, slashingKeeper)
|
||||
|
||||
info, found := app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(pk.Address()))
|
||||
info, found := slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(pk.Address()))
|
||||
require.True(t, found)
|
||||
require.Equal(t, ctx.BlockHeight(), info.StartHeight)
|
||||
require.Equal(t, int64(1), info.IndexOffset)
|
||||
@@ -63,7 +80,7 @@ func TestBeginBlocker(t *testing.T) {
|
||||
height := int64(0)
|
||||
|
||||
// for 1000 blocks, mark the validator as having signed
|
||||
for ; height < app.SlashingKeeper.SignedBlocksWindow(ctx); height++ {
|
||||
for ; height < slashingKeeper.SignedBlocksWindow(ctx); height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
req = abci.RequestBeginBlock{
|
||||
LastCommitInfo: abci.LastCommitInfo{
|
||||
@@ -74,11 +91,11 @@ func TestBeginBlocker(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
slashing.BeginBlocker(ctx, req, app.SlashingKeeper)
|
||||
slashing.BeginBlocker(ctx, req, slashingKeeper)
|
||||
}
|
||||
|
||||
// for 500 blocks, mark the validator as having not signed
|
||||
for ; height < ((app.SlashingKeeper.SignedBlocksWindow(ctx) * 2) - app.SlashingKeeper.MinSignedPerWindow(ctx) + 1); height++ {
|
||||
for ; height < ((slashingKeeper.SignedBlocksWindow(ctx) * 2) - slashingKeeper.MinSignedPerWindow(ctx) + 1); height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
req = abci.RequestBeginBlock{
|
||||
LastCommitInfo: abci.LastCommitInfo{
|
||||
@@ -89,14 +106,14 @@ func TestBeginBlocker(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
slashing.BeginBlocker(ctx, req, app.SlashingKeeper)
|
||||
slashing.BeginBlocker(ctx, req, slashingKeeper)
|
||||
}
|
||||
|
||||
// end block
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// validator should be jailed
|
||||
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(pk))
|
||||
validator, found := stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(pk))
|
||||
require.True(t, found)
|
||||
require.Equal(t, stakingtypes.Unbonding, validator.GetStatus())
|
||||
}
|
||||
|
||||
@@ -7,52 +7,67 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
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) {
|
||||
app := simapp.Setup(t, false)
|
||||
var slashingKeeper slashingkeeper.Keeper
|
||||
var stakingKeeper *stakingkeeper.Keeper
|
||||
var bankKeeper bankkeeper.Keeper
|
||||
|
||||
app, err := simtestutil.Setup(
|
||||
testutil.AppConfig,
|
||||
&slashingKeeper,
|
||||
&stakingKeeper,
|
||||
&bankKeeper,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
app.SlashingKeeper.SetParams(ctx, testslashing.TestParams())
|
||||
slashingKeeper.SetParams(ctx, testslashing.TestParams())
|
||||
|
||||
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
addrDels := simtestutil.AddTestAddrsIncremental(bankKeeper, stakingKeeper, ctx, 2, stakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
|
||||
info1 := types.NewValidatorSigningInfo(sdk.ConsAddress(addrDels[0]), int64(4), int64(3),
|
||||
time.Now().UTC().Add(100000000000), false, int64(10))
|
||||
info2 := types.NewValidatorSigningInfo(sdk.ConsAddress(addrDels[1]), int64(5), int64(4),
|
||||
time.Now().UTC().Add(10000000000), false, int64(10))
|
||||
|
||||
app.SlashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), info1)
|
||||
app.SlashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[1]), info2)
|
||||
genesisState := app.SlashingKeeper.ExportGenesis(ctx)
|
||||
slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), info1)
|
||||
slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[1]), info2)
|
||||
genesisState := slashingKeeper.ExportGenesis(ctx)
|
||||
|
||||
require.Equal(t, genesisState.Params, testslashing.TestParams())
|
||||
require.Len(t, genesisState.SigningInfos, 2)
|
||||
require.Equal(t, genesisState.SigningInfos[0].ValidatorSigningInfo, info1)
|
||||
|
||||
// Tombstone validators after genesis shouldn't effect genesis state
|
||||
app.SlashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
app.SlashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[1]))
|
||||
slashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
slashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[1]))
|
||||
|
||||
ok := app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
ok := slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
require.True(t, ok)
|
||||
|
||||
newInfo1, ok := app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
newInfo1, ok := slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
require.NotEqual(t, info1, newInfo1)
|
||||
// Initialise genesis with genesis state before tombstone
|
||||
|
||||
app.SlashingKeeper.InitGenesis(ctx, app.StakingKeeper, genesisState)
|
||||
slashingKeeper.InitGenesis(ctx, stakingKeeper, genesisState)
|
||||
|
||||
// Validator isTombstoned should return false as GenesisState is initialised
|
||||
ok = app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
ok = slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
require.False(t, ok)
|
||||
|
||||
newInfo1, ok = app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
newInfo2, ok := app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[1]))
|
||||
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)
|
||||
|
||||
@@ -2,60 +2,14 @@ package keeper_test
|
||||
|
||||
import (
|
||||
gocontext "context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/testslashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
)
|
||||
|
||||
type SlashingTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
app *simapp.SimApp
|
||||
ctx sdk.Context
|
||||
queryClient types.QueryClient
|
||||
addrDels []sdk.AccAddress
|
||||
}
|
||||
|
||||
func (suite *SlashingTestSuite) SetupTest() {
|
||||
app := simapp.Setup(suite.T(), false)
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
app.AccountKeeper.SetParams(ctx, authtypes.DefaultParams())
|
||||
app.BankKeeper.SetParams(ctx, banktypes.DefaultParams())
|
||||
app.SlashingKeeper.SetParams(ctx, testslashing.TestParams())
|
||||
|
||||
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
|
||||
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))
|
||||
|
||||
app.SlashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), info1)
|
||||
app.SlashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[1]), info2)
|
||||
|
||||
suite.app = app
|
||||
suite.ctx = ctx
|
||||
suite.addrDels = addrDels
|
||||
|
||||
queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry())
|
||||
types.RegisterQueryServer(queryHelper, app.SlashingKeeper)
|
||||
queryClient := types.NewQueryClient(queryHelper)
|
||||
suite.queryClient = queryClient
|
||||
}
|
||||
|
||||
func (suite *SlashingTestSuite) TestGRPCQueryParams() {
|
||||
func (suite *KeeperTestSuite) TestGRPCQueryParams() {
|
||||
queryClient := suite.queryClient
|
||||
paramsResp, err := queryClient.Params(gocontext.Background(), &types.QueryParamsRequest{})
|
||||
|
||||
@@ -63,7 +17,7 @@ func (suite *SlashingTestSuite) TestGRPCQueryParams() {
|
||||
suite.Equal(testslashing.TestParams(), paramsResp.Params)
|
||||
}
|
||||
|
||||
func (suite *SlashingTestSuite) TestGRPCSigningInfo() {
|
||||
func (suite *KeeperTestSuite) TestGRPCSigningInfo() {
|
||||
queryClient := suite.queryClient
|
||||
|
||||
infoResp, err := queryClient.SigningInfo(gocontext.Background(), &types.QuerySigningInfoRequest{ConsAddress: ""})
|
||||
@@ -71,7 +25,7 @@ func (suite *SlashingTestSuite) TestGRPCSigningInfo() {
|
||||
suite.Nil(infoResp)
|
||||
|
||||
consAddr := sdk.ConsAddress(suite.addrDels[0])
|
||||
info, found := suite.app.SlashingKeeper.GetValidatorSigningInfo(suite.ctx, consAddr)
|
||||
info, found := suite.slashingKeeper.GetValidatorSigningInfo(suite.ctx, consAddr)
|
||||
suite.True(found)
|
||||
|
||||
infoResp, err = queryClient.SigningInfo(gocontext.Background(),
|
||||
@@ -80,12 +34,12 @@ func (suite *SlashingTestSuite) TestGRPCSigningInfo() {
|
||||
suite.Equal(info, infoResp.ValSigningInfo)
|
||||
}
|
||||
|
||||
func (suite *SlashingTestSuite) TestGRPCSigningInfos() {
|
||||
func (suite *KeeperTestSuite) TestGRPCSigningInfos() {
|
||||
queryClient := suite.queryClient
|
||||
|
||||
var signingInfos []types.ValidatorSigningInfo
|
||||
|
||||
suite.app.SlashingKeeper.IterateValidatorSigningInfos(suite.ctx, func(consAddr sdk.ConsAddress, info types.ValidatorSigningInfo) (stop bool) {
|
||||
suite.slashingKeeper.IterateValidatorSigningInfos(suite.ctx, func(consAddr sdk.ConsAddress, info types.ValidatorSigningInfo) (stop bool) {
|
||||
signingInfos = append(signingInfos, info)
|
||||
return false
|
||||
})
|
||||
@@ -104,7 +58,3 @@ func (suite *SlashingTestSuite) TestGRPCSigningInfos() {
|
||||
suite.NotNil(infoResp.Pagination.NextKey)
|
||||
suite.Equal(uint64(2), infoResp.Pagination.Total)
|
||||
}
|
||||
|
||||
func TestSlashingTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(SlashingTestSuite))
|
||||
}
|
||||
|
||||
+160
-100
@@ -4,30 +4,87 @@ import (
|
||||
"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/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
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"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/testslashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/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"
|
||||
)
|
||||
|
||||
func TestUnJailNotBonded(t *testing.T) {
|
||||
app := simapp.Setup(t, false)
|
||||
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
|
||||
}
|
||||
|
||||
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{})
|
||||
|
||||
p := app.StakingKeeper.GetParams(ctx)
|
||||
p.MaxValidators = 5
|
||||
app.StakingKeeper.SetParams(ctx, p)
|
||||
s.accountKeeper.SetParams(ctx, authtypes.DefaultParams())
|
||||
s.bankKeeper.SetParams(ctx, banktypes.DefaultParams())
|
||||
s.slashingKeeper.SetParams(ctx, testslashing.TestParams())
|
||||
|
||||
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 6, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 5, s.stakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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(t, ctx, app.StakingKeeper)
|
||||
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++ {
|
||||
@@ -35,46 +92,46 @@ func TestUnJailNotBonded(t *testing.T) {
|
||||
tstaking.CreateValidatorWithValPower(addr, val, 100, true)
|
||||
}
|
||||
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
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 := app.StakingKeeper.TokensFromConsensusPower(ctx, 50)
|
||||
amt := s.stakingKeeper.TokensFromConsensusPower(ctx, 50)
|
||||
msg := tstaking.CreateValidatorMsg(addr, val, amt)
|
||||
msg.MinSelfDelegation = amt
|
||||
res, err := tstaking.CreateValidatorWithMsg(sdk.WrapSDKContext(ctx), msg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(res)
|
||||
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
staking.EndBlocker(ctx, s.stakingKeeper)
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
tstaking.CheckValidator(addr, stakingtypes.Unbonded, false)
|
||||
|
||||
// unbond below minimum self-delegation
|
||||
require.Equal(t, p.BondDenom, tstaking.Denom)
|
||||
tstaking.Undelegate(sdk.AccAddress(addr), addr, app.StakingKeeper.TokensFromConsensusPower(ctx, 1), true)
|
||||
s.Require().Equal(p.BondDenom, tstaking.Denom)
|
||||
tstaking.Undelegate(sdk.AccAddress(addr), addr, s.stakingKeeper.TokensFromConsensusPower(ctx, 1), true)
|
||||
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
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)
|
||||
require.Error(t, app.SlashingKeeper.Unjail(ctx, addr))
|
||||
s.Require().Error(s.slashingKeeper.Unjail(ctx, addr))
|
||||
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
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, app.StakingKeeper)
|
||||
staking.EndBlocker(ctx, s.stakingKeeper)
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// verify we can immediately unjail
|
||||
require.NoError(t, app.SlashingKeeper.Unjail(ctx, addr))
|
||||
s.Require().NoError(s.slashingKeeper.Unjail(ctx, addr))
|
||||
|
||||
tstaking.CheckValidator(addr, -1, false)
|
||||
}
|
||||
@@ -82,139 +139,138 @@ func TestUnJailNotBonded(t *testing.T) {
|
||||
// Test a new validator entering the validator set
|
||||
// Ensure that SigningInfo.StartHeight is set correctly
|
||||
// and that they are not immediately jailed
|
||||
func TestHandleNewValidator(t *testing.T) {
|
||||
app := simapp.Setup(t, false)
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
func (s *KeeperTestSuite) TestHandleNewValidator() {
|
||||
ctx := s.ctx
|
||||
|
||||
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
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(t, ctx, app.StakingKeeper)
|
||||
ctx = ctx.WithBlockHeight(app.SlashingKeeper.SignedBlocksWindow(ctx) + 1)
|
||||
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, app.StakingKeeper)
|
||||
require.Equal(
|
||||
t, app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)),
|
||||
sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.GetParams(ctx).BondDenom, InitTokens.Sub(amt))),
|
||||
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))),
|
||||
)
|
||||
require.Equal(t, amt, app.StakingKeeper.Validator(ctx, addr).GetBondedTokens())
|
||||
s.Require().Equal(amt, s.stakingKeeper.Validator(ctx, addr).GetBondedTokens())
|
||||
|
||||
// Now a validator, for two blocks
|
||||
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), 100, true)
|
||||
ctx = ctx.WithBlockHeight(app.SlashingKeeper.SignedBlocksWindow(ctx) + 2)
|
||||
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), 100, false)
|
||||
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 := app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||
require.True(t, found)
|
||||
require.Equal(t, app.SlashingKeeper.SignedBlocksWindow(ctx)+1, info.StartHeight)
|
||||
require.Equal(t, int64(2), info.IndexOffset)
|
||||
require.Equal(t, int64(1), info.MissedBlocksCounter)
|
||||
require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil)
|
||||
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, _ := app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||
require.Equal(t, stakingtypes.Bonded, validator.GetStatus())
|
||||
bondPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||
expTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 100)
|
||||
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(app.StakingKeeper.TokensFromConsensusPower(ctx, 1))
|
||||
require.True(t, expTokens.Equal(app.BankKeeper.GetBalance(ctx, bondPool.GetAddress(), app.StakingKeeper.BondDenom(ctx)).Amount))
|
||||
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 TestHandleAlreadyJailed(t *testing.T) {
|
||||
func (s *KeeperTestSuite) TestHandleAlreadyJailed() {
|
||||
// initial setup
|
||||
app := simapp.Setup(t, false)
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
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(t, ctx, app.StakingKeeper)
|
||||
tstaking := teststaking.NewHelper(s.T(), ctx, s.stakingKeeper)
|
||||
|
||||
amt := tstaking.CreateValidatorWithValPower(addr, val, power, true)
|
||||
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
staking.EndBlocker(ctx, s.stakingKeeper)
|
||||
|
||||
// 1000 first blocks OK
|
||||
height := int64(0)
|
||||
for ; height < app.SlashingKeeper.SignedBlocksWindow(ctx); height++ {
|
||||
for ; height < s.slashingKeeper.SignedBlocksWindow(ctx); height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true)
|
||||
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true)
|
||||
}
|
||||
|
||||
// 501 blocks missed
|
||||
for ; height < app.SlashingKeeper.SignedBlocksWindow(ctx)+(app.SlashingKeeper.SignedBlocksWindow(ctx)-app.SlashingKeeper.MinSignedPerWindow(ctx))+1; height++ {
|
||||
for ; height < s.slashingKeeper.SignedBlocksWindow(ctx)+(s.slashingKeeper.SignedBlocksWindow(ctx)-s.slashingKeeper.MinSignedPerWindow(ctx))+1; height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
|
||||
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
|
||||
}
|
||||
|
||||
// end block
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
staking.EndBlocker(ctx, s.stakingKeeper)
|
||||
|
||||
// validator should have been jailed and slashed
|
||||
validator, _ := app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||
require.Equal(t, stakingtypes.Unbonding, validator.GetStatus())
|
||||
validator, _ := s.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||
s.Require().Equal(stakingtypes.Unbonding, validator.GetStatus())
|
||||
|
||||
// validator should have been slashed
|
||||
resultingTokens := amt.Sub(app.StakingKeeper.TokensFromConsensusPower(ctx, 1))
|
||||
require.Equal(t, resultingTokens, validator.GetTokens())
|
||||
resultingTokens := amt.Sub(s.stakingKeeper.TokensFromConsensusPower(ctx, 1))
|
||||
s.Require().Equal(resultingTokens, validator.GetTokens())
|
||||
|
||||
// another block missed
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
|
||||
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false)
|
||||
|
||||
// validator should not have been slashed twice
|
||||
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||
require.Equal(t, resultingTokens, validator.GetTokens())
|
||||
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 TestValidatorDippingInAndOut(t *testing.T) {
|
||||
func (s *KeeperTestSuite) TestValidatorDippingInAndOut() {
|
||||
// initial setup
|
||||
// TestParams set the SignedBlocksWindow to 1000 and MaxMissedBlocksPerWindow to 500
|
||||
app := simapp.Setup(t, false)
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
app.SlashingKeeper.SetParams(ctx, testslashing.TestParams())
|
||||
|
||||
params := app.StakingKeeper.GetParams(ctx)
|
||||
ctx := s.ctx
|
||||
s.slashingKeeper.SetParams(ctx, testslashing.TestParams())
|
||||
|
||||
params := s.stakingKeeper.GetParams(ctx)
|
||||
params.MaxValidators = 1
|
||||
app.StakingKeeper.SetParams(ctx, params)
|
||||
s.stakingKeeper.SetParams(ctx, params)
|
||||
power := int64(100)
|
||||
|
||||
pks := simtestutil.CreateTestPubKeys(3)
|
||||
simapp.AddTestAddrsFromPubKeys(app, ctx, pks, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
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(t, ctx, app.StakingKeeper)
|
||||
tstaking := teststaking.NewHelper(s.T(), ctx, s.stakingKeeper)
|
||||
valAddr := sdk.ValAddress(addr)
|
||||
|
||||
tstaking.CreateValidatorWithValPower(valAddr, val, power, true)
|
||||
validatorUpdates := staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
require.Equal(t, 2, len(validatorUpdates))
|
||||
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)
|
||||
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true)
|
||||
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, app.StakingKeeper)
|
||||
require.Equal(t, 2, len(validatorUpdates))
|
||||
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)
|
||||
|
||||
@@ -225,62 +281,66 @@ func TestValidatorDippingInAndOut(t *testing.T) {
|
||||
// validator added back in
|
||||
tstaking.DelegateWithPower(sdk.AccAddress(pks[2].Address()), valAddr, 50)
|
||||
|
||||
validatorUpdates = staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
require.Equal(t, 2, len(validatorUpdates))
|
||||
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
|
||||
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
|
||||
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 := app.SlashingKeeper.SignedBlocksWindow(ctx) + height
|
||||
for ; height < latest+app.SlashingKeeper.MinSignedPerWindow(ctx); height++ {
|
||||
latest := s.slashingKeeper.SignedBlocksWindow(ctx) + height
|
||||
for ; height < latest+s.slashingKeeper.MinSignedPerWindow(ctx); height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
|
||||
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
|
||||
}
|
||||
|
||||
// should now be jailed & kicked
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
staking.EndBlocker(ctx, s.stakingKeeper)
|
||||
tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, true)
|
||||
|
||||
// check all the signing information
|
||||
signInfo, found := app.SlashingKeeper.GetValidatorSigningInfo(ctx, consAddr)
|
||||
require.True(t, found)
|
||||
require.Equal(t, int64(700), signInfo.StartHeight)
|
||||
require.Equal(t, int64(499), signInfo.MissedBlocksCounter)
|
||||
require.Equal(t, int64(499), signInfo.IndexOffset)
|
||||
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
|
||||
app.StakingKeeper.Unjail(ctx, consAddr)
|
||||
s.stakingKeeper.Unjail(ctx, consAddr)
|
||||
|
||||
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, true)
|
||||
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, app.StakingKeeper)
|
||||
staking.EndBlocker(ctx, s.stakingKeeper)
|
||||
tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false)
|
||||
|
||||
// check start height is correctly set
|
||||
signInfo, found = app.SlashingKeeper.GetValidatorSigningInfo(ctx, consAddr)
|
||||
require.True(t, found)
|
||||
require.Equal(t, height, signInfo.StartHeight)
|
||||
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 = app.SlashingKeeper.SignedBlocksWindow(ctx) + height
|
||||
for ; height < latest+app.SlashingKeeper.MinSignedPerWindow(ctx); height++ {
|
||||
latest = s.slashingKeeper.SignedBlocksWindow(ctx) + height
|
||||
for ; height < latest+s.slashingKeeper.MinSignedPerWindow(ctx); height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
|
||||
s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false)
|
||||
}
|
||||
|
||||
// validator should now be jailed & kicked
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
staking.EndBlocker(ctx, s.stakingKeeper)
|
||||
tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, true)
|
||||
}
|
||||
|
||||
func TestKeeperTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(KeeperTestSuite))
|
||||
}
|
||||
|
||||
@@ -9,36 +9,52 @@ import (
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/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"
|
||||
)
|
||||
|
||||
func TestNewQuerier(t *testing.T) {
|
||||
app := simapp.Setup(t, false)
|
||||
var slashingKeeper slashingkeeper.Keeper
|
||||
var legacyAmino *codec.LegacyAmino
|
||||
app, err := simtestutil.Setup(
|
||||
testutil.AppConfig,
|
||||
&legacyAmino,
|
||||
&slashingKeeper,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
app.SlashingKeeper.SetParams(ctx, testslashing.TestParams())
|
||||
legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino())
|
||||
querier := keeper.NewQuerier(app.SlashingKeeper, legacyQuerierCdc.LegacyAmino)
|
||||
slashingKeeper.SetParams(ctx, testslashing.TestParams())
|
||||
legacyQuerierCdc := codec.NewAminoCodec(legacyAmino)
|
||||
querier := keeper.NewQuerier(slashingKeeper, legacyQuerierCdc.LegacyAmino)
|
||||
|
||||
query := abci.RequestQuery{
|
||||
Path: "",
|
||||
Data: []byte{},
|
||||
}
|
||||
|
||||
_, err := querier(ctx, []string{types.QueryParameters}, query)
|
||||
_, err = querier(ctx, []string{types.QueryParameters}, query)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestQueryParams(t *testing.T) {
|
||||
var slashingKeeper slashingkeeper.Keeper
|
||||
app, err := simtestutil.Setup(
|
||||
testutil.AppConfig,
|
||||
&slashingKeeper,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
cdc := codec.NewLegacyAmino()
|
||||
legacyQuerierCdc := codec.NewAminoCodec(cdc)
|
||||
app := simapp.Setup(t, false)
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
app.SlashingKeeper.SetParams(ctx, testslashing.TestParams())
|
||||
slashingKeeper.SetParams(ctx, testslashing.TestParams())
|
||||
|
||||
querier := keeper.NewQuerier(app.SlashingKeeper, legacyQuerierCdc.LegacyAmino)
|
||||
querier := keeper.NewQuerier(slashingKeeper, legacyQuerierCdc.LegacyAmino)
|
||||
|
||||
query := abci.RequestQuery{
|
||||
Path: "",
|
||||
@@ -52,5 +68,5 @@ func TestQueryParams(t *testing.T) {
|
||||
|
||||
err = cdc.UnmarshalJSON(res, ¶ms)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, app.SlashingKeeper.GetParams(ctx), params)
|
||||
require.Equal(t, slashingKeeper.GetParams(ctx), params)
|
||||
}
|
||||
|
||||
@@ -1,96 +1,88 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
)
|
||||
|
||||
func TestGetSetValidatorSigningInfo(t *testing.T) {
|
||||
app := simapp.Setup(t, false)
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
func (suite *KeeperTestSuite) TestGetSetValidatorSigningInfo() {
|
||||
ctx := suite.ctx
|
||||
|
||||
info, found := app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
require.False(t, found)
|
||||
addrDels := suite.addrDels
|
||||
info, found := suite.slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[2]))
|
||||
suite.Require().False(found)
|
||||
newInfo := types.NewValidatorSigningInfo(
|
||||
sdk.ConsAddress(addrDels[0]),
|
||||
sdk.ConsAddress(addrDels[2]),
|
||||
int64(4),
|
||||
int64(3),
|
||||
time.Unix(2, 0),
|
||||
false,
|
||||
int64(10),
|
||||
)
|
||||
app.SlashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), newInfo)
|
||||
info, found = app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
require.True(t, found)
|
||||
require.Equal(t, info.StartHeight, int64(4))
|
||||
require.Equal(t, info.IndexOffset, int64(3))
|
||||
require.Equal(t, info.JailedUntil, time.Unix(2, 0).UTC())
|
||||
require.Equal(t, info.MissedBlocksCounter, 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))
|
||||
}
|
||||
|
||||
func TestGetSetValidatorMissedBlockBitArray(t *testing.T) {
|
||||
app := simapp.Setup(t, false)
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
func (suite *KeeperTestSuite) TestGetSetValidatorMissedBlockBitArray() {
|
||||
ctx := suite.ctx
|
||||
addrDels := simtestutil.AddTestAddrsIncremental(suite.bankKeeper, suite.stakingKeeper, ctx, 1, suite.stakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
|
||||
missed := app.SlashingKeeper.GetValidatorMissedBlockBitArray(ctx, sdk.ConsAddress(addrDels[0]), 0)
|
||||
require.False(t, missed) // treat empty key as not missed
|
||||
app.SlashingKeeper.SetValidatorMissedBlockBitArray(ctx, sdk.ConsAddress(addrDels[0]), 0, true)
|
||||
missed = app.SlashingKeeper.GetValidatorMissedBlockBitArray(ctx, sdk.ConsAddress(addrDels[0]), 0)
|
||||
require.True(t, missed) // now should be missed
|
||||
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 TestTombstoned(t *testing.T) {
|
||||
app := simapp.Setup(t, false)
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
func (suite *KeeperTestSuite) TestTombstoned() {
|
||||
ctx := suite.ctx
|
||||
addrDels := suite.addrDels
|
||||
|
||||
require.Panics(t, func() { app.SlashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[0])) })
|
||||
require.False(t, app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[0])))
|
||||
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[0]),
|
||||
sdk.ConsAddress(addrDels[4]),
|
||||
int64(4),
|
||||
int64(3),
|
||||
time.Unix(2, 0),
|
||||
false,
|
||||
int64(10),
|
||||
)
|
||||
app.SlashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), newInfo)
|
||||
suite.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[4]), newInfo)
|
||||
|
||||
require.False(t, app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[0])))
|
||||
app.SlashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
require.True(t, app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(addrDels[0])))
|
||||
require.Panics(t, func() { app.SlashingKeeper.Tombstone(ctx, sdk.ConsAddress(addrDels[0])) })
|
||||
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 TestJailUntil(t *testing.T) {
|
||||
app := simapp.Setup(t, false)
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, app.StakingKeeper.TokensFromConsensusPower(ctx, 200))
|
||||
func (suite *KeeperTestSuite) TestJailUntil() {
|
||||
ctx := suite.ctx
|
||||
addrDels := suite.addrDels
|
||||
|
||||
require.Panics(t, func() { app.SlashingKeeper.JailUntil(ctx, sdk.ConsAddress(addrDels[0]), time.Now()) })
|
||||
suite.Require().Panics(func() { suite.slashingKeeper.JailUntil(ctx, sdk.ConsAddress(addrDels[3]), time.Now()) })
|
||||
|
||||
newInfo := types.NewValidatorSigningInfo(
|
||||
sdk.ConsAddress(addrDels[0]),
|
||||
sdk.ConsAddress(addrDels[3]),
|
||||
int64(4),
|
||||
int64(3),
|
||||
time.Unix(2, 0),
|
||||
false,
|
||||
int64(10),
|
||||
)
|
||||
app.SlashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), newInfo)
|
||||
app.SlashingKeeper.JailUntil(ctx, sdk.ConsAddress(addrDels[0]), time.Unix(253402300799, 0).UTC())
|
||||
suite.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[3]), newInfo)
|
||||
suite.slashingKeeper.JailUntil(ctx, sdk.ConsAddress(addrDels[3]), time.Unix(253402300799, 0).UTC())
|
||||
|
||||
info, ok := app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]))
|
||||
require.True(t, ok)
|
||||
require.Equal(t, time.Unix(253402300799, 0).UTC(), info.JailedUntil)
|
||||
info, ok := suite.slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[3]))
|
||||
suite.Require().True(ok)
|
||||
suite.Require().Equal(time.Unix(253402300799, 0).UTC(), info.JailedUntil)
|
||||
}
|
||||
|
||||
@@ -8,11 +8,13 @@ import (
|
||||
gogotypes "github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/depinject"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
)
|
||||
|
||||
@@ -25,7 +27,8 @@ var (
|
||||
)
|
||||
|
||||
func TestDecodeStore(t *testing.T) {
|
||||
cdc := simapp.MakeTestEncodingConfig().Codec
|
||||
var cdc codec.Codec
|
||||
depinject.Inject(testutil.AppConfig, &cdc)
|
||||
dec := simulation.NewDecodeStore(cdc)
|
||||
|
||||
info := types.NewValidatorSigningInfo(consAddr1, 0, 1, time.Now().UTC(), false, 0)
|
||||
|
||||
@@ -11,17 +11,20 @@ import (
|
||||
sdkmath "cosmossdk.io/math"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/depinject"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
)
|
||||
|
||||
// TestRandomizedGenState tests the normal scenario of applying RandomizedGenState.
|
||||
// Abonormal scenarios are not tested here.
|
||||
func TestRandomizedGenState(t *testing.T) {
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
var interfaceRegistry codectypes.InterfaceRegistry
|
||||
depinject.Inject(testutil.AppConfig, &interfaceRegistry)
|
||||
cdc := codec.NewProtoCodec(interfaceRegistry)
|
||||
|
||||
s := rand.NewSource(1)
|
||||
@@ -57,7 +60,8 @@ func TestRandomizedGenState(t *testing.T) {
|
||||
|
||||
// TestRandomizedGenState tests abnormal scenarios of applying RandomizedGenState.
|
||||
func TestRandomizedGenState1(t *testing.T) {
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
var interfaceRegistry codectypes.InterfaceRegistry
|
||||
depinject.Inject(testutil.AppConfig, &interfaceRegistry)
|
||||
cdc := codec.NewProtoCodec(interfaceRegistry)
|
||||
|
||||
s := rand.NewSource(1)
|
||||
|
||||
@@ -6,10 +6,11 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
@@ -27,23 +28,24 @@ func WeightedOperations(
|
||||
appParams simtypes.AppParams, cdc codec.JSONCodec, ak types.AccountKeeper,
|
||||
bk types.BankKeeper, k keeper.Keeper, sk types.StakingKeeper,
|
||||
) simulation.WeightedOperations {
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
var weightMsgUnjail int
|
||||
appParams.GetOrGenerate(cdc, OpWeightMsgUnjail, &weightMsgUnjail, nil,
|
||||
func(_ *rand.Rand) {
|
||||
weightMsgUnjail = simappparams.DefaultWeightMsgUnjail
|
||||
weightMsgUnjail = simtestutil.DefaultWeightMsgUnjail
|
||||
},
|
||||
)
|
||||
|
||||
return simulation.WeightedOperations{
|
||||
simulation.NewWeightedOperation(
|
||||
weightMsgUnjail,
|
||||
SimulateMsgUnjail(ak, bk, k, sk.(*stakingkeeper.Keeper)),
|
||||
SimulateMsgUnjail(codec.NewProtoCodec(interfaceRegistry), ak, bk, k, sk.(*stakingkeeper.Keeper)),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgUnjail generates a MsgUnjail with random values
|
||||
func SimulateMsgUnjail(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, sk *stakingkeeper.Keeper) simtypes.Operation {
|
||||
func SimulateMsgUnjail(cdc *codec.ProtoCodec, ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, sk *stakingkeeper.Keeper) simtypes.Operation {
|
||||
return func(
|
||||
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
accs []simtypes.Account, chainID string,
|
||||
@@ -87,7 +89,7 @@ func SimulateMsgUnjail(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Kee
|
||||
|
||||
msg := types.NewMsgUnjail(validator.GetOperator())
|
||||
|
||||
txGen := simappparams.MakeTestEncodingConfig().TxConfig
|
||||
txGen := tx.NewTxConfig(cdc, tx.DefaultSignModes)
|
||||
tx, err := simtestutil.GenSignedMockTx(
|
||||
txGen,
|
||||
[]sdk.Msg{msg},
|
||||
|
||||
@@ -6,43 +6,104 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/testutil"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
|
||||
distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
|
||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/simulation"
|
||||
"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"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// TestWeightedOperations tests the weights of the operations.
|
||||
func TestWeightedOperations(t *testing.T) {
|
||||
type SimTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
ctx sdk.Context
|
||||
|
||||
app *runtime.App
|
||||
legacyAmino *codec.LegacyAmino
|
||||
codec codec.Codec
|
||||
interfaceRegistry codectypes.InterfaceRegistry
|
||||
accountKeeper authkeeper.AccountKeeper
|
||||
bankKeeper bankkeeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
slashingKeeper slashingkeeper.Keeper
|
||||
distrKeeper distributionkeeper.Keeper
|
||||
mintKeeper mintkeeper.Keeper
|
||||
accs []simtypes.Account
|
||||
}
|
||||
|
||||
func (suite *SimTestSuite) SetupTest() {
|
||||
app, err := simtestutil.Setup(
|
||||
testutil.AppConfig,
|
||||
&suite.legacyAmino,
|
||||
&suite.codec,
|
||||
&suite.interfaceRegistry,
|
||||
&suite.accountKeeper,
|
||||
&suite.bankKeeper,
|
||||
&suite.stakingKeeper,
|
||||
&suite.mintKeeper,
|
||||
&suite.slashingKeeper,
|
||||
&suite.distrKeeper,
|
||||
)
|
||||
|
||||
suite.Require().NoError(err)
|
||||
suite.app = app
|
||||
suite.ctx = app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
app, ctx, accs := createTestApp(t, false, r, 3)
|
||||
accounts := simtypes.RandomAccounts(r, 3)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
initAmt := suite.stakingKeeper.TokensFromConsensusPower(ctx, 200)
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initAmt))
|
||||
|
||||
// add coins to the accounts
|
||||
for _, account := range accounts {
|
||||
acc := suite.accountKeeper.NewAccountWithAddress(ctx, account.Address)
|
||||
suite.accountKeeper.SetAccount(ctx, acc)
|
||||
suite.Require().NoError(banktestutil.FundAccount(suite.bankKeeper, ctx, account.Address, initCoins))
|
||||
}
|
||||
|
||||
suite.mintKeeper.SetParams(ctx, minttypes.DefaultParams())
|
||||
suite.mintKeeper.SetMinter(ctx, minttypes.DefaultInitialMinter())
|
||||
suite.accs = accounts
|
||||
}
|
||||
|
||||
// TestWeightedOperations tests the weights of the operations.
|
||||
func (suite *SimTestSuite) TestWeightedOperations(t *testing.T) {
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
app, ctx, accs := suite.app, suite.ctx, suite.accs
|
||||
ctx.WithChainID("test-chain")
|
||||
|
||||
cdc := app.AppCodec()
|
||||
cdc := suite.codec
|
||||
appParams := make(simtypes.AppParams)
|
||||
|
||||
expected := []struct {
|
||||
weight int
|
||||
opMsgRoute string
|
||||
opMsgName string
|
||||
}{{simappparams.DefaultWeightMsgUnjail, types.ModuleName, types.TypeMsgUnjail}}
|
||||
}{{simtestutil.DefaultWeightMsgUnjail, types.ModuleName, types.TypeMsgUnjail}}
|
||||
|
||||
weightesOps := simulation.WeightedOperations(appParams, cdc, app.AccountKeeper, app.BankKeeper, app.SlashingKeeper, app.StakingKeeper)
|
||||
weightesOps := simulation.WeightedOperations(appParams, cdc, suite.accountKeeper, suite.bankKeeper, suite.slashingKeeper, suite.stakingKeeper)
|
||||
for i, w := range weightesOps {
|
||||
operationMsg, _, err := w.Op()(r, app.BaseApp, ctx, accs, ctx.ChainID())
|
||||
require.NoError(t, err)
|
||||
@@ -50,19 +111,19 @@ func TestWeightedOperations(t *testing.T) {
|
||||
// the following checks are very much dependent from the ordering of the output given
|
||||
// by WeightedOperations. if the ordering in WeightedOperations changes some tests
|
||||
// will fail
|
||||
require.Equal(t, expected[i].weight, w.Weight(), "weight should be the same")
|
||||
require.Equal(t, expected[i].opMsgRoute, operationMsg.Route, "route should be the same")
|
||||
require.Equal(t, expected[i].opMsgName, operationMsg.Name, "operation Msg name should be the same")
|
||||
suite.Require().Equal(t, expected[i].weight, w.Weight(), "weight should be the same")
|
||||
suite.Require().Equal(t, expected[i].opMsgRoute, operationMsg.Route, "route should be the same")
|
||||
suite.Require().Equal(t, expected[i].opMsgName, operationMsg.Name, "operation Msg name should be the same")
|
||||
}
|
||||
}
|
||||
|
||||
// TestSimulateMsgUnjail tests the normal scenario of a valid message of type types.MsgUnjail.
|
||||
// Abonormal scenarios, where the message is created by an errors, are not tested here.
|
||||
func TestSimulateMsgUnjail(t *testing.T) {
|
||||
func (suite *SimTestSuite) TestSimulateMsgUnjail(t *testing.T) {
|
||||
// setup 3 accounts
|
||||
s := rand.NewSource(5)
|
||||
r := rand.New(s)
|
||||
app, ctx, accounts := createTestApp(t, false, r, 3)
|
||||
app, ctx, accounts := suite.app, suite.ctx, suite.accs
|
||||
blockTime := time.Now().UTC()
|
||||
ctx = ctx.WithBlockTime(blockTime)
|
||||
|
||||
@@ -70,33 +131,33 @@ func TestSimulateMsgUnjail(t *testing.T) {
|
||||
accounts = accounts[1:]
|
||||
|
||||
// setup accounts[0] as validator0
|
||||
validator0 := getTestingValidator0(t, app, ctx, accounts)
|
||||
validator0 := suite.getTestingValidator0(ctx, accounts)
|
||||
|
||||
// setup validator0 by consensus address
|
||||
app.StakingKeeper.SetValidatorByConsAddr(ctx, validator0)
|
||||
suite.stakingKeeper.SetValidatorByConsAddr(ctx, validator0)
|
||||
val0ConsAddress, err := validator0.GetConsAddr()
|
||||
require.NoError(t, err)
|
||||
info := types.NewValidatorSigningInfo(val0ConsAddress, int64(4), int64(3),
|
||||
time.Unix(2, 0), false, int64(10))
|
||||
app.SlashingKeeper.SetValidatorSigningInfo(ctx, val0ConsAddress, info)
|
||||
suite.slashingKeeper.SetValidatorSigningInfo(ctx, val0ConsAddress, info)
|
||||
|
||||
// put validator0 in jail
|
||||
app.StakingKeeper.Jail(ctx, val0ConsAddress)
|
||||
suite.stakingKeeper.Jail(ctx, val0ConsAddress)
|
||||
|
||||
// setup self delegation
|
||||
delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
|
||||
delTokens := suite.stakingKeeper.TokensFromConsensusPower(ctx, 2)
|
||||
validator0, issuedShares := validator0.AddTokensFromDel(delTokens)
|
||||
val0AccAddress, err := sdk.ValAddressFromBech32(validator0.OperatorAddress)
|
||||
require.NoError(t, err)
|
||||
selfDelegation := stakingtypes.NewDelegation(val0AccAddress.Bytes(), validator0.GetOperator(), issuedShares)
|
||||
app.StakingKeeper.SetDelegation(ctx, selfDelegation)
|
||||
app.DistrKeeper.SetDelegatorStartingInfo(ctx, validator0.GetOperator(), val0AccAddress.Bytes(), distrtypes.NewDelegatorStartingInfo(2, sdk.OneDec(), 200))
|
||||
suite.stakingKeeper.SetDelegation(ctx, selfDelegation)
|
||||
suite.distrKeeper.SetDelegatorStartingInfo(ctx, validator0.GetOperator(), val0AccAddress.Bytes(), distrtypes.NewDelegatorStartingInfo(2, sdk.OneDec(), 200))
|
||||
|
||||
// begin a new block
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash, Time: blockTime}})
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgUnjail(app.AccountKeeper, app.BankKeeper, app.SlashingKeeper, app.StakingKeeper)
|
||||
op := simulation.SimulateMsgUnjail(codec.NewProtoCodec(suite.interfaceRegistry), suite.accountKeeper, suite.bankKeeper, suite.slashingKeeper, suite.stakingKeeper)
|
||||
operationMsg, futureOperations, err := op(r, app.BaseApp, ctx, accounts, "")
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -109,65 +170,25 @@ func TestSimulateMsgUnjail(t *testing.T) {
|
||||
require.Len(t, futureOperations, 0)
|
||||
}
|
||||
|
||||
// returns context and an app with updated mint keeper
|
||||
func createTestApp(t *testing.T, isCheckTx bool, r *rand.Rand, n int) (*simapp.SimApp, sdk.Context, []simtypes.Account) {
|
||||
accounts := simtypes.RandomAccounts(r, n)
|
||||
// create validator set with single validator
|
||||
account := accounts[0]
|
||||
tmPk, err := cryptocodec.ToTmPubKeyInterface(account.PubKey)
|
||||
require.NoError(t, err)
|
||||
validator := tmtypes.NewValidator(tmPk, 1)
|
||||
|
||||
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
|
||||
|
||||
// generate genesis account
|
||||
senderPrivKey := secp256k1.GenPrivKey()
|
||||
acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0)
|
||||
balance := banktypes.Balance{
|
||||
Address: acc.GetAddress().String(),
|
||||
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
|
||||
}
|
||||
|
||||
app := simapp.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance)
|
||||
|
||||
ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{})
|
||||
initAmt := app.StakingKeeper.TokensFromConsensusPower(ctx, 200)
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initAmt))
|
||||
|
||||
// remove genesis validator account
|
||||
accs := accounts[1:]
|
||||
|
||||
// add coins to the accounts
|
||||
for _, account := range accs {
|
||||
acc := app.AccountKeeper.NewAccountWithAddress(ctx, account.Address)
|
||||
app.AccountKeeper.SetAccount(ctx, acc)
|
||||
require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, account.Address, initCoins))
|
||||
}
|
||||
|
||||
app.MintKeeper.SetParams(ctx, minttypes.DefaultParams())
|
||||
app.MintKeeper.SetMinter(ctx, minttypes.DefaultInitialMinter())
|
||||
|
||||
return app, ctx, accounts
|
||||
}
|
||||
|
||||
func getTestingValidator0(t *testing.T, app *simapp.SimApp, ctx sdk.Context, accounts []simtypes.Account) stakingtypes.Validator {
|
||||
func (suite *SimTestSuite) getTestingValidator0(ctx sdk.Context, accounts []simtypes.Account) stakingtypes.Validator {
|
||||
commission0 := stakingtypes.NewCommission(sdk.ZeroDec(), sdk.OneDec(), sdk.OneDec())
|
||||
return getTestingValidator(t, app, ctx, accounts, commission0, 0)
|
||||
return suite.getTestingValidator(commission0, 0)
|
||||
}
|
||||
|
||||
func getTestingValidator(t *testing.T, app *simapp.SimApp, ctx sdk.Context, accounts []simtypes.Account, commission stakingtypes.Commission, n int) stakingtypes.Validator {
|
||||
func (suite *SimTestSuite) getTestingValidator(commission stakingtypes.Commission, n int) stakingtypes.Validator {
|
||||
ctx, accounts := suite.ctx, suite.accs
|
||||
account := accounts[n]
|
||||
valPubKey := account.ConsKey.PubKey()
|
||||
valAddr := sdk.ValAddress(account.PubKey.Address().Bytes())
|
||||
validator, err := stakingtypes.NewValidator(valAddr, valPubKey, stakingtypes.Description{})
|
||||
require.NoError(t, err)
|
||||
suite.Require().NoError(err)
|
||||
validator, err = validator.SetInitialCommission(commission)
|
||||
require.NoError(t, err)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
validator.DelegatorShares = sdk.NewDec(100)
|
||||
validator.Tokens = sdk.NewInt(1000000)
|
||||
|
||||
app.StakingKeeper.SetValidator(ctx, validator)
|
||||
suite.stakingKeeper.SetValidator(ctx, validator)
|
||||
|
||||
return validator
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ modules:
|
||||
|
||||
app_name: SlashApp
|
||||
|
||||
begin_blockers: [staking, auth, bank, genutil, slashing, params]
|
||||
end_blockers: [staking, auth, bank, genutil, slashing, params]
|
||||
init_genesis: [auth, bank, staking, slashing, genutil, params]
|
||||
begin_blockers: [mint, staking, auth, bank, genutil, slashing, params]
|
||||
end_blockers: [mint, staking, auth, bank, genutil, slashing, params]
|
||||
init_genesis: [auth, bank, staking, mint, slashing, genutil, params]
|
||||
|
||||
- name: auth
|
||||
config:
|
||||
@@ -15,6 +15,8 @@ modules:
|
||||
bech32_prefix: cosmos
|
||||
module_account_permissions:
|
||||
- account: fee_collector
|
||||
- account: mint
|
||||
permissions: [minter]
|
||||
- account: bonded_tokens_pool
|
||||
permissions: [burner, staking]
|
||||
- account: not_bonded_tokens_pool
|
||||
@@ -43,3 +45,7 @@ modules:
|
||||
- name: genutil
|
||||
config:
|
||||
"@type": cosmos.genutil.module.v1.Module
|
||||
|
||||
- name: mint
|
||||
config:
|
||||
"@type": cosmos.mint.module.v1.Module
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/module"
|
||||
_ "github.com/cosmos/cosmos-sdk/x/bank"
|
||||
_ "github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
_ "github.com/cosmos/cosmos-sdk/x/mint"
|
||||
_ "github.com/cosmos/cosmos-sdk/x/params"
|
||||
_ "github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
_ "github.com/cosmos/cosmos-sdk/x/staking"
|
||||
|
||||
Reference in New Issue
Block a user