test(x/staking): write integration tests (#15890)

This commit is contained in:
Likhita Polavarapu 2023-05-03 01:31:19 +05:30 committed by GitHub
parent 946f3d6da7
commit 672b1f9e15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1285 additions and 3161 deletions

View File

@ -1,770 +0,0 @@
package testutil
import (
"fmt"
"cosmossdk.io/math"
"github.com/cosmos/gogoproto/proto"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/x/staking/client/cli"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func (s *E2ETestSuite) TestGRPCQueryValidatorsHandler() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
error bool
}{
{
"test query validators gRPC route with invalid status",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators?status=active", baseURL),
true,
},
{
"test query validators gRPC route without status query param",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators", baseURL),
false,
},
{
"test query validators gRPC route with valid status",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators?status=%s", baseURL, types.Bonded.String()),
false,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequest(tc.url)
s.Require().NoError(err)
var valRes types.QueryValidatorsResponse
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &valRes)
if tc.error {
s.Require().Error(err)
s.Require().Nil(valRes.Validators)
s.Require().Equal(0, len(valRes.Validators))
} else {
s.Require().NoError(err)
s.Require().NotNil(valRes.Validators)
s.Require().Equal(len(s.network.Validators), len(valRes.Validators))
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryValidator() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
error bool
}{
{
"wrong validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s", baseURL, "wrongValidatorAddress"),
true,
},
{
"with no validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s", baseURL, ""),
true,
},
{
"valid request",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s", baseURL, val.ValAddress.String()),
false,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequest(tc.url)
s.Require().NoError(err)
var validator types.QueryValidatorResponse
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &validator)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NotNil(validator.Validator)
s.Require().Equal(s.network.Validators[0].ValAddress.String(), validator.Validator.OperatorAddress)
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryValidatorDelegations() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
headers map[string]string
error bool
respType proto.Message
expectedResp proto.Message
}{
{
"wrong validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations", baseURL, "wrongValAddress"),
map[string]string{},
true,
&types.QueryValidatorDelegationsResponse{},
nil,
},
{
"with no validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations", baseURL, ""),
map[string]string{},
true,
&types.QueryValidatorDelegationsResponse{},
nil,
},
{
"valid request(height specific)",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations", baseURL, val.ValAddress.String()),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
false,
&types.QueryValidatorDelegationsResponse{},
&types.QueryValidatorDelegationsResponse{
DelegationResponses: types.DelegationResponses{
types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDecFromInt(cli.DefaultTokens), sdk.NewCoin(sdk.DefaultBondDenom, cli.DefaultTokens)),
},
Pagination: &query.PageResponse{Total: 1},
},
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
s.Require().NoError(err)
err = val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Equal(tc.expectedResp.String(), tc.respType.String())
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryValidatorUnbondingDelegations() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
error bool
}{
{
"wrong validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/unbonding_delegations", baseURL, "wrongValAddress"),
true,
},
{
"with no validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/unbonding_delegations", baseURL, ""),
true,
},
{
"valid request",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/unbonding_delegations", baseURL, val.ValAddress.String()),
false,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequest(tc.url)
s.Require().NoError(err)
var ubds types.QueryValidatorUnbondingDelegationsResponse
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &ubds)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Len(ubds.UnbondingResponses, 1)
s.Require().Equal(ubds.UnbondingResponses[0].ValidatorAddress, val.ValAddress.String())
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryDelegation() {
val := s.network.Validators[0]
val2 := s.network.Validators[1]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
error bool
respType proto.Message
expectedResp proto.Message
}{
{
"wrong validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", baseURL, "wrongValAddress", val.Address.String()),
true,
&types.QueryDelegationResponse{},
nil,
},
{
"wrong account address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", baseURL, val.ValAddress.String(), "wrongAccAddress"),
true,
&types.QueryDelegationResponse{},
nil,
},
{
"with no validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", baseURL, "", val.Address.String()),
true,
&types.QueryDelegationResponse{},
nil,
},
{
"with no account address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", baseURL, val.ValAddress.String(), ""),
true,
&types.QueryDelegationResponse{},
nil,
},
{
"valid request",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", baseURL, val2.ValAddress.String(), val.Address.String()),
false,
&types.QueryDelegationResponse{},
&types.QueryDelegationResponse{
DelegationResponse: &types.DelegationResponse{
Delegation: types.Delegation{
DelegatorAddress: val.Address.String(),
ValidatorAddress: val2.ValAddress.String(),
Shares: math.LegacyNewDec(10),
},
Balance: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)),
},
},
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequest(tc.url)
s.Require().NoError(err)
s.T().Logf("%s", resp)
err = val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Equal(tc.expectedResp.String(), tc.respType.String())
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryUnbondingDelegation() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
error bool
}{
{
"wrong validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s/unbonding_delegation", baseURL, "wrongValAddress", val.Address.String()),
true,
},
{
"wrong account address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s/unbonding_delegation", baseURL, val.ValAddress.String(), "wrongAccAddress"),
true,
},
{
"with no validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s/unbonding_delegation", baseURL, "", val.Address.String()),
true,
},
{
"with no account address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s/unbonding_delegation", baseURL, val.ValAddress.String(), ""),
true,
},
{
"valid request",
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s/unbonding_delegation", baseURL, val.ValAddress.String(), val.Address.String()),
false,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequest(tc.url)
s.Require().NoError(err)
var ubd types.QueryUnbondingDelegationResponse
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &ubd)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Equal(ubd.Unbond.DelegatorAddress, val.Address.String())
s.Require().Equal(ubd.Unbond.ValidatorAddress, val.ValAddress.String())
s.Require().Len(ubd.Unbond.Entries, 2)
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryDelegatorDelegations() {
val := s.network.Validators[0]
baseURL := val.APIAddress
// Create new account in the keyring for address without delegations.
k, _, err := val.ClientCtx.Keyring.NewMnemonic("test", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
s.Require().NoError(err)
newAddr, err := k.GetAddress()
s.Require().NoError(err)
testCases := []struct {
name string
url string
headers map[string]string
error bool
respType proto.Message
expectedResp proto.Message
}{
{
"wrong validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegations/%s", baseURL, "wrongValAddress"),
map[string]string{},
true,
&types.QueryDelegatorDelegationsResponse{},
nil,
},
{
"with no validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegations/%s", baseURL, ""),
map[string]string{},
true,
&types.QueryDelegatorDelegationsResponse{},
nil,
},
{
"valid request (height specific)",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegations/%s", baseURL, val.Address.String()),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
false,
&types.QueryDelegatorDelegationsResponse{},
&types.QueryDelegatorDelegationsResponse{
DelegationResponses: types.DelegationResponses{
types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDecFromInt(cli.DefaultTokens), sdk.NewCoin(sdk.DefaultBondDenom, cli.DefaultTokens)),
},
Pagination: &query.PageResponse{Total: 1},
},
},
{
"address without delegations",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegations/%s", baseURL, newAddr.String()),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
false,
&types.QueryDelegatorDelegationsResponse{},
&types.QueryDelegatorDelegationsResponse{
DelegationResponses: types.DelegationResponses{},
Pagination: &query.PageResponse{Total: 0},
},
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
s.Require().NoError(err)
err = val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Equal(tc.expectedResp.String(), tc.respType.String())
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryDelegatorUnbondingDelegations() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
error bool
ubdsLength int
}{
{
"wrong validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/unbonding_delegations", baseURL, "wrongValAddress"),
true,
0,
},
{
"with no validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/unbonding_delegations", baseURL, ""),
true,
0,
},
{
"valid request",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/unbonding_delegations", baseURL, val.Address.String()),
false,
1,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequest(tc.url)
s.Require().NoError(err)
var ubds types.QueryDelegatorUnbondingDelegationsResponse
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &ubds)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Len(ubds.UnbondingResponses, tc.ubdsLength)
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryRedelegations() {
val := s.network.Validators[0]
val2 := s.network.Validators[1]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
error bool
}{
{
"wrong validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations", baseURL, "wrongValAddress"),
true,
},
{
"with no validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations", baseURL, ""),
true,
},
{
"valid request",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations", baseURL, val.Address.String()),
false,
},
{
"valid request with src address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations?src_validator_addr=%s", baseURL, val.Address.String(), val.ValAddress.String()),
false,
},
{
"valid request with dst address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations?dst_validator_addr=%s", baseURL, val.Address.String(), val.ValAddress.String()),
false,
},
{
"valid request with dst address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations?src_validator_addr=%s&dst_validator_addr=%s", baseURL, val.Address.String(), val.ValAddress.String(), val2.ValAddress.String()),
false,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequest(tc.url)
s.Require().NoError(err)
var redelegations types.QueryRedelegationsResponse
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &redelegations)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Len(redelegations.RedelegationResponses, 1)
s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.DelegatorAddress, val.Address.String())
s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.ValidatorSrcAddress, val.ValAddress.String())
s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.ValidatorDstAddress, val2.ValAddress.String())
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryDelegatorValidators() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
error bool
}{
{
"wrong delegator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators", baseURL, "wrongDelAddress"),
true,
},
{
"with no delegator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators", baseURL, ""),
true,
},
{
"valid request",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators", baseURL, val.Address.String()),
false,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequest(tc.url)
s.Require().NoError(err)
var validators types.QueryDelegatorValidatorsResponse
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &validators)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Len(validators.Validators, len(s.network.Validators))
s.Require().Equal(int(validators.Pagination.Total), len(s.network.Validators))
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryDelegatorValidator() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
error bool
}{
{
"wrong delegator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators/%s", baseURL, "wrongAccAddress", val.ValAddress.String()),
true,
},
{
"wrong validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators/%s", baseURL, val.Address.String(), "wrongValAddress"),
true,
},
{
"with empty delegator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators/%s", baseURL, "", val.ValAddress.String()),
true,
},
{
"with empty validator address",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators/%s", baseURL, val.Address.String(), ""),
true,
},
{
"valid request",
fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators/%s", baseURL, val.Address.String(), val.ValAddress.String()),
false,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequest(tc.url)
s.Require().NoError(err)
var validator types.QueryDelegatorValidatorResponse
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &validator)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NotNil(validator)
s.Require().Equal(validator.Validator.OperatorAddress, val.ValAddress.String())
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryHistoricalInfo() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
error bool
}{
{
"wrong height",
fmt.Sprintf("%s/cosmos/staking/v1beta1/historical_info/%s", baseURL, "-1"),
true,
},
{
"with no height",
fmt.Sprintf("%s/cosmos/staking/v1beta1/historical_info/%s", baseURL, ""),
true,
},
{
"valid request",
fmt.Sprintf("%s/cosmos/staking/v1beta1/historical_info/%s", baseURL, "2"),
false,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequest(tc.url)
s.Require().NoError(err)
var historicalInfo types.QueryHistoricalInfoResponse
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &historicalInfo)
if tc.error {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NotNil(historicalInfo)
}
})
}
}
func (s *E2ETestSuite) TestGRPCQueryParams() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
respType proto.Message
expected proto.Message
}{
{
"gRPC request params",
fmt.Sprintf("%s/cosmos/staking/v1beta1/params", baseURL),
&types.QueryParamsResponse{},
&types.QueryParamsResponse{
Params: types.DefaultParams(),
},
},
}
for _, tc := range testCases {
tc := tc
resp, err := testutil.GetRequest(tc.url)
s.Run(tc.name, func() {
s.Require().NoError(err)
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType))
s.Require().Equal(tc.expected, tc.respType)
})
}
}
func (s *E2ETestSuite) TestGRPCQueryPool() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
headers map[string]string
respType proto.Message
expected proto.Message
}{
{
"gRPC request params",
fmt.Sprintf("%s/cosmos/staking/v1beta1/pool", baseURL),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
&types.QueryPoolResponse{},
&types.QueryPoolResponse{
Pool: types.Pool{
NotBondedTokens: sdk.NewInt(0),
BondedTokens: cli.DefaultTokens.Mul(sdk.NewInt(2)),
},
},
},
}
for _, tc := range testCases {
tc := tc
resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
s.Run(tc.name, func() {
s.Require().NoError(err)
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType))
s.Require().Equal(tc.expected.String(), tc.respType.String())
})
}
}

File diff suppressed because it is too large Load Diff

View File

@ -4,41 +4,48 @@ import (
"math/big"
"testing"
"cosmossdk.io/simapp"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
"gotest.tools/v3/assert"
cmtprototypes "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil/integration"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/auth"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/testutil"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
var PKs = simtestutil.CreateTestPubKeys(500)
func init() {
sdk.DefaultPowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))
type fixture struct {
app *integration.App
sdkCtx sdk.Context
cdc codec.Codec
keys map[string]*storetypes.KVStoreKey
accountKeeper authkeeper.AccountKeeper
bankKeeper bankkeeper.Keeper
stakingKeeper *stakingkeeper.Keeper
}
// createTestInput Returns a simapp with custom StakingKeeper
// to avoid messing with the hooks.
func createTestInput(t *testing.T) (*codec.LegacyAmino, *simapp.SimApp, sdk.Context) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
app.StakingKeeper = keeper.NewKeeper(
app.AppCodec(),
app.GetKey(types.StoreKey),
app.AccountKeeper,
app.BankKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
return app.LegacyAmino(), app, ctx
func init() {
sdk.DefaultPowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))
}
// intended to be used with require/assert: require.True(ValEq(...))
@ -47,44 +54,107 @@ func ValEq(t *testing.T, exp, got types.Validator) (*testing.T, bool, string, ty
}
// generateAddresses generates numAddrs of normal AccAddrs and ValAddrs
func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int) ([]sdk.AccAddress, []sdk.ValAddress) {
addrDels := simtestutil.AddTestAddrsIncremental(app.BankKeeper, app.StakingKeeper, ctx, numAddrs, sdk.NewInt(10000))
func generateAddresses(f *fixture, numAddrs int) ([]sdk.AccAddress, []sdk.ValAddress) {
addrDels := simtestutil.AddTestAddrsIncremental(f.bankKeeper, f.stakingKeeper, f.sdkCtx, numAddrs, sdk.NewInt(10000))
addrVals := simtestutil.ConvertAddrsToValAddrs(addrDels)
return addrDels, addrVals
}
func createValidators(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers []int64) ([]sdk.AccAddress, []sdk.ValAddress, []types.Validator) {
addrs := simtestutil.AddTestAddrsIncremental(app.BankKeeper, app.StakingKeeper, ctx, 5, app.StakingKeeper.TokensFromConsensusPower(ctx, 300))
func createValidators(t *testing.T, f *fixture, powers []int64) ([]sdk.AccAddress, []sdk.ValAddress, []types.Validator) {
addrs := simtestutil.AddTestAddrsIncremental(f.bankKeeper, f.stakingKeeper, f.sdkCtx, 5, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 300))
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs)
pks := simtestutil.CreateTestPubKeys(5)
cdc := moduletestutil.MakeTestEncodingConfig().Codec
app.StakingKeeper = keeper.NewKeeper(
cdc,
app.GetKey(types.StoreKey),
app.AccountKeeper,
app.BankKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
val1 := testutil.NewValidator(t, valAddrs[0], pks[0])
val2 := testutil.NewValidator(t, valAddrs[1], pks[1])
vals := []types.Validator{val1, val2}
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetValidator(ctx, val2)
app.StakingKeeper.SetValidatorByConsAddr(ctx, val1)
app.StakingKeeper.SetValidatorByConsAddr(ctx, val2)
app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val1)
app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val2)
f.stakingKeeper.SetValidator(f.sdkCtx, val1)
f.stakingKeeper.SetValidator(f.sdkCtx, val2)
f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, val1)
f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, val2)
f.stakingKeeper.SetNewValidatorByPowerIndex(f.sdkCtx, val1)
f.stakingKeeper.SetNewValidatorByPowerIndex(f.sdkCtx, val2)
_, err := app.StakingKeeper.Delegate(ctx, addrs[0], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[0]), types.Unbonded, val1, true)
_, err := f.stakingKeeper.Delegate(f.sdkCtx, addrs[0], f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, powers[0]), types.Unbonded, val1, true)
assert.NilError(t, err)
_, err = app.StakingKeeper.Delegate(ctx, addrs[1], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[1]), types.Unbonded, val2, true)
_, err = f.stakingKeeper.Delegate(f.sdkCtx, addrs[1], f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, powers[1]), types.Unbonded, val2, true)
assert.NilError(t, err)
_, err = app.StakingKeeper.Delegate(ctx, addrs[0], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[2]), types.Unbonded, val2, true)
_, err = f.stakingKeeper.Delegate(f.sdkCtx, addrs[0], f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, powers[2]), types.Unbonded, val2, true)
assert.NilError(t, err)
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
applyValidatorSetUpdates(t, f.sdkCtx, f.stakingKeeper, -1)
return addrs, valAddrs, vals
}
func initFixture(t testing.TB) *fixture {
keys := storetypes.NewKVStoreKeys(
authtypes.StoreKey, banktypes.StoreKey, types.StoreKey,
)
cdc := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, staking.AppModuleBasic{}).Codec
logger := log.NewTestLogger(t)
cms := integration.CreateMultiStore(keys, logger)
newCtx := sdk.NewContext(cms, cmtprototypes.Header{}, true, logger)
authority := authtypes.NewModuleAddress("gov")
maccPerms := map[string][]string{
minttypes.ModuleName: {authtypes.Minter},
types.ModuleName: {authtypes.Minter},
types.BondedPoolName: {authtypes.Burner, authtypes.Staking},
types.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
}
accountKeeper := authkeeper.NewAccountKeeper(
cdc,
runtime.NewKVStoreService(keys[authtypes.StoreKey]),
authtypes.ProtoBaseAccount,
maccPerms,
sdk.Bech32MainPrefix,
authority.String(),
)
blockedAddresses := map[string]bool{
accountKeeper.GetAuthority(): false,
}
bankKeeper := bankkeeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
log.NewNopLogger(),
)
stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[types.StoreKey], accountKeeper, bankKeeper, authority.String())
authModule := auth.NewAppModule(cdc, accountKeeper, authsims.RandomGenesisAccounts, nil)
bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper, nil)
stakingModule := staking.NewAppModule(cdc, stakingKeeper, accountKeeper, bankKeeper, nil)
integrationApp := integration.NewIntegrationApp(newCtx, logger, keys, cdc, authModule, bankModule, stakingModule)
sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context())
// Register MsgServer and QueryServer
types.RegisterMsgServer(integrationApp.MsgServiceRouter(), stakingkeeper.NewMsgServerImpl(stakingKeeper))
types.RegisterQueryServer(integrationApp.QueryHelper(), stakingkeeper.NewQuerier(stakingKeeper))
// set default staking params
stakingKeeper.SetParams(sdkCtx, types.DefaultParams())
f := fixture{
app: integrationApp,
sdkCtx: sdkCtx,
cdc: cdc,
keys: keys,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
stakingKeeper: stakingKeeper,
}
return &f
}

View File

@ -7,7 +7,6 @@ import (
"cosmossdk.io/math"
"gotest.tools/v3/assert"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
@ -16,36 +15,51 @@ import (
)
func TestUnbondingDelegationsMaxEntries(t *testing.T) {
_, app, ctx := createTestInput(t)
t.Parallel()
f := initFixture(t)
addrDels := simtestutil.AddTestAddrsIncremental(app.BankKeeper, app.StakingKeeper, ctx, 1, sdk.NewInt(10000))
addrVals := simtestutil.ConvertAddrsToValAddrs(addrDels)
ctx := f.sdkCtx
startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
initTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, int64(1000))
f.bankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)))
bondDenom := app.StakingKeeper.BondDenom(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
addrDel := sdk.AccAddress([]byte("addr"))
accAmt := sdk.NewInt(10000)
initCoins := sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(ctx), accAmt))
if err := f.bankKeeper.MintCoins(ctx, types.ModuleName, initCoins); err != nil {
panic(err)
}
assert.NilError(t, banktestutil.FundModuleAccount(ctx, app.BankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
if err := f.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addrDel, initCoins); err != nil {
panic(err)
}
addrVal := sdk.ValAddress(addrDel)
startTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, 10)
bondDenom := f.stakingKeeper.BondDenom(ctx)
notBondedPool := f.stakingKeeper.GetNotBondedPool(ctx)
assert.NilError(t, banktestutil.FundModuleAccount(ctx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
f.accountKeeper.SetModuleAccount(ctx, notBondedPool)
// create a validator and a delegator to that validator
validator := testutil.NewValidator(t, addrVals[0], PKs[0])
validator := testutil.NewValidator(t, addrVal, PKs[0])
validator, issuedShares := validator.AddTokensFromDel(startTokens)
assert.DeepEqual(t, startTokens, issuedShares.RoundInt())
validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
validator = keeper.TestingUpdateValidator(f.stakingKeeper, ctx, validator, true)
assert.Assert(math.IntEq(t, startTokens, validator.BondedTokens()))
assert.Assert(t, validator.IsBonded())
delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares)
app.StakingKeeper.SetDelegation(ctx, delegation)
delegation := types.NewDelegation(addrDel, addrVal, issuedShares)
f.stakingKeeper.SetDelegation(ctx, delegation)
maxEntries := app.StakingKeeper.MaxEntries(ctx)
maxEntries := f.stakingKeeper.MaxEntries(ctx)
oldBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
oldBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
// should all pass
var completionTime time.Time
@ -54,49 +68,49 @@ func TestUnbondingDelegationsMaxEntries(t *testing.T) {
var err error
ctx = ctx.WithBlockHeight(i)
var amount math.Int
completionTime, amount, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
completionTime, amount, err = f.stakingKeeper.Undelegate(ctx, addrDel, addrVal, math.LegacyNewDec(1))
totalUnbonded = totalUnbonded.Add(amount)
assert.NilError(t, err)
}
newBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
newBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries))))
assert.Assert(math.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries))))
assert.Assert(math.IntEq(t, totalUnbonded, oldBonded.Sub(newBonded)))
assert.Assert(math.IntEq(t, totalUnbonded, newNotBonded.Sub(oldNotBonded)))
oldBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
oldBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
// an additional unbond should fail due to max entries
_, _, err := app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
_, _, err := f.stakingKeeper.Undelegate(ctx, addrDel, addrVal, math.LegacyNewDec(1))
assert.Error(t, err, "too many unbonding delegation entries for (delegator, validator) tuple")
newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
newBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, newBonded, oldBonded))
assert.Assert(math.IntEq(t, newNotBonded, oldNotBonded))
// mature unbonding delegations
ctx = ctx.WithBlockTime(completionTime)
_, err = app.StakingKeeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0])
_, err = f.stakingKeeper.CompleteUnbonding(ctx, addrDel, addrVal)
assert.NilError(t, err)
newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
newBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, newBonded, oldBonded))
assert.Assert(math.IntEq(t, newNotBonded, oldNotBonded.SubRaw(int64(maxEntries))))
oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
// unbonding should work again
_, _, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
_, _, err = f.stakingKeeper.Undelegate(ctx, addrDel, addrVal, math.LegacyNewDec(1))
assert.NilError(t, err)
newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
newBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, newBonded, oldBonded.SubRaw(1)))
assert.Assert(math.IntEq(t, newNotBonded, oldNotBonded.AddRaw(1)))
}

View File

@ -4,25 +4,33 @@ import (
"testing"
"time"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"gotest.tools/v3/assert"
"pgregory.net/rapid"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil/integration"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/auth"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/distribution"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtestutil "github.com/cosmos/cosmos-sdk/x/staking/testutil"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
@ -38,42 +46,109 @@ var (
)
type deterministicFixture struct {
ctx sdk.Context
stakingKeeper *stakingkeeper.Keeper
bankKeeper bankkeeper.BaseKeeper
app *integration.App
ctx sdk.Context
cdc codec.Codec
keys map[string]*storetypes.KVStoreKey
accountKeeper authkeeper.AccountKeeper
queryClient stakingtypes.QueryClient
amt1 math.Int
amt2 math.Int
bankKeeper bankkeeper.BaseKeeper
stakingKeeper *stakingkeeper.Keeper
queryClient stakingtypes.QueryClient
amt1 math.Int
amt2 math.Int
}
func initDeterministicFixture(t *testing.T) *deterministicFixture {
f := &deterministicFixture{}
var interfaceRegistry codectypes.InterfaceRegistry
app, err := simtestutil.Setup(
depinject.Configs(
stakingtestutil.AppConfig,
depinject.Supply(log.NewNopLogger()),
),
&f.bankKeeper,
&f.accountKeeper,
&f.stakingKeeper,
&interfaceRegistry,
keys := storetypes.NewKVStoreKeys(
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
)
assert.NilError(t, err)
cdc := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, distribution.AppModuleBasic{}).Codec
f.ctx = app.BaseApp.NewContext(false, cmtproto.Header{})
logger := log.NewTestLogger(t)
cms := integration.CreateMultiStore(keys, logger)
queryHelper := baseapp.NewQueryServerTestHelper(f.ctx, interfaceRegistry)
stakingtypes.RegisterQueryServer(queryHelper, stakingkeeper.Querier{Keeper: f.stakingKeeper})
f.queryClient = stakingtypes.NewQueryClient(queryHelper)
newCtx := sdk.NewContext(cms, cmtproto.Header{}, true, logger)
f.amt1 = f.stakingKeeper.TokensFromConsensusPower(f.ctx, 101)
f.amt2 = f.stakingKeeper.TokensFromConsensusPower(f.ctx, 102)
authority := authtypes.NewModuleAddress("gov")
return f
maccPerms := map[string][]string{
minttypes.ModuleName: {authtypes.Minter},
stakingtypes.ModuleName: {authtypes.Minter},
stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking},
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
}
accountKeeper := authkeeper.NewAccountKeeper(
cdc,
runtime.NewKVStoreService(keys[authtypes.StoreKey]),
authtypes.ProtoBaseAccount,
maccPerms,
sdk.Bech32MainPrefix,
authority.String(),
)
blockedAddresses := map[string]bool{
accountKeeper.GetAuthority(): false,
}
bankKeeper := bankkeeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
log.NewNopLogger(),
)
stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[stakingtypes.StoreKey], accountKeeper, bankKeeper, authority.String())
authModule := auth.NewAppModule(cdc, accountKeeper, authsims.RandomGenesisAccounts, nil)
bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper, nil)
stakingModule := staking.NewAppModule(cdc, stakingKeeper, accountKeeper, bankKeeper, nil)
integrationApp := integration.NewIntegrationApp(newCtx, logger, keys, cdc, authModule, bankModule, stakingModule)
sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context())
// Register MsgServer and QueryServer
stakingtypes.RegisterMsgServer(integrationApp.MsgServiceRouter(), stakingkeeper.NewMsgServerImpl(stakingKeeper))
stakingtypes.RegisterQueryServer(integrationApp.QueryHelper(), stakingkeeper.NewQuerier(stakingKeeper))
// set default staking params
stakingKeeper.SetParams(sdkCtx, stakingtypes.DefaultParams())
// set pools
startTokens := stakingKeeper.TokensFromConsensusPower(sdkCtx, 10)
bondDenom := stakingKeeper.BondDenom(sdkCtx)
notBondedPool := stakingKeeper.GetNotBondedPool(sdkCtx)
assert.NilError(t, banktestutil.FundModuleAccount(sdkCtx, bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
accountKeeper.SetModuleAccount(sdkCtx, notBondedPool)
bondedPool := stakingKeeper.GetBondedPool(sdkCtx)
assert.NilError(t, banktestutil.FundModuleAccount(sdkCtx, bankKeeper, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
accountKeeper.SetModuleAccount(sdkCtx, bondedPool)
qr := integrationApp.QueryHelper()
queryClient := stakingtypes.NewQueryClient(qr)
amt1 := stakingKeeper.TokensFromConsensusPower(sdkCtx, 101)
amt2 := stakingKeeper.TokensFromConsensusPower(sdkCtx, 102)
f := deterministicFixture{
app: integrationApp,
ctx: sdkCtx,
cdc: cdc,
keys: keys,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
stakingKeeper: stakingKeeper,
queryClient: queryClient,
amt1: amt1,
amt2: amt2,
}
return &f
}
func durationGenerator() *rapid.Generator[time.Duration] {
@ -288,7 +363,7 @@ func TestGRPCValidators(t *testing.T) {
getStaticValidator(f, t)
getStaticValidator2(f, t)
testdata.DeterministicIterations(f.ctx, t, &stakingtypes.QueryValidatorsRequest{}, f.queryClient.Validators, 3525, false)
testdata.DeterministicIterations(f.ctx, t, &stakingtypes.QueryValidatorsRequest{}, f.queryClient.Validators, 2862, false)
}
func TestGRPCValidatorDelegations(t *testing.T) {
@ -658,7 +733,7 @@ func TestGRPCPool(t *testing.T) {
f = initDeterministicFixture(t) // reset
getStaticValidator(f, t)
testdata.DeterministicIterations(f.ctx, t, &stakingtypes.QueryPoolRequest{}, f.queryClient.Pool, 6185, false)
testdata.DeterministicIterations(f.ctx, t, &stakingtypes.QueryPoolRequest{}, f.queryClient.Pool, 6242, false)
}
func TestGRPCRedelegations(t *testing.T) {

View File

@ -5,45 +5,34 @@ import (
"testing"
"cosmossdk.io/math"
"cosmossdk.io/simapp"
abci "github.com/cometbft/cometbft/abci/types"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/stretchr/testify/require"
"gotest.tools/v3/assert"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank/testutil"
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func bootstrapGenesisTest(t *testing.T, numAddrs int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
func bootstrapGenesisTest(t *testing.T, numAddrs int) (*fixture, []sdk.AccAddress) {
t.Parallel()
f := initFixture(t)
addrDels, _ := generateAddresses(app, ctx, numAddrs)
return app, ctx, addrDels
addrDels, _ := generateAddresses(f, numAddrs)
return f, addrDels
}
func TestInitGenesis(t *testing.T) {
app, ctx, addrs := bootstrapGenesisTest(t, 10)
f, addrs := bootstrapGenesisTest(t, 10)
valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 1)
params := app.StakingKeeper.GetParams(ctx)
validators := app.StakingKeeper.GetAllValidators(ctx)
assert.Assert(t, len(validators) == 1)
var delegations []types.Delegation
valTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 1)
pk0, err := codectypes.NewAnyWithValue(PKs[0])
assert.NilError(t, err)
pk1, err := codectypes.NewAnyWithValue(PKs[1])
assert.NilError(t, err)
// initialize the validators
bondedVal1 := types.Validator{
bondedVal := types.Validator{
OperatorAddress: sdk.ValAddress(addrs[0]).String(),
ConsensusPubkey: pk0,
Status: types.Bonded,
@ -51,12 +40,34 @@ func TestInitGenesis(t *testing.T) {
DelegatorShares: sdk.NewDecFromInt(valTokens),
Description: types.NewDescription("hoop", "", "", "", ""),
}
bondedVal2 := types.Validator{
f.stakingKeeper.SetValidator(f.sdkCtx, bondedVal)
params := (f.stakingKeeper.GetParams(f.sdkCtx))
validators := (f.stakingKeeper.GetAllValidators(f.sdkCtx))
assert.Assert(t, len(validators) == 1)
var delegations []types.Delegation
pk1, err := codectypes.NewAnyWithValue(PKs[1])
assert.NilError(t, err)
pk2, err := codectypes.NewAnyWithValue(PKs[2])
assert.NilError(t, err)
// initialize the validators
bondedVal1 := types.Validator{
OperatorAddress: sdk.ValAddress(addrs[1]).String(),
ConsensusPubkey: pk1,
Status: types.Bonded,
Tokens: valTokens,
DelegatorShares: sdk.NewDecFromInt(valTokens),
Description: types.NewDescription("hoop", "", "", "", ""),
}
bondedVal2 := types.Validator{
OperatorAddress: sdk.ValAddress(addrs[2]).String(),
ConsensusPubkey: pk2,
Status: types.Bonded,
Tokens: valTokens,
DelegatorShares: sdk.NewDecFromInt(valTokens),
Description: types.NewDescription("bloop", "", "", "", ""),
}
@ -64,11 +75,11 @@ func TestInitGenesis(t *testing.T) {
validators = append(validators, bondedVal1, bondedVal2)
// mint coins in the bonded pool representing the validators coins
i2 := len(validators) - 1 // -1 to exclude genesis validator
i2 := len(validators)
assert.NilError(t,
testutil.FundModuleAccount(
ctx,
app.BankKeeper,
banktestutil.FundModuleAccount(
f.sdkCtx,
f.bankKeeper,
types.BondedPoolName,
sdk.NewCoins(
sdk.NewCoin(params.BondDenom, valTokens.MulRaw((int64)(i2))),
@ -76,19 +87,19 @@ func TestInitGenesis(t *testing.T) {
),
)
genesisDelegations := app.StakingKeeper.GetAllDelegations(ctx)
genesisDelegations := (f.stakingKeeper.GetAllDelegations(f.sdkCtx))
delegations = append(delegations, genesisDelegations...)
genesisState := types.NewGenesisState(params, validators, delegations)
vals := app.StakingKeeper.InitGenesis(ctx, genesisState)
vals := (f.stakingKeeper.InitGenesis(f.sdkCtx, genesisState))
actualGenesis := app.StakingKeeper.ExportGenesis(ctx)
actualGenesis := (f.stakingKeeper.ExportGenesis(f.sdkCtx))
assert.DeepEqual(t, genesisState.Params, actualGenesis.Params)
assert.DeepEqual(t, genesisState.Delegations, actualGenesis.Delegations)
assert.DeepEqual(t, app.StakingKeeper.GetAllValidators(ctx), actualGenesis.Validators)
assert.DeepEqual(t, (f.stakingKeeper.GetAllValidators(f.sdkCtx)), actualGenesis.Validators)
// Ensure validators have addresses.
vals2, err := staking.WriteValidators(ctx, app.StakingKeeper)
vals2, err := staking.WriteValidators(f.sdkCtx, (f.stakingKeeper))
assert.NilError(t, err)
for _, val := range vals2 {
@ -96,27 +107,26 @@ func TestInitGenesis(t *testing.T) {
}
// now make sure the validators are bonded and intra-tx counters are correct
resVal, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[0]))
resVal, found := (f.stakingKeeper.GetValidator(f.sdkCtx, sdk.ValAddress(addrs[1])))
assert.Assert(t, found)
assert.Equal(t, types.Bonded, resVal.Status)
resVal, found = app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[1]))
resVal, found = (f.stakingKeeper.GetValidator(f.sdkCtx, sdk.ValAddress(addrs[2])))
assert.Assert(t, found)
assert.Equal(t, types.Bonded, resVal.Status)
abcivals := make([]abci.ValidatorUpdate, len(vals))
validators = validators[1:] // remove genesis validator
for i, val := range validators {
abcivals[i] = val.ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx))
abcivals[i] = val.ABCIValidatorUpdate((f.stakingKeeper.PowerReduction(f.sdkCtx)))
}
assert.DeepEqual(t, abcivals, vals)
}
func TestInitGenesis_PoolsBalanceMismatch(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.NewContext(false, cmtproto.Header{})
t.Parallel()
f := initFixture(t)
consPub, err := codectypes.NewAnyWithValue(PKs[0])
assert.NilError(t, err)
@ -140,7 +150,7 @@ func TestInitGenesis_PoolsBalanceMismatch(t *testing.T) {
require.Panics(t, func() {
// setting validator status to bonded so the balance counts towards bonded pool
validator.Status = types.Bonded
app.StakingKeeper.InitGenesis(ctx, &types.GenesisState{
f.stakingKeeper.InitGenesis(f.sdkCtx, &types.GenesisState{
Params: params,
Validators: []types.Validator{validator},
})
@ -151,7 +161,7 @@ func TestInitGenesis_PoolsBalanceMismatch(t *testing.T) {
require.Panics(t, func() {
// setting validator status to unbonded so the balance counts towards not bonded pool
validator.Status = types.Unbonded
app.StakingKeeper.InitGenesis(ctx, &types.GenesisState{
f.stakingKeeper.InitGenesis(f.sdkCtx, &types.GenesisState{
Params: params,
Validators: []types.Validator{validator},
})
@ -164,10 +174,10 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
size := 200
assert.Assert(t, size > 100)
app, ctx, addrs := bootstrapGenesisTest(t, 200)
genesisValidators := app.StakingKeeper.GetAllValidators(ctx)
f, addrs := bootstrapGenesisTest(t, 200)
genesisValidators := f.stakingKeeper.GetAllValidators(f.sdkCtx)
params := app.StakingKeeper.GetParams(ctx)
params := f.stakingKeeper.GetParams(f.sdkCtx)
delegations := []types.Delegation{}
validators := make([]types.Validator, size)
@ -183,9 +193,9 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
assert.NilError(t, err)
validators[i].Status = types.Bonded
tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 1)
tokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 1)
if i < 100 {
tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
tokens = f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 2)
}
validators[i].Tokens = tokens
@ -200,19 +210,19 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
// mint coins in the bonded pool representing the validators coins
assert.NilError(t,
testutil.FundModuleAccount(
ctx,
app.BankKeeper,
banktestutil.FundModuleAccount(
f.sdkCtx,
f.bankKeeper,
types.BondedPoolName,
sdk.NewCoins(sdk.NewCoin(params.BondDenom, bondedPoolAmt)),
),
)
vals := app.StakingKeeper.InitGenesis(ctx, genesisState)
vals := f.stakingKeeper.InitGenesis(f.sdkCtx, genesisState)
abcivals := make([]abci.ValidatorUpdate, 100)
for i, val := range validators[:100] {
abcivals[i] = val.ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx))
abcivals[i] = val.ABCIValidatorUpdate(f.stakingKeeper.PowerReduction(f.sdkCtx))
}
// remove genesis validator

View File

@ -7,17 +7,40 @@ import (
"gotest.tools/v3/assert"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func createValidatorAccs(t *testing.T, f *fixture) ([]sdk.AccAddress, []types.Validator) {
addrs, _, validators := createValidators(&testing.T{}, f, []int64{9, 8, 7})
header := cmtproto.Header{
ChainID: "HelloChain",
Height: 5,
}
// sort a copy of the validators, so that original validators does not
// have its order changed
sortedVals := make([]types.Validator, len(validators))
copy(sortedVals, validators)
hi := types.NewHistoricalInfo(header, sortedVals, f.stakingKeeper.PowerReduction(f.sdkCtx))
f.stakingKeeper.SetHistoricalInfo(f.sdkCtx, 5, &hi)
return addrs, validators
}
func TestGRPCQueryValidators(t *testing.T) {
t.Parallel()
f := initFixture(t)
queryClient, vals := f.queryClient, f.vals
_, vals := createValidatorAccs(t, f)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
var req *types.QueryValidatorsRequest
testCases := []struct {
msg string
@ -33,7 +56,7 @@ func TestGRPCQueryValidators(t *testing.T) {
req = &types.QueryValidatorsRequest{}
},
true,
len(vals) + 1, // +1 validator from genesis state
len(vals),
false,
"",
},
@ -43,7 +66,7 @@ func TestGRPCQueryValidators(t *testing.T) {
req = &types.QueryValidatorsRequest{Status: ""}
},
true,
len(vals) + 1, // +1 validator from genesis state
len(vals),
false,
"",
},
@ -79,7 +102,7 @@ func TestGRPCQueryValidators(t *testing.T) {
assert.NilError(t, err)
assert.Assert(t, valsResp != nil)
assert.Equal(t, tc.numVals, len(valsResp.Validators))
assert.Equal(t, uint64(len(vals))+1, valsResp.Pagination.Total) // +1 validator from genesis state
assert.Equal(t, uint64(len(vals)), valsResp.Pagination.Total)
if tc.hasNext {
assert.Assert(t, valsResp.Pagination.NextKey != nil)
@ -97,9 +120,14 @@ func TestGRPCQueryDelegatorValidators(t *testing.T) {
t.Parallel()
f := initFixture(t)
app, ctx, queryClient, addrs := f.app, f.ctx, f.queryClient, f.addrs
params := app.StakingKeeper.GetParams(ctx)
delValidators := app.StakingKeeper.GetDelegatorValidators(ctx, addrs[0], params.MaxValidators)
ctx := f.sdkCtx
addrs, _ := createValidatorAccs(t, f)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
params := f.stakingKeeper.GetParams(ctx)
delValidators := f.stakingKeeper.GetDelegatorValidators(ctx, addrs[0], params.MaxValidators)
var req *types.QueryDelegatorValidatorsRequest
testCases := []struct {
msg string
@ -115,6 +143,17 @@ func TestGRPCQueryDelegatorValidators(t *testing.T) {
false,
"delegator address cannot be empty",
},
{
"invalid delegator address",
func() {
req = &types.QueryDelegatorValidatorsRequest{
DelegatorAddr: "invalid",
Pagination: &query.PageRequest{Limit: 1, CountTotal: true},
}
},
false,
"invalid bech32",
},
{
"valid request",
func() {
@ -149,7 +188,11 @@ func TestGRPCQueryDelegatorValidator(t *testing.T) {
t.Parallel()
f := initFixture(t)
queryClient, addrs, vals := f.queryClient, f.addrs, f.vals
addrs, vals := createValidatorAccs(t, f)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
addr := addrs[1]
addrVal, addrVal1 := vals[0].OperatorAddress, vals[1].OperatorAddress
var req *types.QueryDelegatorValidatorRequest
@ -178,6 +221,28 @@ func TestGRPCQueryDelegatorValidator(t *testing.T) {
false,
"no delegation for (address, validator) tuple",
},
{
"empty delegator address",
func() {
req = &types.QueryDelegatorValidatorRequest{
DelegatorAddr: "",
ValidatorAddr: addrVal1,
}
},
false,
"delegator address cannot be empty",
},
{
"empty validator address",
func() {
req = &types.QueryDelegatorValidatorRequest{
DelegatorAddr: addr.String(),
ValidatorAddr: "",
}
},
false,
"validator address cannot be empty",
},
{
"valid request",
func() {
@ -210,12 +275,17 @@ func TestGRPCQueryDelegation(t *testing.T) {
t.Parallel()
f := initFixture(t)
app, ctx, queryClient, addrs, vals := f.app, f.ctx, f.queryClient, f.addrs, f.vals
ctx := f.sdkCtx
addrs, vals := createValidatorAccs(t, f)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
addrAcc, addrAcc1 := addrs[0], addrs[1]
addrVal := vals[0].OperatorAddress
valAddr, err := sdk.ValAddressFromBech32(addrVal)
assert.NilError(t, err)
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
delegation, found := f.stakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
assert.Assert(t, found)
var req *types.QueryDelegationRequest
@ -274,12 +344,17 @@ func TestGRPCQueryDelegatorDelegations(t *testing.T) {
t.Parallel()
f := initFixture(t)
app, ctx, queryClient, addrs, vals := f.app, f.ctx, f.queryClient, f.addrs, f.vals
ctx := f.sdkCtx
addrs, vals := createValidatorAccs(t, f)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
addrAcc := addrs[0]
addrVal1 := vals[0].OperatorAddress
valAddr, err := sdk.ValAddressFromBech32(addrVal1)
assert.NilError(t, err)
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
delegation, found := f.stakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
assert.Assert(t, found)
var req *types.QueryDelegatorDelegationsRequest
@ -347,14 +422,19 @@ func TestGRPCQueryValidatorDelegations(t *testing.T) {
t.Parallel()
f := initFixture(t)
app, ctx, queryClient, addrs, vals := f.app, f.ctx, f.queryClient, f.addrs, f.vals
ctx := f.sdkCtx
addrs, vals := createValidatorAccs(t, f)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
addrAcc := addrs[0]
addrVal1 := vals[1].OperatorAddress
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs)
addrVal2 := valAddrs[4]
valAddr, err := sdk.ValAddressFromBech32(addrVal1)
assert.NilError(t, err)
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
delegation, found := f.stakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
assert.Assert(t, found)
var req *types.QueryValidatorDelegationsRequest
@ -375,7 +455,7 @@ func TestGRPCQueryValidatorDelegations(t *testing.T) {
"validator address cannot be empty",
},
{
"invalid validator delegator pair",
"invalid validator address",
func() {
req = &types.QueryValidatorDelegationsRequest{ValidatorAddr: addrVal2.String()}
},
@ -424,17 +504,22 @@ func TestGRPCQueryUnbondingDelegation(t *testing.T) {
t.Parallel()
f := initFixture(t)
app, ctx, queryClient, addrs, vals := f.app, f.ctx, f.queryClient, f.addrs, f.vals
ctx := f.sdkCtx
addrs, vals := createValidatorAccs(t, f)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
addrAcc2 := addrs[1]
addrVal2 := vals[1].OperatorAddress
unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
unbondingTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, 2)
valAddr, err1 := sdk.ValAddressFromBech32(addrVal2)
assert.NilError(t, err1)
_, _, err := app.StakingKeeper.Undelegate(ctx, addrAcc2, valAddr, sdk.NewDecFromInt(unbondingTokens))
_, _, err := f.stakingKeeper.Undelegate(ctx, addrAcc2, valAddr, sdk.NewDecFromInt(unbondingTokens))
assert.NilError(t, err)
unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, valAddr)
unbond, found := f.stakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, valAddr)
assert.Assert(t, found)
var req *types.QueryUnbondingDelegationRequest
testCases := []struct {
@ -452,13 +537,45 @@ func TestGRPCQueryUnbondingDelegation(t *testing.T) {
"delegator address cannot be empty",
},
{
"invalid request",
"empty validator address",
func() {
req = &types.QueryUnbondingDelegationRequest{}
req = &types.QueryUnbondingDelegationRequest{
DelegatorAddr: addrAcc2.String(),
}
},
false,
"validator address cannot be empty",
},
{
"empty delegator address",
func() {
req = &types.QueryUnbondingDelegationRequest{
ValidatorAddr: addrVal2,
}
},
false,
"delegator address cannot be empty",
},
{
"invalid validator address",
func() {
req = &types.QueryUnbondingDelegationRequest{
DelegatorAddr: addrAcc2.String(), ValidatorAddr: sdk.AccAddress([]byte("invalid")).String(),
}
},
false,
"invalid Bech32",
},
{
"delegation not found for validator",
func() {
req = &types.QueryUnbondingDelegationRequest{
DelegatorAddr: addrAcc2.String(), ValidatorAddr: sdk.ValAddress([]byte("invalid")).String(),
}
},
false,
fmt.Sprintf("unbonding delegation with delegator %s not found for validator", addrAcc2.String()),
},
{
"valid request",
func() {
@ -490,21 +607,26 @@ func TestGRPCQueryDelegatorUnbondingDelegations(t *testing.T) {
t.Parallel()
f := initFixture(t)
app, ctx, queryClient, addrs, vals := f.app, f.ctx, f.queryClient, f.addrs, f.vals
ctx := f.sdkCtx
addrs, vals := createValidatorAccs(t, f)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
addrAcc, addrAcc1 := addrs[0], addrs[1]
addrVal, addrVal2 := vals[0].OperatorAddress, vals[1].OperatorAddress
unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
unbondingTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, 2)
valAddr1, err1 := sdk.ValAddressFromBech32(addrVal)
assert.NilError(t, err1)
_, _, err := app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr1, sdk.NewDecFromInt(unbondingTokens))
_, _, err := f.stakingKeeper.Undelegate(ctx, addrAcc, valAddr1, sdk.NewDecFromInt(unbondingTokens))
assert.NilError(t, err)
valAddr2, err1 := sdk.ValAddressFromBech32(addrVal2)
assert.NilError(t, err1)
_, _, err = app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr2, sdk.NewDecFromInt(unbondingTokens))
_, _, err = f.stakingKeeper.Undelegate(ctx, addrAcc, valAddr2, sdk.NewDecFromInt(unbondingTokens))
assert.NilError(t, err)
unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc, valAddr1)
unbond, found := f.stakingKeeper.GetUnbondingDelegation(ctx, addrAcc, valAddr1)
assert.Assert(t, found)
var req *types.QueryDelegatorUnbondingDelegationsRequest
testCases := []struct {
@ -572,30 +694,38 @@ func TestGRPCQueryPoolParameters(t *testing.T) {
t.Parallel()
f := initFixture(t)
app, ctx, queryClient := f.app, f.ctx, f.queryClient
ctx := f.sdkCtx
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
bondDenom := sdk.DefaultBondDenom
// Query pool
res, err := queryClient.Pool(gocontext.Background(), &types.QueryPoolRequest{})
assert.NilError(t, err)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
assert.DeepEqual(t, app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, res.Pool.NotBondedTokens)
assert.DeepEqual(t, app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, res.Pool.BondedTokens)
bondedPool := f.stakingKeeper.GetBondedPool(ctx)
notBondedPool := f.stakingKeeper.GetNotBondedPool(ctx)
assert.DeepEqual(t, f.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, res.Pool.NotBondedTokens)
assert.DeepEqual(t, f.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, res.Pool.BondedTokens)
// Query Params
resp, err := queryClient.Params(gocontext.Background(), &types.QueryParamsRequest{})
assert.NilError(t, err)
assert.DeepEqual(t, app.StakingKeeper.GetParams(ctx), resp.Params)
assert.DeepEqual(t, f.stakingKeeper.GetParams(ctx), resp.Params)
}
func TestGRPCQueryHistoricalInfo(t *testing.T) {
t.Parallel()
f := initFixture(t)
app, ctx, queryClient := f.app, f.ctx, f.queryClient
ctx := f.sdkCtx
_, _ = createValidatorAccs(t, f)
hi, found := app.StakingKeeper.GetHistoricalInfo(ctx, 5)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
hi, found := f.stakingKeeper.GetHistoricalInfo(ctx, 5)
assert.Assert(t, found)
var req *types.QueryHistoricalInfoRequest
@ -659,22 +789,26 @@ func TestGRPCQueryRedelegations(t *testing.T) {
t.Parallel()
f := initFixture(t)
app, ctx, queryClient, addrs, vals := f.app, f.ctx, f.queryClient, f.addrs, f.vals
ctx := f.sdkCtx
addrs, vals := createValidatorAccs(t, f)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
addrAcc, addrAcc1 := addrs[0], addrs[1]
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs)
val1, val2, val3, val4 := vals[0], vals[1], valAddrs[3], valAddrs[4]
delAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 1)
_, err := app.StakingKeeper.Delegate(ctx, addrAcc1, delAmount, types.Unbonded, val1, true)
delAmount := f.stakingKeeper.TokensFromConsensusPower(ctx, 1)
_, err := f.stakingKeeper.Delegate(ctx, addrAcc1, delAmount, types.Unbonded, val1, true)
assert.NilError(t, err)
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
applyValidatorSetUpdates(t, ctx, f.stakingKeeper, -1)
rdAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 1)
_, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator(), sdk.NewDecFromInt(rdAmount))
rdAmount := f.stakingKeeper.TokensFromConsensusPower(ctx, 1)
_, err = f.stakingKeeper.BeginRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator(), sdk.NewDecFromInt(rdAmount))
assert.NilError(t, err)
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
applyValidatorSetUpdates(t, ctx, f.stakingKeeper, -1)
redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator())
redel, found := f.stakingKeeper.GetRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator())
assert.Assert(t, found)
var req *types.QueryRedelegationsRequest
@ -772,15 +906,20 @@ func TestGRPCQueryValidatorUnbondingDelegations(t *testing.T) {
t.Parallel()
f := initFixture(t)
app, ctx, queryClient, addrs, vals := f.app, f.ctx, f.queryClient, f.addrs, f.vals
ctx := f.sdkCtx
addrs, vals := createValidatorAccs(t, f)
qr := f.app.QueryHelper()
queryClient := types.NewQueryClient(qr)
addrAcc1, _ := addrs[0], addrs[1]
val1 := vals[0]
// undelegate
undelAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
_, _, err := app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), sdk.NewDecFromInt(undelAmount))
undelAmount := f.stakingKeeper.TokensFromConsensusPower(ctx, 2)
_, _, err := f.stakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), sdk.NewDecFromInt(undelAmount))
assert.NilError(t, err)
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
applyValidatorSetUpdates(t, ctx, f.stakingKeeper, -1)
var req *types.QueryValidatorUnbondingDelegationsRequest
testCases := []struct {
@ -797,6 +936,17 @@ func TestGRPCQueryValidatorUnbondingDelegations(t *testing.T) {
false,
"validator address cannot be empty",
},
{
"invalid validator address",
func() {
req = &types.QueryValidatorUnbondingDelegationsRequest{
ValidatorAddr: "invalid",
Pagination: &query.PageRequest{Limit: 1, CountTotal: true},
}
},
false,
"invalid bech32",
},
{
"valid request",
func() {

View File

@ -1,59 +0,0 @@
package keeper_test
import (
"testing"
"cosmossdk.io/simapp"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// fixture uses simapp (and not a depinjected app) because we manually set a
// new app.StakingKeeper in `createValidators`.
type fixture struct {
app *simapp.SimApp
ctx sdk.Context
addrs []sdk.AccAddress
vals []types.Validator
queryClient types.QueryClient
msgServer types.MsgServer
}
// initFixture uses simapp (and not a depinjected app) because we manually set a
// new app.StakingKeeper in `createValidators` which is used in most of the
// staking keeper tests.
func initFixture(t *testing.T) *fixture {
f := &fixture{}
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
querier := keeper.Querier{Keeper: app.StakingKeeper}
queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, querier)
queryClient := types.NewQueryClient(queryHelper)
f.msgServer = keeper.NewMsgServerImpl(app.StakingKeeper)
addrs, _, validators := createValidators(t, ctx, app, []int64{9, 8, 7})
header := cmtproto.Header{
ChainID: "HelloChain",
Height: 5,
}
// sort a copy of the validators, so that original validators does not
// have its order changed
sortedVals := make([]types.Validator, len(validators))
copy(sortedVals, validators)
hi := types.NewHistoricalInfo(header, sortedVals, app.StakingKeeper.PowerReduction(ctx))
app.StakingKeeper.SetHistoricalInfo(ctx, 5, &hi)
f.app, f.ctx, f.queryClient, f.addrs, f.vals = app, ctx, queryClient, addrs, validators
return f
}

View File

@ -4,69 +4,49 @@ import (
"testing"
"time"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"gotest.tools/v3/assert"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"github.com/cosmos/cosmos-sdk/testutil/configurator"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/cosmos/cosmos-sdk/x/bank/testutil"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func TestCancelUnbondingDelegation(t *testing.T) {
// setup the app
var (
stakingKeeper *keeper.Keeper
bankKeeper bankkeeper.Keeper
accountKeeper authkeeper.AccountKeeper
)
app, err := simtestutil.SetupWithConfiguration(
depinject.Configs(
configurator.NewAppConfig(
configurator.BankModule(),
configurator.TxModule(),
configurator.StakingModule(),
configurator.ParamsModule(),
configurator.ConsensusModule(),
configurator.AuthModule(),
),
depinject.Supply(log.NewNopLogger()),
),
simtestutil.DefaultStartUpConfig(),
&stakingKeeper, &bankKeeper, &accountKeeper)
assert.NilError(t, err)
t.Parallel()
f := initFixture(t)
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
msgServer := keeper.NewMsgServerImpl(stakingKeeper)
bondDenom := stakingKeeper.BondDenom(ctx)
ctx := f.sdkCtx
msgServer := keeper.NewMsgServerImpl(f.stakingKeeper)
bondDenom := f.stakingKeeper.BondDenom(ctx)
// set the not bonded pool module account
notBondedPool := stakingKeeper.GetNotBondedPool(ctx)
startTokens := stakingKeeper.TokensFromConsensusPower(ctx, 5)
notBondedPool := f.stakingKeeper.GetNotBondedPool(ctx)
startTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, 5)
assert.NilError(t, testutil.FundModuleAccount(ctx, bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), startTokens))))
accountKeeper.SetModuleAccount(ctx, notBondedPool)
assert.NilError(t, testutil.FundModuleAccount(ctx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(ctx), startTokens))))
f.accountKeeper.SetModuleAccount(ctx, notBondedPool)
moduleBalance := bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), stakingKeeper.BondDenom(ctx))
moduleBalance := f.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), f.stakingKeeper.BondDenom(ctx))
assert.DeepEqual(t, sdk.NewInt64Coin(bondDenom, startTokens.Int64()), moduleBalance)
// accounts
delAddrs := simtestutil.AddTestAddrsIncremental(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(10000))
validators := stakingKeeper.GetValidators(ctx, 10)
assert.Equal(t, len(validators), 1)
addrs := simtestutil.AddTestAddrsIncremental(f.bankKeeper, f.stakingKeeper, ctx, 2, sdk.NewInt(10000))
valAddr := sdk.ValAddress(addrs[0])
delegatorAddr := addrs[1]
validatorAddr, err := sdk.ValAddressFromBech32(validators[0].OperatorAddress)
// setup a new validator with bonded status
validator, err := types.NewValidator(valAddr, PKs[0], types.NewDescription("Validator", "", "", "", ""))
validator.Status = types.Bonded
assert.NilError(t, err)
f.stakingKeeper.SetValidator(ctx, validator)
validatorAddr, err := sdk.ValAddressFromBech32(validator.OperatorAddress)
assert.NilError(t, err)
delegatorAddr := delAddrs[0]
// setting the ubd entry
unbondingAmount := sdk.NewInt64Coin(stakingKeeper.BondDenom(ctx), 5)
unbondingAmount := sdk.NewInt64Coin(f.stakingKeeper.BondDenom(ctx), 5)
ubd := types.NewUnbondingDelegation(
delegatorAddr, validatorAddr, 10,
ctx.BlockTime().Add(time.Minute*10),
@ -75,8 +55,8 @@ func TestCancelUnbondingDelegation(t *testing.T) {
)
// set and retrieve a record
stakingKeeper.SetUnbondingDelegation(ctx, ubd)
resUnbond, found := stakingKeeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr)
f.stakingKeeper.SetUnbondingDelegation(ctx, ubd)
resUnbond, found := f.stakingKeeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr)
assert.Assert(t, found)
assert.DeepEqual(t, ubd, resUnbond)
@ -92,7 +72,7 @@ func TestCancelUnbondingDelegation(t *testing.T) {
req: types.MsgCancelUnbondingDelegation{
DelegatorAddress: resUnbond.DelegatorAddress,
ValidatorAddress: resUnbond.ValidatorAddress,
Amount: sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(4)),
Amount: sdk.NewCoin(f.stakingKeeper.BondDenom(ctx), sdk.NewInt(4)),
CreationHeight: 11,
},
expErrMsg: "unbonding delegation entry is not found at block height",
@ -103,7 +83,7 @@ func TestCancelUnbondingDelegation(t *testing.T) {
req: types.MsgCancelUnbondingDelegation{
DelegatorAddress: resUnbond.DelegatorAddress,
ValidatorAddress: resUnbond.ValidatorAddress,
Amount: sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(4)),
Amount: sdk.NewCoin(f.stakingKeeper.BondDenom(ctx), sdk.NewInt(4)),
CreationHeight: 0,
},
expErrMsg: "invalid height",
@ -181,7 +161,7 @@ func TestCancelUnbondingDelegation(t *testing.T) {
assert.ErrorContains(t, err, testCase.expErrMsg)
} else {
assert.NilError(t, err)
balanceForNotBondedPool := bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom)
balanceForNotBondedPool := f.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom)
assert.DeepEqual(t, balanceForNotBondedPool, moduleBalance.Sub(testCase.req.Amount))
moduleBalance = moduleBalance.Sub(testCase.req.Amount)
}

View File

@ -1,47 +0,0 @@
package keeper
import (
"testing"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"gotest.tools/v3/assert"
"github.com/cosmos/cosmos-sdk/testutil/configurator"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func TestParams(t *testing.T) {
var stakingKeeper *keeper.Keeper
app, err := simtestutil.SetupWithConfiguration(
depinject.Configs(
configurator.NewAppConfig(
configurator.BankModule(),
configurator.TxModule(),
configurator.StakingModule(),
configurator.ParamsModule(),
configurator.ConsensusModule(),
configurator.AuthModule(),
),
depinject.Supply(log.NewNopLogger()),
),
simtestutil.DefaultStartUpConfig(),
&stakingKeeper)
assert.NilError(t, err)
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
expParams := types.DefaultParams()
// check that the empty keeper loads the default
resParams := stakingKeeper.GetParams(ctx)
assert.Assert(t, expParams.Equal(resParams))
// modify a params, save, and retrieve
expParams.MaxValidators = 777
stakingKeeper.SetParams(ctx, expParams)
resParams = stakingKeeper.GetParams(ctx)
assert.Assert(t, expParams.Equal(resParams))
}

View File

@ -5,7 +5,6 @@ import (
"time"
"cosmossdk.io/math"
"cosmossdk.io/simapp"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/stretchr/testify/require"
"gotest.tools/v3/assert"
@ -18,40 +17,41 @@ import (
)
// bootstrapSlashTest creates 3 validators and bootstrap the app.
func bootstrapSlashTest(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) {
_, app, ctx := createTestInput(t)
func bootstrapSlashTest(t *testing.T, power int64) (*fixture, []sdk.AccAddress, []sdk.ValAddress) {
t.Parallel()
f := initFixture(t)
addrDels, addrVals := generateAddresses(app, ctx, 100)
addrDels, addrVals := generateAddresses(f, 100)
amt := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels)))))
amt := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, power)
totalSupply := sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), amt.MulRaw(int64(len(addrDels)))))
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
assert.NilError(t, banktestutil.FundModuleAccount(ctx, app.BankKeeper, notBondedPool.GetName(), totalSupply))
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, notBondedPool.GetName(), totalSupply))
app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
f.accountKeeper.SetModuleAccount(f.sdkCtx, notBondedPool)
numVals := int64(3)
bondedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(numVals)))
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
bondedCoins := sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), amt.MulRaw(numVals)))
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
// set bonded pool balance
app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
assert.NilError(t, banktestutil.FundModuleAccount(ctx, app.BankKeeper, bondedPool.GetName(), bondedCoins))
f.accountKeeper.SetModuleAccount(f.sdkCtx, bondedPool)
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, bondedPool.GetName(), bondedCoins))
for i := int64(0); i < numVals; i++ {
validator := testutil.NewValidator(t, addrVals[i], PKs[i])
validator, _ = validator.AddTokensFromDel(amt)
validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
validator = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validator, true)
f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, validator)
}
return app, ctx, addrDels, addrVals
return f, addrDels, addrVals
}
// tests slashUnbondingDelegation
func TestSlashUnbondingDelegation(t *testing.T) {
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
f, addrDels, addrVals := bootstrapSlashTest(t, 10)
fraction := sdk.NewDecWithPrec(5, 1)
@ -60,26 +60,26 @@ func TestSlashUnbondingDelegation(t *testing.T) {
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0,
time.Unix(5, 0), sdk.NewInt(10), 0)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd)
// unbonding started prior to the infraction height, stakw didn't contribute
slashAmount := app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 1, fraction)
slashAmount := f.stakingKeeper.SlashUnbondingDelegation(f.sdkCtx, ubd, 1, fraction)
assert.Assert(t, slashAmount.Equal(sdk.NewInt(0)))
// after the expiration time, no longer eligible for slashing
ctx = ctx.WithBlockHeader(cmtproto.Header{Time: time.Unix(10, 0)})
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction)
f.sdkCtx = f.sdkCtx.WithBlockHeader(cmtproto.Header{Time: time.Unix(10, 0)})
f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd)
slashAmount = f.stakingKeeper.SlashUnbondingDelegation(f.sdkCtx, ubd, 0, fraction)
assert.Assert(t, slashAmount.Equal(sdk.NewInt(0)))
// test valid slash, before expiration timestamp and to which stake contributed
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
oldUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
ctx = ctx.WithBlockHeader(cmtproto.Header{Time: time.Unix(0, 0)})
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction)
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
oldUnbondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, notBondedPool.GetAddress())
f.sdkCtx = f.sdkCtx.WithBlockHeader(cmtproto.Header{Time: time.Unix(0, 0)})
f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd)
slashAmount = f.stakingKeeper.SlashUnbondingDelegation(f.sdkCtx, ubd, 0, fraction)
assert.Assert(t, slashAmount.Equal(sdk.NewInt(5)))
ubd, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
ubd, found := f.stakingKeeper.GetUnbondingDelegation(f.sdkCtx, addrDels[0], addrVals[0])
assert.Assert(t, found)
assert.Assert(t, len(ubd.Entries) == 1)
@ -88,194 +88,194 @@ func TestSlashUnbondingDelegation(t *testing.T) {
// balance decreased
assert.DeepEqual(t, sdk.NewInt(5), ubd.Entries[0].Balance)
newUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
newUnbondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, notBondedPool.GetAddress())
diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances...)
assert.Assert(t, diffTokens.AmountOf(app.StakingKeeper.BondDenom(ctx)).Equal(sdk.NewInt(5)))
assert.Assert(t, diffTokens.AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx)).Equal(sdk.NewInt(5)))
}
// tests slashRedelegation
func TestSlashRedelegation(t *testing.T) {
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
f, addrDels, addrVals := bootstrapSlashTest(t, 10)
fraction := sdk.NewDecWithPrec(5, 1)
// add bonded tokens to pool for (re)delegations
startCoins := sdk.NewCoins(sdk.NewInt64Coin(app.StakingKeeper.BondDenom(ctx), 15))
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
_ = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
startCoins := sdk.NewCoins(sdk.NewInt64Coin(f.stakingKeeper.BondDenom(f.sdkCtx), 15))
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
_ = f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
assert.NilError(t, banktestutil.FundModuleAccount(ctx, app.BankKeeper, bondedPool.GetName(), startCoins))
app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, bondedPool.GetName(), startCoins))
f.accountKeeper.SetModuleAccount(f.sdkCtx, bondedPool)
// set a redelegation with an expiration timestamp beyond which the
// redelegation shouldn't be slashed
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0,
time.Unix(5, 0), sdk.NewInt(10), math.LegacyNewDec(10), 0)
app.StakingKeeper.SetRedelegation(ctx, rd)
f.stakingKeeper.SetRedelegation(f.sdkCtx, rd)
// set the associated delegation
del := types.NewDelegation(addrDels[0], addrVals[1], math.LegacyNewDec(10))
app.StakingKeeper.SetDelegation(ctx, del)
f.stakingKeeper.SetDelegation(f.sdkCtx, del)
// started redelegating prior to the current height, stake didn't contribute to infraction
validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[1])
validator, found := f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
assert.Assert(t, found)
slashAmount := app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 1, fraction)
slashAmount := f.stakingKeeper.SlashRedelegation(f.sdkCtx, validator, rd, 1, fraction)
assert.Assert(t, slashAmount.Equal(sdk.NewInt(0)))
// after the expiration time, no longer eligible for slashing
ctx = ctx.WithBlockHeader(cmtproto.Header{Time: time.Unix(10, 0)})
app.StakingKeeper.SetRedelegation(ctx, rd)
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
f.sdkCtx = f.sdkCtx.WithBlockHeader(cmtproto.Header{Time: time.Unix(10, 0)})
f.stakingKeeper.SetRedelegation(f.sdkCtx, rd)
validator, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
assert.Assert(t, found)
slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction)
slashAmount = f.stakingKeeper.SlashRedelegation(f.sdkCtx, validator, rd, 0, fraction)
assert.Assert(t, slashAmount.Equal(sdk.NewInt(0)))
balances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
balances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
// test valid slash, before expiration timestamp and to which stake contributed
ctx = ctx.WithBlockHeader(cmtproto.Header{Time: time.Unix(0, 0)})
app.StakingKeeper.SetRedelegation(ctx, rd)
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
f.sdkCtx = f.sdkCtx.WithBlockHeader(cmtproto.Header{Time: time.Unix(0, 0)})
f.stakingKeeper.SetRedelegation(f.sdkCtx, rd)
validator, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
assert.Assert(t, found)
slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction)
slashAmount = f.stakingKeeper.SlashRedelegation(f.sdkCtx, validator, rd, 0, fraction)
assert.Assert(t, slashAmount.Equal(sdk.NewInt(5)))
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1])
assert.Assert(t, found)
assert.Assert(t, len(rd.Entries) == 1)
// end block
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
applyValidatorSetUpdates(t, f.sdkCtx, f.stakingKeeper, 1)
// initialbalance unchanged
assert.DeepEqual(t, sdk.NewInt(10), rd.Entries[0].InitialBalance)
// shares decreased
del, found = app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[1])
del, found = f.stakingKeeper.GetDelegation(f.sdkCtx, addrDels[0], addrVals[1])
assert.Assert(t, found)
assert.Equal(t, int64(5), del.Shares.RoundInt64())
// pool bonded tokens should decrease
burnedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), slashAmount))
assert.DeepEqual(t, balances.Sub(burnedCoins...), app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()))
burnedCoins := sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), slashAmount))
assert.DeepEqual(t, balances.Sub(burnedCoins...), f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress()))
}
// test slash at a negative height
// this just represents pre-genesis and should have the same effect as slashing at height 0
func TestSlashAtNegativeHeight(t *testing.T) {
app, ctx, _, _ := bootstrapSlashTest(t, 10)
f, _, _ := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
oldBondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
_, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
_, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
app.StakingKeeper.Slash(ctx, consAddr, -2, 10, fraction)
f.stakingKeeper.Slash(f.sdkCtx, consAddr, -2, 10, fraction)
// read updated state
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
// end block
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
applyValidatorSetUpdates(t, f.sdkCtx, f.stakingKeeper, 1)
validator, found = app.StakingKeeper.GetValidator(ctx, validator.GetOperator())
validator, found = f.stakingKeeper.GetValidator(f.sdkCtx, validator.GetOperator())
assert.Assert(t, found)
// power decreased
assert.Equal(t, int64(5), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
assert.Equal(t, int64(5), validator.GetConsensusPower(f.stakingKeeper.PowerReduction(f.sdkCtx)))
// pool bonded shares decreased
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(app.StakingKeeper.BondDenom(ctx))
assert.DeepEqual(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 5).String(), diffTokens.String())
newBondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 5).String(), diffTokens.String())
}
// tests Slash at the current height
func TestSlashValidatorAtCurrentHeight(t *testing.T) {
app, ctx, _, _ := bootstrapSlashTest(t, 10)
f, _, _ := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
oldBondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
_, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
_, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
app.StakingKeeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction)
f.stakingKeeper.Slash(f.sdkCtx, consAddr, f.sdkCtx.BlockHeight(), 10, fraction)
// read updated state
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
// end block
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
applyValidatorSetUpdates(t, f.sdkCtx, f.stakingKeeper, 1)
validator, found = app.StakingKeeper.GetValidator(ctx, validator.GetOperator())
validator, found = f.stakingKeeper.GetValidator(f.sdkCtx, validator.GetOperator())
assert.Assert(t, found)
// power decreased
assert.Equal(t, int64(5), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
assert.Equal(t, int64(5), validator.GetConsensusPower(f.stakingKeeper.PowerReduction(f.sdkCtx)))
// pool bonded shares decreased
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(app.StakingKeeper.BondDenom(ctx))
assert.DeepEqual(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 5).String(), diffTokens.String())
newBondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 5).String(), diffTokens.String())
}
// tests Slash at a previous height with an unbonding delegation
func TestSlashWithUnbondingDelegation(t *testing.T) {
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
f, addrDels, addrVals := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
// set an unbonding delegation with expiration timestamp beyond which the
// unbonding delegation shouldn't be slashed
ubdTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 4)
ubdTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 4)
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, time.Unix(0, 0), ubdTokens, 0)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd)
// slash validator for the first time
ctx = ctx.WithBlockHeight(12)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
f.sdkCtx = f.sdkCtx.WithBlockHeight(12)
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
oldBondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
_, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
_, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction)
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, fraction)
// end block
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
applyValidatorSetUpdates(t, f.sdkCtx, f.stakingKeeper, 1)
// read updating unbonding delegation
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
ubd, found = f.stakingKeeper.GetUnbondingDelegation(f.sdkCtx, addrDels[0], addrVals[0])
assert.Assert(t, found)
assert.Assert(t, len(ubd.Entries) == 1)
// balance decreased
assert.DeepEqual(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 2), ubd.Entries[0].Balance)
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 2), ubd.Entries[0].Balance)
// bonded tokens burned
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(app.StakingKeeper.BondDenom(ctx))
assert.DeepEqual(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 3), diffTokens)
newBondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 3), diffTokens)
// read updated validator
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
// power decreased by 3 - 6 stake originally bonded at the time of infraction
// was still bonded at the time of discovery and was slashed by half, 4 stake
// bonded at the time of discovery hadn't been bonded at the time of infraction
// and wasn't slashed
assert.Equal(t, int64(7), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
assert.Equal(t, int64(7), validator.GetConsensusPower(f.stakingKeeper.PowerReduction(f.sdkCtx)))
// slash validator again
ctx = ctx.WithBlockHeight(13)
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
f.sdkCtx = f.sdkCtx.WithBlockHeight(13)
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 9, 10, fraction)
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
ubd, found = f.stakingKeeper.GetUnbondingDelegation(f.sdkCtx, addrDels[0], addrVals[0])
assert.Assert(t, found)
assert.Assert(t, len(ubd.Entries) == 1)
@ -283,25 +283,25 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
assert.DeepEqual(t, sdk.NewInt(0), ubd.Entries[0].Balance)
// bonded tokens burned again
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(app.StakingKeeper.BondDenom(ctx))
assert.DeepEqual(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 6), diffTokens)
newBondedPoolBalances = f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 6), diffTokens)
// read updated validator
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
// power decreased by 3 again
assert.Equal(t, int64(4), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
assert.Equal(t, int64(4), validator.GetConsensusPower(f.stakingKeeper.PowerReduction(f.sdkCtx)))
// slash validator again
// all originally bonded stake has been slashed, so this will have no effect
// on the unbonding delegation, but it will slash stake bonded since the infraction
// this may not be the desirable behavior, ref https://github.com/cosmos/cosmos-sdk/issues/1440
ctx = ctx.WithBlockHeight(13)
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
f.sdkCtx = f.sdkCtx.WithBlockHeight(13)
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 9, 10, fraction)
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
ubd, found = f.stakingKeeper.GetUnbondingDelegation(f.sdkCtx, addrDels[0], addrVals[0])
assert.Assert(t, found)
assert.Assert(t, len(ubd.Entries) == 1)
@ -309,25 +309,25 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
assert.DeepEqual(t, sdk.NewInt(0), ubd.Entries[0].Balance)
// bonded tokens burned again
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(app.StakingKeeper.BondDenom(ctx))
assert.DeepEqual(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 9), diffTokens)
newBondedPoolBalances = f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 9), diffTokens)
// read updated validator
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
// power decreased by 3 again
assert.Equal(t, int64(1), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
assert.Equal(t, int64(1), validator.GetConsensusPower(f.stakingKeeper.PowerReduction(f.sdkCtx)))
// slash validator again
// all originally bonded stake has been slashed, so this will have no effect
// on the unbonding delegation, but it will slash stake bonded since the infraction
// this may not be the desirable behavior, ref https://github.com/cosmos/cosmos-sdk/issues/1440
ctx = ctx.WithBlockHeight(13)
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
f.sdkCtx = f.sdkCtx.WithBlockHeight(13)
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 9, 10, fraction)
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
ubd, found = f.stakingKeeper.GetUnbondingDelegation(f.sdkCtx, addrDels[0], addrVals[0])
assert.Assert(t, found)
assert.Assert(t, len(ubd.Entries) == 1)
@ -335,259 +335,259 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
assert.DeepEqual(t, sdk.NewInt(0), ubd.Entries[0].Balance)
// just 1 bonded token burned again since that's all the validator now has
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(app.StakingKeeper.BondDenom(ctx))
assert.DeepEqual(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 10), diffTokens)
newBondedPoolBalances = f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10), diffTokens)
// apply TM updates
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
applyValidatorSetUpdates(t, f.sdkCtx, f.stakingKeeper, -1)
// read updated validator
// power decreased by 1 again, validator is out of stake
// validator should be in unbonding period
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, _ = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Equal(t, validator.GetStatus(), types.Unbonding)
}
// tests Slash at a previous height with a redelegation
func TestSlashWithRedelegation(t *testing.T) {
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
f, addrDels, addrVals := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondDenom := app.StakingKeeper.BondDenom(ctx)
bondDenom := f.stakingKeeper.BondDenom(f.sdkCtx)
// set a redelegation
rdTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6)
rdTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 6)
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, time.Unix(0, 0), rdTokens, sdk.NewDecFromInt(rdTokens), 0)
app.StakingKeeper.SetRedelegation(ctx, rd)
f.stakingKeeper.SetRedelegation(f.sdkCtx, rd)
// set the associated delegation
del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDecFromInt(rdTokens))
app.StakingKeeper.SetDelegation(ctx, del)
f.stakingKeeper.SetDelegation(f.sdkCtx, del)
// update bonded tokens
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
rdCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdTokens.MulRaw(2)))
assert.NilError(t, banktestutil.FundModuleAccount(ctx, app.BankKeeper, bondedPool.GetName(), rdCoins))
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, bondedPool.GetName(), rdCoins))
app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
f.accountKeeper.SetModuleAccount(f.sdkCtx, bondedPool)
oldBonded := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
oldBonded := f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := f.bankKeeper.GetBalance(f.sdkCtx, notBondedPool.GetAddress(), bondDenom).Amount
// slash validator
ctx = ctx.WithBlockHeight(12)
_, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
f.sdkCtx = f.sdkCtx.WithBlockHeight(12)
_, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
require.NotPanics(t, func() {
app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction)
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, fraction)
})
burnAmount := sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 10)).Mul(fraction).TruncateInt()
burnAmount := sdk.NewDecFromInt(f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10)).Mul(fraction).TruncateInt()
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
bondedPool = f.stakingKeeper.GetBondedPool(f.sdkCtx)
notBondedPool = f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
// burn bonded tokens from only from delegations
bondedPoolBalance := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance := f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
notBondedPoolBalance := f.bankKeeper.GetBalance(f.sdkCtx, notBondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldNotBonded, notBondedPoolBalance))
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldBonded = f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
// read updating redelegation
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1])
assert.Assert(t, found)
assert.Assert(t, len(rd.Entries) == 1)
// read updated validator
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
// power decreased by 2 - 4 stake originally bonded at the time of infraction
// was still bonded at the time of discovery and was slashed by half, 4 stake
// bonded at the time of discovery hadn't been bonded at the time of infraction
// and wasn't slashed
assert.Equal(t, int64(8), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
assert.Equal(t, int64(8), validator.GetConsensusPower(f.stakingKeeper.PowerReduction(f.sdkCtx)))
// slash the validator again
_, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
_, found = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
require.NotPanics(t, func() {
app.StakingKeeper.Slash(ctx, consAddr, 10, 10, math.LegacyOneDec())
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, math.LegacyOneDec())
})
burnAmount = app.StakingKeeper.TokensFromConsensusPower(ctx, 7)
burnAmount = f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 7)
// read updated pool
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
bondedPool = f.stakingKeeper.GetBondedPool(f.sdkCtx)
notBondedPool = f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
// seven bonded tokens burned
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance = f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
assert.Assert(math.IntEq(t, oldNotBonded, notBondedPoolBalance))
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance = f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
notBondedPoolBalance = f.bankKeeper.GetBalance(f.sdkCtx, notBondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldNotBonded, notBondedPoolBalance))
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldBonded = f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
// read updating redelegation
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1])
assert.Assert(t, found)
assert.Assert(t, len(rd.Entries) == 1)
// read updated validator
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
// power decreased by 4
assert.Equal(t, int64(4), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
assert.Equal(t, int64(4), validator.GetConsensusPower(f.stakingKeeper.PowerReduction(f.sdkCtx)))
// slash the validator again, by 100%
ctx = ctx.WithBlockHeight(12)
_, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
f.sdkCtx = f.sdkCtx.WithBlockHeight(12)
_, found = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Assert(t, found)
require.NotPanics(t, func() {
app.StakingKeeper.Slash(ctx, consAddr, 10, 10, math.LegacyOneDec())
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, math.LegacyOneDec())
})
burnAmount = sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 10)).Mul(math.LegacyOneDec()).TruncateInt()
burnAmount = sdk.NewDecFromInt(f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10)).Mul(math.LegacyOneDec()).TruncateInt()
burnAmount = burnAmount.Sub(math.LegacyOneDec().MulInt(rdTokens).TruncateInt())
// read updated pool
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
bondedPool = f.stakingKeeper.GetBondedPool(f.sdkCtx)
notBondedPool = f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance = f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
notBondedPoolBalance = f.bankKeeper.GetBalance(f.sdkCtx, notBondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldNotBonded, notBondedPoolBalance))
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldBonded = f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
// read updating redelegation
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1])
assert.Assert(t, found)
assert.Assert(t, len(rd.Entries) == 1)
// apply TM updates
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
applyValidatorSetUpdates(t, f.sdkCtx, f.stakingKeeper, -1)
// read updated validator
// validator decreased to zero power, should be in unbonding period
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, _ = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Equal(t, validator.GetStatus(), types.Unbonding)
// slash the validator again, by 100%
// no stake remains to be slashed
ctx = ctx.WithBlockHeight(12)
f.sdkCtx = f.sdkCtx.WithBlockHeight(12)
// validator still in unbonding period
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, _ = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Equal(t, validator.GetStatus(), types.Unbonding)
require.NotPanics(t, func() {
app.StakingKeeper.Slash(ctx, consAddr, 10, 10, math.LegacyOneDec())
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, math.LegacyOneDec())
})
// read updated pool
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
bondedPool = f.stakingKeeper.GetBondedPool(f.sdkCtx)
notBondedPool = f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance = f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldBonded, bondedPoolBalance))
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
notBondedPoolBalance = f.bankKeeper.GetBalance(f.sdkCtx, notBondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldNotBonded, notBondedPoolBalance))
// read updating redelegation
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1])
assert.Assert(t, found)
assert.Assert(t, len(rd.Entries) == 1)
// read updated validator
// power still zero, still in unbonding period
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
validator, _ = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Equal(t, validator.GetStatus(), types.Unbonding)
}
// tests Slash at a previous height with both an unbonding delegation and a redelegation
func TestSlashBoth(t *testing.T) {
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
f, addrDels, addrVals := bootstrapSlashTest(t, 10)
fraction := sdk.NewDecWithPrec(5, 1)
bondDenom := app.StakingKeeper.BondDenom(ctx)
bondDenom := f.stakingKeeper.BondDenom(f.sdkCtx)
// set a redelegation with expiration timestamp beyond which the
// redelegation shouldn't be slashed
rdATokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6)
rdATokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 6)
rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, time.Unix(0, 0), rdATokens, sdk.NewDecFromInt(rdATokens), 0)
app.StakingKeeper.SetRedelegation(ctx, rdA)
f.stakingKeeper.SetRedelegation(f.sdkCtx, rdA)
// set the associated delegation
delA := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDecFromInt(rdATokens))
app.StakingKeeper.SetDelegation(ctx, delA)
f.stakingKeeper.SetDelegation(f.sdkCtx, delA)
// set an unbonding delegation with expiration timestamp (beyond which the
// unbonding delegation shouldn't be slashed)
ubdATokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 4)
ubdATokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 4)
ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
time.Unix(0, 0), ubdATokens, 0)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubdA)
f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubdA)
bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdATokens.MulRaw(2)))
notBondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, ubdATokens))
// update bonded tokens
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
assert.NilError(t, banktestutil.FundModuleAccount(ctx, app.BankKeeper, bondedPool.GetName(), bondedCoins))
assert.NilError(t, banktestutil.FundModuleAccount(ctx, app.BankKeeper, notBondedPool.GetName(), notBondedCoins))
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, bondedPool.GetName(), bondedCoins))
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, notBondedPool.GetName(), notBondedCoins))
app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
f.accountKeeper.SetModuleAccount(f.sdkCtx, bondedPool)
f.accountKeeper.SetModuleAccount(f.sdkCtx, notBondedPool)
oldBonded := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
oldBonded := f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := f.bankKeeper.GetBalance(f.sdkCtx, notBondedPool.GetAddress(), bondDenom).Amount
// slash validator
ctx = ctx.WithBlockHeight(12)
_, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
f.sdkCtx = f.sdkCtx.WithBlockHeight(12)
_, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, sdk.GetConsAddress(PKs[0]))
assert.Assert(t, found)
consAddr0 := sdk.ConsAddress(PKs[0].Address())
app.StakingKeeper.Slash(ctx, consAddr0, 10, 10, fraction)
f.stakingKeeper.Slash(f.sdkCtx, consAddr0, 10, 10, fraction)
burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt()
burnedBondAmount := sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 10)).Mul(fraction).TruncateInt()
burnedBondAmount := sdk.NewDecFromInt(f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10)).Mul(fraction).TruncateInt()
burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount)
// read updated pool
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
bondedPool = f.stakingKeeper.GetBondedPool(f.sdkCtx)
notBondedPool = f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
bondedPoolBalance := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance := f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldBonded.Sub(burnedBondAmount), bondedPoolBalance))
notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
notBondedPoolBalance := f.bankKeeper.GetBalance(f.sdkCtx, notBondedPool.GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, oldNotBonded.Sub(burnedNotBondedAmount), notBondedPoolBalance))
// read updating redelegation
rdA, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
rdA, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1])
assert.Assert(t, found)
assert.Assert(t, len(rdA.Entries) == 1)
// read updated validator
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
validator, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, sdk.GetConsAddress(PKs[0]))
assert.Assert(t, found)
// power not decreased, all stake was bonded since
assert.Equal(t, int64(10), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
assert.Equal(t, int64(10), validator.GetConsensusPower(f.stakingKeeper.PowerReduction(f.sdkCtx)))
}
func TestSlashAmount(t *testing.T) {
app, ctx, _, _ := bootstrapSlashTest(t, 10)
f, _, _ := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
burnedCoins := app.StakingKeeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction)
burnedCoins := f.stakingKeeper.Slash(f.sdkCtx, consAddr, f.sdkCtx.BlockHeight(), 10, fraction)
assert.Assert(t, burnedCoins.GT(math.ZeroInt()))
// test the case where the validator was not found, which should return no coins
_, addrVals := generateAddresses(app, ctx, 100)
noBurned := app.StakingKeeper.Slash(ctx, sdk.ConsAddress(addrVals[0]), ctx.BlockHeight(), 10, fraction)
_, addrVals := generateAddresses(f, 100)
noBurned := f.stakingKeeper.Slash(f.sdkCtx, sdk.ConsAddress(addrVals[0]), f.sdkCtx.BlockHeight(), 10, fraction)
assert.Assert(t, sdk.NewInt(0).Equal(noBurned))
}

View File

@ -5,7 +5,6 @@ import (
"time"
"cosmossdk.io/math"
"cosmossdk.io/simapp"
"github.com/golang/mock/gomock"
"gotest.tools/v3/assert"
@ -18,7 +17,7 @@ import (
)
// SetupUnbondingTests creates two validators and setup mocked staking hooks for testing unbonding
func SetupUnbondingTests(t *testing.T, app *simapp.SimApp, ctx sdk.Context, hookCalled *bool, ubdeID *uint64) (bondDenom string, addrDels []sdk.AccAddress, addrVals []sdk.ValAddress) {
func SetupUnbondingTests(t *testing.T, f *fixture, hookCalled *bool, ubdeID *uint64) (bondDenom string, addrDels []sdk.AccAddress, addrVals []sdk.ValAddress) {
// setup hooks
mockCtrl := gomock.NewController(t)
mockStackingHooks := testutil.NewMockStakingHooks(mockCtrl)
@ -28,7 +27,7 @@ func SetupUnbondingTests(t *testing.T, app *simapp.SimApp, ctx sdk.Context, hook
// save id
*ubdeID = id
// call back to stop unbonding
err := app.StakingKeeper.PutUnbondingOnHold(ctx, id)
err := f.stakingKeeper.PutUnbondingOnHold(f.sdkCtx, id)
assert.NilError(t, err)
return nil
@ -42,40 +41,40 @@ func SetupUnbondingTests(t *testing.T, app *simapp.SimApp, ctx sdk.Context, hook
mockStackingHooks.EXPECT().BeforeDelegationSharesModified(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
mockStackingHooks.EXPECT().BeforeValidatorModified(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
mockStackingHooks.EXPECT().BeforeValidatorSlashed(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
app.StakingKeeper.SetHooks(types.NewMultiStakingHooks(mockStackingHooks))
f.stakingKeeper.SetHooks(types.NewMultiStakingHooks(mockStackingHooks))
addrDels = simtestutil.AddTestAddrsIncremental(app.BankKeeper, app.StakingKeeper, ctx, 2, math.NewInt(10000))
addrDels = simtestutil.AddTestAddrsIncremental(f.bankKeeper, f.stakingKeeper, f.sdkCtx, 2, math.NewInt(10000))
addrVals = simtestutil.ConvertAddrsToValAddrs(addrDels)
valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 20)
valTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10)
startTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 20)
bondDenom = app.StakingKeeper.BondDenom(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
bondDenom = f.stakingKeeper.BondDenom(f.sdkCtx)
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
assert.NilError(t, banktestutil.FundModuleAccount(ctx, app.BankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
app.BankKeeper.SendCoinsFromModuleToModule(ctx, types.BondedPoolName, types.NotBondedPoolName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, startTokens)))
app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
f.bankKeeper.SendCoinsFromModuleToModule(f.sdkCtx, types.BondedPoolName, types.NotBondedPoolName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, startTokens)))
f.accountKeeper.SetModuleAccount(f.sdkCtx, notBondedPool)
// Create a validator
validator1 := testutil.NewValidator(t, addrVals[0], PKs[0])
validator1, issuedShares1 := validator1.AddTokensFromDel(valTokens)
assert.DeepEqual(t, valTokens, issuedShares1.RoundInt())
validator1 = stakingkeeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator1, true)
validator1 = stakingkeeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validator1, true)
assert.Assert(math.IntEq(t, valTokens, validator1.BondedTokens()))
assert.Assert(t, validator1.IsBonded())
// Create a delegator
delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares1)
app.StakingKeeper.SetDelegation(ctx, delegation)
f.stakingKeeper.SetDelegation(f.sdkCtx, delegation)
// Create a validator to redelegate to
validator2 := testutil.NewValidator(t, addrVals[1], PKs[1])
validator2, issuedShares2 := validator2.AddTokensFromDel(valTokens)
assert.DeepEqual(t, valTokens, issuedShares2.RoundInt())
validator2 = stakingkeeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true)
validator2 = stakingkeeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validator2, true)
assert.Equal(t, types.Bonded, validator2.Status)
assert.Assert(t, validator2.IsBonded())
@ -168,67 +167,71 @@ func doValidatorUnbonding(
}
func TestValidatorUnbondingOnHold1(t *testing.T) {
t.Parallel()
f := initFixture(t)
var (
hookCalled bool
ubdeID uint64
)
_, app, ctx := createTestInput(t)
_, _, addrVals := SetupUnbondingTests(t, app, ctx, &hookCalled, &ubdeID)
_, _, addrVals := SetupUnbondingTests(t, f, &hookCalled, &ubdeID)
// Start unbonding first validator
validator := doValidatorUnbonding(t, app.StakingKeeper, ctx, addrVals[0], &hookCalled)
validator := doValidatorUnbonding(t, f.stakingKeeper, f.sdkCtx, addrVals[0], &hookCalled)
completionTime := validator.UnbondingTime
completionHeight := validator.UnbondingHeight
// CONSUMER CHAIN'S UNBONDING PERIOD ENDS - STOPPED UNBONDING CAN NOW COMPLETE
err := app.StakingKeeper.UnbondingCanComplete(ctx, ubdeID)
err := f.stakingKeeper.UnbondingCanComplete(f.sdkCtx, ubdeID)
assert.NilError(t, err)
// Try to unbond validator
app.StakingKeeper.UnbondAllMatureValidators(ctx)
f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx)
// Check that validator unbonding is not complete (is not mature yet)
validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
validator, found := f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[0])
assert.Assert(t, found)
assert.Equal(t, types.Unbonding, validator.Status)
unbondingVals := app.StakingKeeper.GetUnbondingValidators(ctx, completionTime, completionHeight)
unbondingVals := f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
assert.Equal(t, 1, len(unbondingVals))
assert.Equal(t, validator.OperatorAddress, unbondingVals[0])
// PROVIDER CHAIN'S UNBONDING PERIOD ENDS - BUT UNBONDING CANNOT COMPLETE
ctx = ctx.WithBlockTime(completionTime.Add(time.Duration(1)))
ctx = ctx.WithBlockHeight(completionHeight + 1)
app.StakingKeeper.UnbondAllMatureValidators(ctx)
f.sdkCtx = f.sdkCtx.WithBlockTime(completionTime.Add(time.Duration(1)))
f.sdkCtx = f.sdkCtx.WithBlockHeight(completionHeight + 1)
f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx)
// Check that validator unbonding is complete
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
validator, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[0])
assert.Assert(t, found)
assert.Equal(t, types.Unbonded, validator.Status)
unbondingVals = app.StakingKeeper.GetUnbondingValidators(ctx, completionTime, completionHeight)
unbondingVals = f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
assert.Equal(t, 0, len(unbondingVals))
}
func TestValidatorUnbondingOnHold2(t *testing.T) {
t.Parallel()
f := initFixture(t)
var (
hookCalled bool
ubdeID uint64
ubdeIDs []uint64
)
_, app, ctx := createTestInput(t)
_, _, addrVals := SetupUnbondingTests(t, app, ctx, &hookCalled, &ubdeID)
_, _, addrVals := SetupUnbondingTests(t, f, &hookCalled, &ubdeID)
// Start unbonding first validator
validator1 := doValidatorUnbonding(t, app.StakingKeeper, ctx, addrVals[0], &hookCalled)
validator1 := doValidatorUnbonding(t, f.stakingKeeper, f.sdkCtx, addrVals[0], &hookCalled)
ubdeIDs = append(ubdeIDs, ubdeID)
// Reset hookCalled flag
hookCalled = false
// Start unbonding second validator
validator2 := doValidatorUnbonding(t, app.StakingKeeper, ctx, addrVals[1], &hookCalled)
validator2 := doValidatorUnbonding(t, f.stakingKeeper, f.sdkCtx, addrVals[1], &hookCalled)
ubdeIDs = append(ubdeIDs, ubdeID)
// Check that there are two unbonding operations
@ -241,127 +244,136 @@ func TestValidatorUnbondingOnHold2(t *testing.T) {
completionHeight := validator1.UnbondingHeight
// PROVIDER CHAIN'S UNBONDING PERIOD ENDS - BUT UNBONDING CANNOT COMPLETE
ctx = ctx.WithBlockTime(completionTime.Add(time.Duration(1)))
ctx = ctx.WithBlockHeight(completionHeight + 1)
app.StakingKeeper.UnbondAllMatureValidators(ctx)
f.sdkCtx = f.sdkCtx.WithBlockTime(completionTime.Add(time.Duration(1)))
f.sdkCtx = f.sdkCtx.WithBlockHeight(completionHeight + 1)
f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx)
// Check that unbonding is not complete for both validators
validator1, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
validator1, found := f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[0])
assert.Assert(t, found)
assert.Equal(t, types.Unbonding, validator1.Status)
validator2, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
validator2, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
assert.Assert(t, found)
assert.Equal(t, types.Unbonding, validator2.Status)
unbondingVals := app.StakingKeeper.GetUnbondingValidators(ctx, completionTime, completionHeight)
unbondingVals := f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
assert.Equal(t, 2, len(unbondingVals))
assert.Equal(t, validator1.OperatorAddress, unbondingVals[0])
assert.Equal(t, validator2.OperatorAddress, unbondingVals[1])
// CONSUMER CHAIN'S UNBONDING PERIOD ENDS - STOPPED UNBONDING CAN NOW COMPLETE
err := app.StakingKeeper.UnbondingCanComplete(ctx, ubdeIDs[0])
err := f.stakingKeeper.UnbondingCanComplete(f.sdkCtx, ubdeIDs[0])
assert.NilError(t, err)
// Try again to unbond validators
app.StakingKeeper.UnbondAllMatureValidators(ctx)
f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx)
// Check that unbonding is complete for validator1, but not for validator2
validator1, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
validator1, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[0])
assert.Assert(t, found)
assert.Equal(t, types.Unbonded, validator1.Status)
validator2, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
validator2, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
assert.Assert(t, found)
assert.Equal(t, types.Unbonding, validator2.Status)
unbondingVals = app.StakingKeeper.GetUnbondingValidators(ctx, completionTime, completionHeight)
unbondingVals = f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
assert.Equal(t, 1, len(unbondingVals))
assert.Equal(t, validator2.OperatorAddress, unbondingVals[0])
// Unbonding for validator2 can complete
err = app.StakingKeeper.UnbondingCanComplete(ctx, ubdeIDs[1])
err = f.stakingKeeper.UnbondingCanComplete(f.sdkCtx, ubdeIDs[1])
assert.NilError(t, err)
// Try again to unbond validators
app.StakingKeeper.UnbondAllMatureValidators(ctx)
f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx)
// Check that unbonding is complete for validator2
validator2, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
validator2, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
assert.Assert(t, found)
assert.Equal(t, types.Unbonded, validator2.Status)
unbondingVals = app.StakingKeeper.GetUnbondingValidators(ctx, completionTime, completionHeight)
unbondingVals = f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
assert.Equal(t, 0, len(unbondingVals))
}
func TestRedelegationOnHold1(t *testing.T) {
t.Parallel()
f := initFixture(t)
var (
hookCalled bool
ubdeID uint64
)
_, app, ctx := createTestInput(t)
_, addrDels, addrVals := SetupUnbondingTests(t, app, ctx, &hookCalled, &ubdeID)
completionTime := doRedelegation(t, app.StakingKeeper, ctx, addrDels, addrVals, &hookCalled)
// _, app, ctx := createTestInput(t)
_, addrDels, addrVals := SetupUnbondingTests(t, f, &hookCalled, &ubdeID)
completionTime := doRedelegation(t, f.stakingKeeper, f.sdkCtx, addrDels, addrVals, &hookCalled)
// CONSUMER CHAIN'S UNBONDING PERIOD ENDS - BUT UNBONDING CANNOT COMPLETE
err := app.StakingKeeper.UnbondingCanComplete(ctx, ubdeID)
err := f.stakingKeeper.UnbondingCanComplete(f.sdkCtx, ubdeID)
assert.NilError(t, err)
// Redelegation is not complete - still exists
redelegations := app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
redelegations := f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
assert.Equal(t, 1, len(redelegations))
// PROVIDER CHAIN'S UNBONDING PERIOD ENDS - STOPPED UNBONDING CAN NOW COMPLETE
ctx = ctx.WithBlockTime(completionTime)
_, err = app.StakingKeeper.CompleteRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
f.sdkCtx = f.sdkCtx.WithBlockTime(completionTime)
_, err = f.stakingKeeper.CompleteRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1])
assert.NilError(t, err)
// Redelegation is complete and record is gone
redelegations = app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
redelegations = f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
assert.Equal(t, 0, len(redelegations))
}
func TestRedelegationOnHold2(t *testing.T) {
t.Parallel()
f := initFixture(t)
var (
hookCalled bool
ubdeID uint64
)
_, app, ctx := createTestInput(t)
_, addrDels, addrVals := SetupUnbondingTests(t, app, ctx, &hookCalled, &ubdeID)
completionTime := doRedelegation(t, app.StakingKeeper, ctx, addrDels, addrVals, &hookCalled)
// _, app, ctx := createTestInput(t)
_, addrDels, addrVals := SetupUnbondingTests(t, f, &hookCalled, &ubdeID)
completionTime := doRedelegation(t, f.stakingKeeper, f.sdkCtx, addrDels, addrVals, &hookCalled)
// PROVIDER CHAIN'S UNBONDING PERIOD ENDS - BUT UNBONDING CANNOT COMPLETE
ctx = ctx.WithBlockTime(completionTime)
_, err := app.StakingKeeper.CompleteRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
f.sdkCtx = f.sdkCtx.WithBlockTime(completionTime)
_, err := f.stakingKeeper.CompleteRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1])
assert.NilError(t, err)
// Redelegation is not complete - still exists
redelegations := app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
redelegations := f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
assert.Equal(t, 1, len(redelegations))
// CONSUMER CHAIN'S UNBONDING PERIOD ENDS - STOPPED UNBONDING CAN NOW COMPLETE
err = app.StakingKeeper.UnbondingCanComplete(ctx, ubdeID)
err = f.stakingKeeper.UnbondingCanComplete(f.sdkCtx, ubdeID)
assert.NilError(t, err)
// Redelegation is complete and record is gone
redelegations = app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
redelegations = f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
assert.Equal(t, 0, len(redelegations))
}
func TestUnbondingDelegationOnHold1(t *testing.T) {
t.Parallel()
f := initFixture(t)
var (
hookCalled bool
ubdeID uint64
)
_, app, ctx := createTestInput(t)
bondDenom, addrDels, addrVals := SetupUnbondingTests(t, app, ctx, &hookCalled, &ubdeID)
completionTime, bondedAmt1, notBondedAmt1 := doUnbondingDelegation(t, app.StakingKeeper, app.BankKeeper, ctx, bondDenom, addrDels, addrVals, &hookCalled)
// _, app, ctx := createTestInput(t)
bondDenom, addrDels, addrVals := SetupUnbondingTests(t, f, &hookCalled, &ubdeID)
completionTime, bondedAmt1, notBondedAmt1 := doUnbondingDelegation(t, f.stakingKeeper, f.bankKeeper, f.sdkCtx, bondDenom, addrDels, addrVals, &hookCalled)
// CONSUMER CHAIN'S UNBONDING PERIOD ENDS - BUT UNBONDING CANNOT COMPLETE
err := app.StakingKeeper.UnbondingCanComplete(ctx, ubdeID)
err := f.stakingKeeper.UnbondingCanComplete(f.sdkCtx, ubdeID)
assert.NilError(t, err)
bondedAmt3 := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
notBondedAmt3 := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
bondedAmt3 := f.bankKeeper.GetBalance(f.sdkCtx, f.stakingKeeper.GetBondedPool(f.sdkCtx).GetAddress(), bondDenom).Amount
notBondedAmt3 := f.bankKeeper.GetBalance(f.sdkCtx, f.stakingKeeper.GetNotBondedPool(f.sdkCtx).GetAddress(), bondDenom).Amount
// Bonded and unbonded amounts are the same as before because the completionTime has not yet passed and so the
// unbondingDelegation has not completed
@ -369,13 +381,13 @@ func TestUnbondingDelegationOnHold1(t *testing.T) {
assert.Assert(math.IntEq(t, notBondedAmt1, notBondedAmt3))
// PROVIDER CHAIN'S UNBONDING PERIOD ENDS - STOPPED UNBONDING CAN NOW COMPLETE
ctx = ctx.WithBlockTime(completionTime)
_, err = app.StakingKeeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0])
f.sdkCtx = f.sdkCtx.WithBlockTime(completionTime)
_, err = f.stakingKeeper.CompleteUnbonding(f.sdkCtx, addrDels[0], addrVals[0])
assert.NilError(t, err)
// Check that the unbonding was finally completed
bondedAmt5 := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
notBondedAmt5 := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
bondedAmt5 := f.bankKeeper.GetBalance(f.sdkCtx, f.stakingKeeper.GetBondedPool(f.sdkCtx).GetAddress(), bondDenom).Amount
notBondedAmt5 := f.bankKeeper.GetBalance(f.sdkCtx, f.stakingKeeper.GetNotBondedPool(f.sdkCtx).GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, bondedAmt1, bondedAmt5))
// Not bonded amount back to what it was originally
@ -383,22 +395,25 @@ func TestUnbondingDelegationOnHold1(t *testing.T) {
}
func TestUnbondingDelegationOnHold2(t *testing.T) {
t.Parallel()
f := initFixture(t)
var (
hookCalled bool
ubdeID uint64
)
_, app, ctx := createTestInput(t)
bondDenom, addrDels, addrVals := SetupUnbondingTests(t, app, ctx, &hookCalled, &ubdeID)
completionTime, bondedAmt1, notBondedAmt1 := doUnbondingDelegation(t, app.StakingKeeper, app.BankKeeper, ctx, bondDenom, addrDels, addrVals, &hookCalled)
// _, app, ctx := createTestInput(t)
bondDenom, addrDels, addrVals := SetupUnbondingTests(t, f, &hookCalled, &ubdeID)
completionTime, bondedAmt1, notBondedAmt1 := doUnbondingDelegation(t, f.stakingKeeper, f.bankKeeper, f.sdkCtx, bondDenom, addrDels, addrVals, &hookCalled)
// PROVIDER CHAIN'S UNBONDING PERIOD ENDS - BUT UNBONDING CANNOT COMPLETE
ctx = ctx.WithBlockTime(completionTime)
_, err := app.StakingKeeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0])
f.sdkCtx = f.sdkCtx.WithBlockTime(completionTime)
_, err := f.stakingKeeper.CompleteUnbonding(f.sdkCtx, addrDels[0], addrVals[0])
assert.NilError(t, err)
bondedAmt3 := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
notBondedAmt3 := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
bondedAmt3 := f.bankKeeper.GetBalance(f.sdkCtx, f.stakingKeeper.GetBondedPool(f.sdkCtx).GetAddress(), bondDenom).Amount
notBondedAmt3 := f.bankKeeper.GetBalance(f.sdkCtx, f.stakingKeeper.GetNotBondedPool(f.sdkCtx).GetAddress(), bondDenom).Amount
// Bonded and unbonded amounts are the same as before because the completionTime has not yet passed and so the
// unbondingDelegation has not completed
@ -406,12 +421,12 @@ func TestUnbondingDelegationOnHold2(t *testing.T) {
assert.Assert(math.IntEq(t, notBondedAmt1, notBondedAmt3))
// CONSUMER CHAIN'S UNBONDING PERIOD ENDS - STOPPED UNBONDING CAN NOW COMPLETE
err = app.StakingKeeper.UnbondingCanComplete(ctx, ubdeID)
err = f.stakingKeeper.UnbondingCanComplete(f.sdkCtx, ubdeID)
assert.NilError(t, err)
// Check that the unbonding was finally completed
bondedAmt5 := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
notBondedAmt5 := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
bondedAmt5 := f.bankKeeper.GetBalance(f.sdkCtx, f.stakingKeeper.GetBondedPool(f.sdkCtx).GetAddress(), bondDenom).Amount
notBondedAmt5 := f.bankKeeper.GetBalance(f.sdkCtx, f.stakingKeeper.GetNotBondedPool(f.sdkCtx).GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, bondedAmt1, bondedAmt5))
// Not bonded amount back to what it was originally

View File

@ -4,8 +4,8 @@ import (
"fmt"
"testing"
"cosmossdk.io/simapp"
storetypes "cosmossdk.io/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
"github.com/cosmos/cosmos-sdk/x/staking/types"
@ -23,16 +23,16 @@ func BenchmarkGetValidator(b *testing.B) {
totalPower += int64(i)
}
app, ctx, _, valAddrs, vals := initValidators(b, totalPower, len(powers), powers)
f, _, valAddrs, vals := initValidators(b, totalPower, len(powers), powers)
for _, validator := range vals {
app.StakingKeeper.SetValidator(ctx, validator)
f.stakingKeeper.SetValidator(f.sdkCtx, validator)
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
for _, addr := range valAddrs {
_, _ = app.StakingKeeper.GetValidator(ctx, addr)
_, _ = f.stakingKeeper.GetValidator(f.sdkCtx, addr)
}
}
}
@ -47,25 +47,25 @@ func BenchmarkGetValidatorDelegations(b *testing.B) {
totalPower += int64(i)
}
app, ctx, _, valAddrs, vals := initValidators(b, totalPower, len(powers), powers)
f, _, valAddrs, vals := initValidators(b, totalPower, len(powers), powers)
for _, validator := range vals {
app.StakingKeeper.SetValidator(ctx, validator)
f.stakingKeeper.SetValidator(f.sdkCtx, validator)
}
delegationsNum := 1000
for _, val := range valAddrs {
for i := 0; i < delegationsNum; i++ {
delegator := sdk.AccAddress(fmt.Sprintf("address%d", i))
banktestutil.FundAccount(ctx, app.BankKeeper, delegator,
banktestutil.FundAccount(f.sdkCtx, f.bankKeeper, delegator,
sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(int64(i)))))
NewDel := types.NewDelegation(delegator, val, sdk.NewDec(int64(i)))
app.StakingKeeper.SetDelegation(ctx, NewDel)
f.stakingKeeper.SetDelegation(f.sdkCtx, NewDel)
}
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
updateValidatorDelegations(ctx, app, valAddrs[0], sdk.ValAddress("val"))
updateValidatorDelegations(f, valAddrs[0], sdk.ValAddress("val"))
}
}
@ -79,34 +79,34 @@ func BenchmarkGetValidatorDelegationsLegacy(b *testing.B) {
totalPower += int64(i)
}
app, ctx, _, valAddrs, vals := initValidators(b, totalPower, len(powers), powers)
f, _, valAddrs, vals := initValidators(b, totalPower, len(powers), powers)
for _, validator := range vals {
app.StakingKeeper.SetValidator(ctx, validator)
f.stakingKeeper.SetValidator(f.sdkCtx, validator)
}
delegationsNum := 1000
for _, val := range valAddrs {
for i := 0; i < delegationsNum; i++ {
delegator := sdk.AccAddress(fmt.Sprintf("address%d", i))
banktestutil.FundAccount(ctx, app.BankKeeper, delegator,
banktestutil.FundAccount(f.sdkCtx, f.bankKeeper, delegator,
sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(int64(i)))))
NewDel := types.NewDelegation(delegator, val, sdk.NewDec(int64(i)))
app.StakingKeeper.SetDelegation(ctx, NewDel)
f.stakingKeeper.SetDelegation(f.sdkCtx, NewDel)
}
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
updateValidatorDelegationsLegacy(ctx, app, valAddrs[0], sdk.ValAddress("val"))
updateValidatorDelegationsLegacy(f, valAddrs[0], sdk.ValAddress("val"))
}
}
func updateValidatorDelegationsLegacy(ctx sdk.Context, app *simapp.SimApp, existingValAddr, newValAddr sdk.ValAddress) {
storeKey := app.GetKey(types.StoreKey)
cdc, k := app.AppCodec(), app.StakingKeeper
func updateValidatorDelegationsLegacy(f *fixture, existingValAddr, newValAddr sdk.ValAddress) {
storeKey := f.keys[types.StoreKey]
cdc, k := f.cdc, f.stakingKeeper
store := ctx.KVStore(storeKey)
store := f.sdkCtx.KVStore(storeKey)
iterator := storetypes.KVStorePrefixIterator(store, types.DelegationKey)
defer iterator.Close()
@ -114,18 +114,18 @@ func updateValidatorDelegationsLegacy(ctx sdk.Context, app *simapp.SimApp, exist
for ; iterator.Valid(); iterator.Next() {
delegation := types.MustUnmarshalDelegation(cdc, iterator.Value())
if delegation.GetValidatorAddr().Equals(existingValAddr) {
k.RemoveDelegation(ctx, delegation)
k.RemoveDelegation(f.sdkCtx, delegation)
delegation.ValidatorAddress = newValAddr.String()
k.SetDelegation(ctx, delegation)
k.SetDelegation(f.sdkCtx, delegation)
}
}
}
func updateValidatorDelegations(ctx sdk.Context, app *simapp.SimApp, existingValAddr, newValAddr sdk.ValAddress) {
storeKey := app.GetKey(types.StoreKey)
cdc, k := app.AppCodec(), app.StakingKeeper
func updateValidatorDelegations(f *fixture, existingValAddr, newValAddr sdk.ValAddress) {
storeKey := f.keys[types.StoreKey]
cdc, k := f.cdc, f.stakingKeeper
store := ctx.KVStore(storeKey)
store := f.sdkCtx.KVStore(storeKey)
itr := storetypes.KVStorePrefixIterator(store, types.GetDelegationsByValPrefixKey(existingValAddr))
defer itr.Close()
@ -141,12 +141,12 @@ func updateValidatorDelegations(ctx sdk.Context, app *simapp.SimApp, existingVal
delegation := types.MustUnmarshalDelegation(cdc, bz)
// remove old operator addr from delegation
if err := k.RemoveDelegation(ctx, delegation); err != nil {
if err := k.RemoveDelegation(f.sdkCtx, delegation); err != nil {
panic(err)
}
delegation.ValidatorAddress = newValAddr.String()
// add with new operator addr
k.SetDelegation(ctx, delegation)
k.SetDelegation(f.sdkCtx, delegation)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -308,6 +308,7 @@ func (s *CLITestSuite) TestNewCreateValidatorCmd() {
func (s *CLITestSuite) TestNewEditValidatorCmd() {
cmd := cli.NewEditValidatorCmd()
moniker := "testing"
details := "bio"
identity := "test identity"
securityContact := "test contact"
@ -382,9 +383,21 @@ func (s *CLITestSuite) TestNewEditValidatorCmd() {
},
"",
},
{
"edit validator moniker", // https://github.com/cosmos/cosmos-sdk/issues/10660
[]string{
fmt.Sprintf("--%s=%s", cli.FlagEditMoniker, moniker),
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()),
},
"",
},
{
"with all edit flags",
[]string{
fmt.Sprintf("--%s=%s", cli.FlagEditMoniker, moniker),
fmt.Sprintf("--details=%s", details),
fmt.Sprintf("--identity=%s", identity),
fmt.Sprintf("--security-contact=%s", securityContact),
@ -499,6 +512,34 @@ func (s *CLITestSuite) TestNewRedelegateCmd() {
},
"invalid decimal coin expression: fooCoin",
},
{
"wrong src validator",
[]string{
"invalid", // wrong src-validator-addr
sdk.ValAddress(s.addrs[1]).String(), // dst-validator-addr
sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(150)).String(), // amount
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=%d", flags.FlagGas, 300000),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()),
},
"invalid bech32",
},
{
"wrong dst validator",
[]string{
sdk.ValAddress(s.addrs[0]).String(), // src-validator-addr
"invalid", // wrong dst-validator-addr
sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(150)).String(), // amount
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=%d", flags.FlagGas, 300000),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()),
},
"invalid bech32",
},
{
"valid transaction of delegate",
[]string{

View File

@ -278,6 +278,68 @@ func (s *KeeperTestSuite) TestUnbondingDelegation() {
require.Equal(0, len(resUnbonds))
}
func (s *KeeperTestSuite) TestUnbondingDelegationsFromValidator() {
ctx, keeper := s.ctx, s.stakingKeeper
require := s.Require()
delAddrs, valAddrs := createValAddrs(2)
for _, addr := range delAddrs {
s.accountKeeper.EXPECT().StringToBytes(addr.String()).Return(addr, nil).AnyTimes()
s.accountKeeper.EXPECT().BytesToString(addr).Return(addr.String(), nil).AnyTimes()
}
ubd := stakingtypes.NewUnbondingDelegation(
delAddrs[0],
valAddrs[0],
0,
time.Unix(0, 0).UTC(),
sdk.NewInt(5),
0,
)
// set and retrieve a record
keeper.SetUnbondingDelegation(ctx, ubd)
resUnbond, found := keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
require.True(found)
require.Equal(ubd, resUnbond)
// modify a records, save, and retrieve
expUnbond := sdk.NewInt(21)
ubd.Entries[0].Balance = expUnbond
keeper.SetUnbondingDelegation(ctx, ubd)
resUnbonds := keeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
require.Equal(1, len(resUnbonds))
resUnbonds = keeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
require.Equal(1, len(resUnbonds))
resUnbonds = keeper.GetUnbondingDelegationsFromValidator(ctx, valAddrs[0])
require.Equal(1, len(resUnbonds))
resUnbond, found = keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
require.True(found)
require.Equal(ubd, resUnbond)
resDelUnbond := keeper.GetDelegatorUnbonding(ctx, delAddrs[0])
require.Equal(expUnbond, resDelUnbond)
// delete a record
keeper.RemoveUnbondingDelegation(ctx, ubd)
_, found = keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
require.False(found)
resUnbonds = keeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
require.Equal(0, len(resUnbonds))
resUnbonds = keeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
require.Equal(0, len(resUnbonds))
resUnbonds = keeper.GetUnbondingDelegationsFromValidator(ctx, valAddrs[0])
require.Equal(0, len(resUnbonds))
}
func (s *KeeperTestSuite) TestUnbondDelegation() {
ctx, keeper := s.ctx, s.stakingKeeper
require := s.Require()

View File

@ -22,6 +22,10 @@ type Querier struct {
var _ types.QueryServer = Querier{}
func NewQuerier(keeper *Keeper) Querier {
return Querier{Keeper: keeper}
}
// Validators queries all validators that match the given status
func (k Querier) Validators(c context.Context, req *types.QueryValidatorsRequest) (*types.QueryValidatorsResponse, error) {
if req == nil {

View File

@ -28,6 +28,15 @@ func (s *KeeperTestSuite) TestGRPCQueryValidator() {
},
false,
},
{
"with valid and not existing address",
func() {
req = &types.QueryValidatorRequest{
ValidatorAddr: "cosmosvaloper15jkng8hytwt22lllv6mw4k89qkqehtahd84ptu",
}
},
false,
},
{
"valid request",
func() {

View File

@ -84,10 +84,14 @@ func (s *KeeperTestSuite) TestParams() {
require := s.Require()
expParams := stakingtypes.DefaultParams()
// check that the empty keeper loads the default
resParams := keeper.GetParams(ctx)
require.Equal(expParams, resParams)
expParams.MaxValidators = 555
expParams.MaxEntries = 111
keeper.SetParams(ctx, expParams)
resParams := keeper.GetParams(ctx)
resParams = keeper.GetParams(ctx)
require.True(expParams.Equal(resParams))
}