refactor: staking module using mocks (#12827)

## Description

Closes: #12504 


---

### Author Checklist

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

I have...

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

### Reviewers Checklist

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

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
This commit is contained in:
cool-developer
2022-08-28 14:02:29 +00:00
committed by GitHub
parent d11196aad0
commit bc274d8d95
24 changed files with 4307 additions and 3300 deletions
-771
View File
@@ -1,771 +0,0 @@
package testutil
import (
"fmt"
"cosmossdk.io/math"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/rest"
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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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 := rest.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 *IntegrationTestSuite) 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
-48
View File
@@ -1,48 +0,0 @@
package testutil
import (
"fmt"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingcli "github.com/cosmos/cosmos-sdk/x/staking/client/cli"
)
var commonArgs = []string{
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()),
}
// MsgRedelegateExec creates a redelegate message.
func MsgRedelegateExec(clientCtx client.Context, from, src, dst, amount fmt.Stringer, extraArgs ...string) (testutil.BufferWriter, error) {
args := []string{
src.String(),
dst.String(),
amount.String(),
fmt.Sprintf("--%s=%s", flags.FlagFrom, from.String()),
fmt.Sprintf("--%s=%d", flags.FlagGas, 300000),
}
args = append(args, extraArgs...)
args = append(args, commonArgs...)
return clitestutil.ExecTestCLICmd(clientCtx, stakingcli.NewRedelegateCmd(), args)
}
// MsgUnbondExec creates a unbond message.
func MsgUnbondExec(clientCtx client.Context, from fmt.Stringer, valAddress,
amount fmt.Stringer, extraArgs ...string,
) (testutil.BufferWriter, error) {
args := []string{
valAddress.String(),
amount.String(),
fmt.Sprintf("--%s=%s", flags.FlagFrom, from.String()),
}
args = append(args, commonArgs...)
args = append(args, extraArgs...)
return clitestutil.ExecTestCLICmd(clientCtx, stakingcli.NewUnbondCmd(), args)
}
-90
View File
@@ -1,90 +0,0 @@
package keeper_test
import (
"math/big"
"testing"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
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/staking/teststaking"
"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))
}
// 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, tmproto.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
}
// intended to be used with require/assert: require.True(ValEq(...))
func ValEq(t *testing.T, exp, got types.Validator) (*testing.T, bool, string, types.Validator, types.Validator) {
return t, exp.MinEqual(&got), "expected:\n%v\ngot:\n%v", exp, got
}
// generateAddresses generates numAddrs of normal AccAddrs and ValAddrs
func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int) ([]sdk.AccAddress, []sdk.ValAddress) {
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 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 := simapp.AddTestAddrsIncremental(app, ctx, 5, app.StakingKeeper.TokensFromConsensusPower(ctx, 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 := teststaking.NewValidator(t, valAddrs[0], pks[0])
val2 := teststaking.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)
_, err := app.StakingKeeper.Delegate(ctx, addrs[0], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[0]), types.Unbonded, val1, true)
require.NoError(t, err)
_, err = app.StakingKeeper.Delegate(ctx, addrs[1], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[1]), types.Unbonded, val2, true)
require.NoError(t, err)
_, err = app.StakingKeeper.Delegate(ctx, addrs[0], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[2]), types.Unbonded, val2, true)
require.NoError(t, err)
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
return addrs, valAddrs, vals
}
File diff suppressed because it is too large Load Diff
-220
View File
@@ -1,220 +0,0 @@
package keeper_test
import (
"fmt"
"testing"
"cosmossdk.io/math"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"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, tmproto.Header{})
addrDels, _ := generateAddresses(app, ctx, numAddrs)
return app, ctx, addrDels
}
func TestInitGenesis(t *testing.T) {
app, ctx, addrs := bootstrapGenesisTest(t, 10)
valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 1)
params := app.StakingKeeper.GetParams(ctx)
validators := app.StakingKeeper.GetAllValidators(ctx)
require.Len(t, validators, 1)
var delegations []types.Delegation
pk0, err := codectypes.NewAnyWithValue(PKs[0])
require.NoError(t, err)
pk1, err := codectypes.NewAnyWithValue(PKs[1])
require.NoError(t, err)
// initialize the validators
bondedVal1 := types.Validator{
OperatorAddress: sdk.ValAddress(addrs[0]).String(),
ConsensusPubkey: pk0,
Status: types.Bonded,
Tokens: valTokens,
DelegatorShares: sdk.NewDecFromInt(valTokens),
Description: types.NewDescription("hoop", "", "", "", ""),
}
bondedVal2 := types.Validator{
OperatorAddress: sdk.ValAddress(addrs[1]).String(),
ConsensusPubkey: pk1,
Status: types.Bonded,
Tokens: valTokens,
DelegatorShares: sdk.NewDecFromInt(valTokens),
Description: types.NewDescription("bloop", "", "", "", ""),
}
// append new bonded validators to the list
validators = append(validators, bondedVal1, bondedVal2)
// mint coins in the bonded pool representing the validators coins
i2 := len(validators) - 1 // -1 to exclude genesis validator
require.NoError(t,
testutil.FundModuleAccount(
app.BankKeeper,
ctx,
types.BondedPoolName,
sdk.NewCoins(
sdk.NewCoin(params.BondDenom, valTokens.MulRaw((int64)(i2))),
),
),
)
genesisDelegations := app.StakingKeeper.GetAllDelegations(ctx)
delegations = append(delegations, genesisDelegations...)
genesisState := types.NewGenesisState(params, validators, delegations)
vals := app.StakingKeeper.InitGenesis(ctx, genesisState)
actualGenesis := app.StakingKeeper.ExportGenesis(ctx)
require.Equal(t, genesisState.Params, actualGenesis.Params)
require.Equal(t, genesisState.Delegations, actualGenesis.Delegations)
require.EqualValues(t, app.StakingKeeper.GetAllValidators(ctx), actualGenesis.Validators)
// Ensure validators have addresses.
vals2, err := staking.WriteValidators(ctx, app.StakingKeeper)
require.NoError(t, err)
for _, val := range vals2 {
require.NotEmpty(t, val.Address)
}
// now make sure the validators are bonded and intra-tx counters are correct
resVal, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[0]))
require.True(t, found)
require.Equal(t, types.Bonded, resVal.Status)
resVal, found = app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[1]))
require.True(t, found)
require.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))
}
require.Equal(t, abcivals, vals)
}
func TestInitGenesis_PoolsBalanceMismatch(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.NewContext(false, tmproto.Header{})
consPub, err := codectypes.NewAnyWithValue(PKs[0])
require.NoError(t, err)
validator := types.Validator{
OperatorAddress: sdk.ValAddress("12345678901234567890").String(),
ConsensusPubkey: consPub,
Jailed: false,
Tokens: sdk.NewInt(10),
DelegatorShares: sdk.NewDecFromInt(sdk.NewInt(10)),
Description: types.NewDescription("bloop", "", "", "", ""),
}
params := types.Params{
UnbondingTime: 10000,
MaxValidators: 1,
MaxEntries: 10,
BondDenom: "stake",
}
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{
Params: params,
Validators: []types.Validator{validator},
})
},
"should panic because bonded pool balance is different from bonded pool coins",
)
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{
Params: params,
Validators: []types.Validator{validator},
})
},
"should panic because not bonded pool balance is different from not bonded pool coins",
)
}
func TestInitGenesisLargeValidatorSet(t *testing.T) {
size := 200
require.True(t, size > 100)
app, ctx, addrs := bootstrapGenesisTest(t, 200)
genesisValidators := app.StakingKeeper.GetAllValidators(ctx)
params := app.StakingKeeper.GetParams(ctx)
delegations := []types.Delegation{}
validators := make([]types.Validator, size)
var err error
bondedPoolAmt := math.ZeroInt()
for i := range validators {
validators[i], err = types.NewValidator(
sdk.ValAddress(addrs[i]),
PKs[i],
types.NewDescription(fmt.Sprintf("#%d", i), "", "", "", ""),
)
require.NoError(t, err)
validators[i].Status = types.Bonded
tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 1)
if i < 100 {
tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
}
validators[i].Tokens = tokens
validators[i].DelegatorShares = sdk.NewDecFromInt(tokens)
// add bonded coins
bondedPoolAmt = bondedPoolAmt.Add(tokens)
}
validators = append(validators, genesisValidators...)
genesisState := types.NewGenesisState(params, validators, delegations)
// mint coins in the bonded pool representing the validators coins
require.NoError(t,
testutil.FundModuleAccount(
app.BankKeeper,
ctx,
types.BondedPoolName,
sdk.NewCoins(sdk.NewCoin(params.BondDenom, bondedPoolAmt)),
),
)
vals := app.StakingKeeper.InitGenesis(ctx, genesisState)
abcivals := make([]abci.ValidatorUpdate, 100)
for i, val := range validators[:100] {
abcivals[i] = val.ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx))
}
// remove genesis validator
vals = vals[:100]
require.Equal(t, abcivals, vals)
}
+12 -740
View File
@@ -4,89 +4,17 @@ import (
gocontext "context"
"fmt"
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/teststaking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func (suite *KeeperTestSuite) TestGRPCQueryValidators() {
queryClient, vals := suite.queryClient, suite.vals
var req *types.QueryValidatorsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
numVals int
hasNext bool
}{
{
"empty request",
func() {
req = &types.QueryValidatorsRequest{}
},
true,
func (s *KeeperTestSuite) TestGRPCQueryValidator() {
ctx, keeper, queryClient := s.ctx, s.stakingKeeper, s.queryClient
require := s.Require()
len(vals) + 1, // +1 validator from genesis state
false,
},
{
"empty status returns all the validators",
func() {
req = &types.QueryValidatorsRequest{Status: ""}
},
true,
len(vals) + 1, // +1 validator from genesis state
false,
},
{
"invalid request",
func() {
req = &types.QueryValidatorsRequest{Status: "test"}
},
false,
0,
false,
},
{
"valid request",
func() {
req = &types.QueryValidatorsRequest{
Status: types.Bonded.String(),
Pagination: &query.PageRequest{Limit: 1, CountTotal: true},
}
},
true,
1,
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
valsResp, err := queryClient.Validators(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.NotNil(valsResp)
suite.Equal(tc.numVals, len(valsResp.Validators))
suite.Equal(uint64(len(vals))+1, valsResp.Pagination.Total) // +1 validator from genesis state
if tc.hasNext {
suite.NotNil(valsResp.Pagination.NextKey)
} else {
suite.Nil(valsResp.Pagination.NextKey)
}
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryValidator() {
app, ctx, queryClient, vals := suite.app, suite.ctx, suite.queryClient, suite.vals
validator, found := app.StakingKeeper.GetValidator(ctx, vals[0].GetOperator())
suite.True(found)
validator := teststaking.NewValidator(s.T(), sdk.ValAddress(PKs[0].Address().Bytes()), PKs[0])
keeper.SetValidator(ctx, validator)
var req *types.QueryValidatorRequest
testCases := []struct {
msg string
@@ -103,678 +31,22 @@ func (suite *KeeperTestSuite) TestGRPCQueryValidator() {
{
"valid request",
func() {
req = &types.QueryValidatorRequest{ValidatorAddr: vals[0].OperatorAddress}
req = &types.QueryValidatorRequest{ValidatorAddr: validator.OperatorAddress}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
s.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.Validator(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.True(validator.Equal(&res.Validator))
require.NoError(err)
require.True(validator.Equal(&res.Validator))
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryDelegatorValidators() {
app, ctx, queryClient, addrs := suite.app, suite.ctx, suite.queryClient, suite.addrs
params := app.StakingKeeper.GetParams(ctx)
delValidators := app.StakingKeeper.GetDelegatorValidators(ctx, addrs[0], params.MaxValidators)
var req *types.QueryDelegatorValidatorsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &types.QueryDelegatorValidatorsRequest{}
},
false,
},
{
"valid request",
func() {
req = &types.QueryDelegatorValidatorsRequest{
DelegatorAddr: addrs[0].String(),
Pagination: &query.PageRequest{Limit: 1, CountTotal: true},
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.DelegatorValidators(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.Equal(1, len(res.Validators))
suite.NotNil(res.Pagination.NextKey)
suite.Equal(uint64(len(delValidators)), res.Pagination.Total)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryDelegatorValidator() {
queryClient, addrs, vals := suite.queryClient, suite.addrs, suite.vals
addr := addrs[1]
addrVal, addrVal1 := vals[0].OperatorAddress, vals[1].OperatorAddress
var req *types.QueryDelegatorValidatorRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &types.QueryDelegatorValidatorRequest{}
},
false,
},
{
"invalid delegator, validator pair",
func() {
req = &types.QueryDelegatorValidatorRequest{
DelegatorAddr: addr.String(),
ValidatorAddr: addrVal,
}
},
false,
},
{
"valid request",
func() {
req = &types.QueryDelegatorValidatorRequest{
DelegatorAddr: addr.String(),
ValidatorAddr: addrVal1,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.DelegatorValidator(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.Equal(addrVal1, res.Validator.OperatorAddress)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryDelegation() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc, addrAcc1 := addrs[0], addrs[1]
addrVal := vals[0].OperatorAddress
valAddr, err := sdk.ValAddressFromBech32(addrVal)
suite.NoError(err)
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
suite.True(found)
var req *types.QueryDelegationRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &types.QueryDelegationRequest{}
},
false,
},
{
"invalid validator, delegator pair",
func() {
req = &types.QueryDelegationRequest{
DelegatorAddr: addrAcc1.String(),
ValidatorAddr: addrVal,
}
},
false,
},
{
"valid request",
func() {
req = &types.QueryDelegationRequest{DelegatorAddr: addrAcc.String(), ValidatorAddr: addrVal}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.Delegation(gocontext.Background(), req)
if tc.expPass {
suite.Equal(delegation.ValidatorAddress, res.DelegationResponse.Delegation.ValidatorAddress)
suite.Equal(delegation.DelegatorAddress, res.DelegationResponse.Delegation.DelegatorAddress)
suite.Equal(sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), res.DelegationResponse.Balance)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryDelegatorDelegations() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc := addrs[0]
addrVal1 := vals[0].OperatorAddress
valAddr, err := sdk.ValAddressFromBech32(addrVal1)
suite.NoError(err)
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
suite.True(found)
var req *types.QueryDelegatorDelegationsRequest
testCases := []struct {
msg string
malleate func()
onSuccess func(suite *KeeperTestSuite, response *types.QueryDelegatorDelegationsResponse)
expErr bool
}{
{
"empty request",
func() {
req = &types.QueryDelegatorDelegationsRequest{}
},
func(suite *KeeperTestSuite, response *types.QueryDelegatorDelegationsResponse) {},
true,
},
{
"valid request with no delegations",
func() {
req = &types.QueryDelegatorDelegationsRequest{DelegatorAddr: addrs[4].String()}
},
func(suite *KeeperTestSuite, response *types.QueryDelegatorDelegationsResponse) {
suite.Equal(uint64(0), response.Pagination.Total)
suite.Len(response.DelegationResponses, 0)
},
false,
},
{
"valid request",
func() {
req = &types.QueryDelegatorDelegationsRequest{
DelegatorAddr: addrAcc.String(),
Pagination: &query.PageRequest{Limit: 1, CountTotal: true},
}
},
func(suite *KeeperTestSuite, response *types.QueryDelegatorDelegationsResponse) {
suite.Equal(uint64(2), response.Pagination.Total)
suite.Len(response.DelegationResponses, 1)
suite.Equal(sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), response.DelegationResponses[0].Balance)
},
false,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.DelegatorDelegations(gocontext.Background(), req)
if tc.expErr {
suite.Error(err)
} else {
suite.NoError(err)
tc.onSuccess(suite, res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryValidatorDelegations() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc := addrs[0]
addrVal1 := vals[1].OperatorAddress
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs)
addrVal2 := valAddrs[4]
valAddr, err := sdk.ValAddressFromBech32(addrVal1)
suite.NoError(err)
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
suite.True(found)
var req *types.QueryValidatorDelegationsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
expErr bool
}{
{
"empty request",
func() {
req = &types.QueryValidatorDelegationsRequest{}
},
false,
true,
},
{
"invalid validator delegator pair",
func() {
req = &types.QueryValidatorDelegationsRequest{ValidatorAddr: addrVal2.String()}
},
false,
false,
},
{
"valid request",
func() {
req = &types.QueryValidatorDelegationsRequest{
ValidatorAddr: addrVal1,
Pagination: &query.PageRequest{Limit: 1, CountTotal: true},
}
},
true,
false,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.ValidatorDelegations(gocontext.Background(), req)
if tc.expPass && !tc.expErr {
suite.NoError(err)
suite.Len(res.DelegationResponses, 1)
suite.NotNil(res.Pagination.NextKey)
suite.Equal(uint64(2), res.Pagination.Total)
suite.Equal(addrVal1, res.DelegationResponses[0].Delegation.ValidatorAddress)
suite.Equal(sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), res.DelegationResponses[0].Balance)
} else if !tc.expPass && !tc.expErr {
suite.NoError(err)
suite.Nil(res.DelegationResponses)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryUnbondingDelegation() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc2 := addrs[1]
addrVal2 := vals[1].OperatorAddress
unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
valAddr, err1 := sdk.ValAddressFromBech32(addrVal2)
suite.NoError(err1)
_, err := app.StakingKeeper.Undelegate(ctx, addrAcc2, valAddr, sdk.NewDecFromInt(unbondingTokens))
suite.NoError(err)
unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, valAddr)
suite.True(found)
var req *types.QueryUnbondingDelegationRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &types.QueryUnbondingDelegationRequest{}
},
false,
},
{
"invalid request",
func() {
req = &types.QueryUnbondingDelegationRequest{}
},
false,
},
{
"valid request",
func() {
req = &types.QueryUnbondingDelegationRequest{
DelegatorAddr: addrAcc2.String(), ValidatorAddr: addrVal2,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.UnbondingDelegation(gocontext.Background(), req)
if tc.expPass {
suite.NotNil(res)
suite.Equal(unbond, res.Unbond)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryDelegatorUnbondingDelegations() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc, addrAcc1 := addrs[0], addrs[1]
addrVal, addrVal2 := vals[0].OperatorAddress, vals[1].OperatorAddress
unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
valAddr1, err1 := sdk.ValAddressFromBech32(addrVal)
suite.NoError(err1)
_, err := app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr1, sdk.NewDecFromInt(unbondingTokens))
suite.NoError(err)
valAddr2, err1 := sdk.ValAddressFromBech32(addrVal2)
suite.NoError(err1)
_, err = app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr2, sdk.NewDecFromInt(unbondingTokens))
suite.NoError(err)
unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc, valAddr1)
suite.True(found)
var req *types.QueryDelegatorUnbondingDelegationsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
expErr bool
}{
{
"empty request",
func() {
req = &types.QueryDelegatorUnbondingDelegationsRequest{}
},
false,
true,
},
{
"invalid request",
func() {
req = &types.QueryDelegatorUnbondingDelegationsRequest{DelegatorAddr: addrAcc1.String()}
},
false,
false,
},
{
"valid request",
func() {
req = &types.QueryDelegatorUnbondingDelegationsRequest{
DelegatorAddr: addrAcc.String(),
Pagination: &query.PageRequest{Limit: 1, CountTotal: true},
}
},
true,
false,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.DelegatorUnbondingDelegations(gocontext.Background(), req)
if tc.expPass && !tc.expErr {
suite.NoError(err)
suite.NotNil(res.Pagination.NextKey)
suite.Equal(uint64(2), res.Pagination.Total)
suite.Len(res.UnbondingResponses, 1)
suite.Equal(unbond, res.UnbondingResponses[0])
} else if !tc.expPass && !tc.expErr {
suite.NoError(err)
suite.Nil(res.UnbondingResponses)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryPoolParameters() {
app, ctx, queryClient := suite.app, suite.ctx, suite.queryClient
bondDenom := sdk.DefaultBondDenom
// Query pool
res, err := queryClient.Pool(gocontext.Background(), &types.QueryPoolRequest{})
suite.NoError(err)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
suite.Equal(app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, res.Pool.NotBondedTokens)
suite.Equal(app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, res.Pool.BondedTokens)
// Query Params
resp, err := queryClient.Params(gocontext.Background(), &types.QueryParamsRequest{})
suite.NoError(err)
suite.Equal(app.StakingKeeper.GetParams(ctx), resp.Params)
}
func (suite *KeeperTestSuite) TestGRPCQueryHistoricalInfo() {
app, ctx, queryClient := suite.app, suite.ctx, suite.queryClient
hi, found := app.StakingKeeper.GetHistoricalInfo(ctx, 5)
suite.True(found)
var req *types.QueryHistoricalInfoRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &types.QueryHistoricalInfoRequest{}
},
false,
},
{
"invalid request with negative height",
func() {
req = &types.QueryHistoricalInfoRequest{Height: -1}
},
false,
},
{
"valid request with old height",
func() {
req = &types.QueryHistoricalInfoRequest{Height: 4}
},
false,
},
{
"valid request with current height",
func() {
req = &types.QueryHistoricalInfoRequest{Height: 5}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.HistoricalInfo(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.NotNil(res)
suite.True(hi.Equal(res.Hist))
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryRedelegations() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
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)
suite.NoError(err)
applyValidatorSetUpdates(suite.T(), ctx, app.StakingKeeper, -1)
rdAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 1)
_, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator(), sdk.NewDecFromInt(rdAmount))
suite.NoError(err)
applyValidatorSetUpdates(suite.T(), ctx, app.StakingKeeper, -1)
redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator())
suite.True(found)
var req *types.QueryRedelegationsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
expErr bool
}{
{
"request redelegations for non existent addr",
func() {
req = &types.QueryRedelegationsRequest{DelegatorAddr: addrAcc.String()}
},
false,
false,
},
{
"request redelegations with non existent pairs",
func() {
req = &types.QueryRedelegationsRequest{
DelegatorAddr: addrAcc.String(), SrcValidatorAddr: val3.String(),
DstValidatorAddr: val4.String(),
}
},
false,
true,
},
{
"request redelegations with delegatoraddr, sourceValAddr, destValAddr",
func() {
req = &types.QueryRedelegationsRequest{
DelegatorAddr: addrAcc1.String(), SrcValidatorAddr: val1.OperatorAddress,
DstValidatorAddr: val2.OperatorAddress, Pagination: &query.PageRequest{},
}
},
true,
false,
},
{
"request redelegations with delegatoraddr and sourceValAddr",
func() {
req = &types.QueryRedelegationsRequest{
DelegatorAddr: addrAcc1.String(), SrcValidatorAddr: val1.OperatorAddress,
Pagination: &query.PageRequest{},
}
},
true,
false,
},
{
"query redelegations with sourceValAddr only",
func() {
req = &types.QueryRedelegationsRequest{
SrcValidatorAddr: val1.GetOperator().String(),
Pagination: &query.PageRequest{Limit: 1, CountTotal: true},
}
},
true,
false,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.Redelegations(gocontext.Background(), req)
if tc.expPass && !tc.expErr {
suite.NoError(err)
suite.Len(res.RedelegationResponses, len(redel.Entries))
suite.Equal(redel.DelegatorAddress, res.RedelegationResponses[0].Redelegation.DelegatorAddress)
suite.Equal(redel.ValidatorSrcAddress, res.RedelegationResponses[0].Redelegation.ValidatorSrcAddress)
suite.Equal(redel.ValidatorDstAddress, res.RedelegationResponses[0].Redelegation.ValidatorDstAddress)
suite.Len(redel.Entries, len(res.RedelegationResponses[0].Entries))
} else if !tc.expPass && !tc.expErr {
suite.NoError(err)
suite.Nil(res.RedelegationResponses)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryValidatorUnbondingDelegations() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
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))
suite.NoError(err)
applyValidatorSetUpdates(suite.T(), ctx, app.StakingKeeper, -1)
var req *types.QueryValidatorUnbondingDelegationsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &types.QueryValidatorUnbondingDelegationsRequest{}
},
false,
},
{
"valid request",
func() {
req = &types.QueryValidatorUnbondingDelegationsRequest{
ValidatorAddr: val1.GetOperator().String(),
Pagination: &query.PageRequest{Limit: 1, CountTotal: true},
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.ValidatorUnbondingDelegations(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.Equal(uint64(1), res.Pagination.Total)
suite.Equal(1, len(res.UnbondingResponses))
suite.Equal(res.UnbondingResponses[0].ValidatorAddress, val1.OperatorAddress)
} else {
suite.Error(err)
suite.Nil(res)
require.Error(err)
require.Nil(res)
}
})
}
+75 -89
View File
@@ -1,67 +1,61 @@
package keeper_test
import (
"testing"
"cosmossdk.io/math"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/simapp"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/teststaking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
// IsValSetSorted reports whether valset is sorted.
func IsValSetSorted(data []types.Validator, powerReduction math.Int) bool {
func IsValSetSorted(data []stakingtypes.Validator, powerReduction math.Int) bool {
n := len(data)
for i := n - 1; i > 0; i-- {
if types.ValidatorsByVotingPower(data).Less(i, i-1, powerReduction) {
if stakingtypes.ValidatorsByVotingPower(data).Less(i, i-1, powerReduction) {
return false
}
}
return true
}
func TestHistoricalInfo(t *testing.T) {
_, app, ctx := createTestInput(t)
func (s *KeeperTestSuite) TestHistoricalInfo() {
ctx, keeper := s.ctx, s.stakingKeeper
require := s.Require()
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0))
addrVals := simtestutil.ConvertAddrsToValAddrs(addrDels)
_, addrVals := createValAddrs(50)
validators := make([]types.Validator, len(addrVals))
validators := make([]stakingtypes.Validator, len(addrVals))
for i, valAddr := range addrVals {
validators[i] = teststaking.NewValidator(t, valAddr, PKs[i])
validators[i] = teststaking.NewValidator(s.T(), valAddr, PKs[i])
}
hi := types.NewHistoricalInfo(ctx.BlockHeader(), validators, app.StakingKeeper.PowerReduction(ctx))
app.StakingKeeper.SetHistoricalInfo(ctx, 2, &hi)
hi := stakingtypes.NewHistoricalInfo(ctx.BlockHeader(), validators, keeper.PowerReduction(ctx))
keeper.SetHistoricalInfo(ctx, 2, &hi)
recv, found := app.StakingKeeper.GetHistoricalInfo(ctx, 2)
require.True(t, found, "HistoricalInfo not found after set")
require.Equal(t, hi, recv, "HistoricalInfo not equal")
require.True(t, IsValSetSorted(recv.Valset, app.StakingKeeper.PowerReduction(ctx)), "HistoricalInfo validators is not sorted")
recv, found := keeper.GetHistoricalInfo(ctx, 2)
require.True(found, "HistoricalInfo not found after set")
require.Equal(hi, recv, "HistoricalInfo not equal")
require.True(IsValSetSorted(recv.Valset, keeper.PowerReduction(ctx)), "HistoricalInfo validators is not sorted")
app.StakingKeeper.DeleteHistoricalInfo(ctx, 2)
keeper.DeleteHistoricalInfo(ctx, 2)
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 2)
require.False(t, found, "HistoricalInfo found after delete")
require.Equal(t, types.HistoricalInfo{}, recv, "HistoricalInfo is not empty")
recv, found = keeper.GetHistoricalInfo(ctx, 2)
require.False(found, "HistoricalInfo found after delete")
require.Equal(stakingtypes.HistoricalInfo{}, recv, "HistoricalInfo is not empty")
}
func TestTrackHistoricalInfo(t *testing.T) {
_, app, ctx := createTestInput(t)
func (s *KeeperTestSuite) TestTrackHistoricalInfo() {
ctx, keeper := s.ctx, s.stakingKeeper
require := s.Require()
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0))
addrVals := simtestutil.ConvertAddrsToValAddrs(addrDels)
_, addrVals := createValAddrs(50)
// set historical entries in params to 5
params := types.DefaultParams()
params := stakingtypes.DefaultParams()
params.HistoricalEntries = 5
app.StakingKeeper.SetParams(ctx, params)
keeper.SetParams(ctx, params)
// set historical info at 5, 4 which should be pruned
// and check that it has been stored
@@ -73,39 +67,35 @@ func TestTrackHistoricalInfo(t *testing.T) {
ChainID: "HelloChain",
Height: 5,
}
valSet := []types.Validator{
teststaking.NewValidator(t, addrVals[0], PKs[0]),
teststaking.NewValidator(t, addrVals[1], PKs[1]),
valSet := []stakingtypes.Validator{
teststaking.NewValidator(s.T(), addrVals[0], PKs[0]),
teststaking.NewValidator(s.T(), addrVals[1], PKs[1]),
}
hi4 := types.NewHistoricalInfo(h4, valSet, app.StakingKeeper.PowerReduction(ctx))
hi5 := types.NewHistoricalInfo(h5, valSet, app.StakingKeeper.PowerReduction(ctx))
app.StakingKeeper.SetHistoricalInfo(ctx, 4, &hi4)
app.StakingKeeper.SetHistoricalInfo(ctx, 5, &hi5)
recv, found := app.StakingKeeper.GetHistoricalInfo(ctx, 4)
require.True(t, found)
require.Equal(t, hi4, recv)
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 5)
require.True(t, found)
require.Equal(t, hi5, recv)
// genesis validator
genesisVals := app.StakingKeeper.GetAllValidators(ctx)
require.Len(t, genesisVals, 1)
hi4 := stakingtypes.NewHistoricalInfo(h4, valSet, keeper.PowerReduction(ctx))
hi5 := stakingtypes.NewHistoricalInfo(h5, valSet, keeper.PowerReduction(ctx))
keeper.SetHistoricalInfo(ctx, 4, &hi4)
keeper.SetHistoricalInfo(ctx, 5, &hi5)
recv, found := keeper.GetHistoricalInfo(ctx, 4)
require.True(found)
require.Equal(hi4, recv)
recv, found = keeper.GetHistoricalInfo(ctx, 5)
require.True(found)
require.Equal(hi5, recv)
// Set bonded validators in keeper
val1 := teststaking.NewValidator(t, addrVals[2], PKs[2])
val1.Status = types.Bonded // when not bonded, consensus power is Zero
val1.Tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetLastValidatorPower(ctx, val1.GetOperator(), 10)
val2 := teststaking.NewValidator(t, addrVals[3], PKs[3])
val1.Status = types.Bonded
val2.Tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 80)
app.StakingKeeper.SetValidator(ctx, val2)
app.StakingKeeper.SetLastValidatorPower(ctx, val2.GetOperator(), 80)
val1 := teststaking.NewValidator(s.T(), addrVals[2], PKs[2])
val1.Status = stakingtypes.Bonded // when not bonded, consensus power is Zero
val1.Tokens = keeper.TokensFromConsensusPower(ctx, 10)
keeper.SetValidator(ctx, val1)
keeper.SetLastValidatorPower(ctx, val1.GetOperator(), 10)
val2 := teststaking.NewValidator(s.T(), addrVals[3], PKs[3])
val1.Status = stakingtypes.Bonded
val2.Tokens = keeper.TokensFromConsensusPower(ctx, 80)
keeper.SetValidator(ctx, val2)
keeper.SetLastValidatorPower(ctx, val2.GetOperator(), 80)
vals := []types.Validator{val1, genesisVals[0], val2}
require.True(t, IsValSetSorted(vals, app.StakingKeeper.PowerReduction(ctx)))
vals := []stakingtypes.Validator{val1, val2}
require.True(IsValSetSorted(vals, keeper.PowerReduction(ctx)))
// Set Header for BeginBlock context
header := tmproto.Header{
@@ -114,55 +104,51 @@ func TestTrackHistoricalInfo(t *testing.T) {
}
ctx = ctx.WithBlockHeader(header)
app.StakingKeeper.TrackHistoricalInfo(ctx)
keeper.TrackHistoricalInfo(ctx)
// Check HistoricalInfo at height 10 is persisted
expected := types.HistoricalInfo{
expected := stakingtypes.HistoricalInfo{
Header: header,
Valset: vals,
}
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 10)
require.True(t, found, "GetHistoricalInfo failed after BeginBlock")
require.Equal(t, expected, recv, "GetHistoricalInfo returned unexpected result")
recv, found = keeper.GetHistoricalInfo(ctx, 10)
require.True(found, "GetHistoricalInfo failed after BeginBlock")
require.Equal(expected, recv, "GetHistoricalInfo returned unexpected result")
// Check HistoricalInfo at height 5, 4 is pruned
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 4)
require.False(t, found, "GetHistoricalInfo did not prune earlier height")
require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 4 is not empty after prune")
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 5)
require.False(t, found, "GetHistoricalInfo did not prune first prune height")
require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune")
recv, found = keeper.GetHistoricalInfo(ctx, 4)
require.False(found, "GetHistoricalInfo did not prune earlier height")
require.Equal(stakingtypes.HistoricalInfo{}, recv, "GetHistoricalInfo at height 4 is not empty after prune")
recv, found = keeper.GetHistoricalInfo(ctx, 5)
require.False(found, "GetHistoricalInfo did not prune first prune height")
require.Equal(stakingtypes.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune")
}
func TestGetAllHistoricalInfo(t *testing.T) {
_, app, ctx := createTestInput(t)
// clear historical info
infos := app.StakingKeeper.GetAllHistoricalInfo(ctx)
require.Len(t, infos, 1)
app.StakingKeeper.DeleteHistoricalInfo(ctx, infos[0].Header.Height)
func (s *KeeperTestSuite) TestGetAllHistoricalInfo() {
ctx, keeper := s.ctx, s.stakingKeeper
require := s.Require()
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0))
addrVals := simtestutil.ConvertAddrsToValAddrs(addrDels)
_, addrVals := createValAddrs(50)
valSet := []types.Validator{
teststaking.NewValidator(t, addrVals[0], PKs[0]),
teststaking.NewValidator(t, addrVals[1], PKs[1]),
valSet := []stakingtypes.Validator{
teststaking.NewValidator(s.T(), addrVals[0], PKs[0]),
teststaking.NewValidator(s.T(), addrVals[1], PKs[1]),
}
header1 := tmproto.Header{ChainID: "HelloChain", Height: 10}
header2 := tmproto.Header{ChainID: "HelloChain", Height: 11}
header3 := tmproto.Header{ChainID: "HelloChain", Height: 12}
hist1 := types.HistoricalInfo{Header: header1, Valset: valSet}
hist2 := types.HistoricalInfo{Header: header2, Valset: valSet}
hist3 := types.HistoricalInfo{Header: header3, Valset: valSet}
hist1 := stakingtypes.HistoricalInfo{Header: header1, Valset: valSet}
hist2 := stakingtypes.HistoricalInfo{Header: header2, Valset: valSet}
hist3 := stakingtypes.HistoricalInfo{Header: header3, Valset: valSet}
expHistInfos := []types.HistoricalInfo{hist1, hist2, hist3}
expHistInfos := []stakingtypes.HistoricalInfo{hist1, hist2, hist3}
for i, hi := range expHistInfos {
app.StakingKeeper.SetHistoricalInfo(ctx, int64(10+i), &hi)
keeper.SetHistoricalInfo(ctx, int64(10+i), &hi)
}
infos = app.StakingKeeper.GetAllHistoricalInfo(ctx)
require.Equal(t, expHistInfos, infos)
infos := keeper.GetAllHistoricalInfo(ctx)
require.Equal(expHistInfos, infos)
}
+71 -48
View File
@@ -3,72 +3,95 @@ package keeper_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/suite"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
stakingtestutil "github.com/cosmos/cosmos-sdk/x/staking/testutil"
)
var (
bondedAcc = authtypes.NewEmptyModuleAccount(stakingtypes.BondedPoolName)
notBondedAcc = authtypes.NewEmptyModuleAccount(stakingtypes.NotBondedPoolName)
PKs = simtestutil.CreateTestPubKeys(500)
)
type KeeperTestSuite struct {
suite.Suite
app *simapp.SimApp
ctx sdk.Context
addrs []sdk.AccAddress
vals []types.Validator
queryClient types.QueryClient
msgServer types.MsgServer
ctx sdk.Context
stakingKeeper *stakingkeeper.Keeper
bankKeeper *stakingtestutil.MockBankKeeper
accountKeeper *stakingtestutil.MockAccountKeeper
queryClient stakingtypes.QueryClient
msgServer stakingtypes.MsgServer
}
func (suite *KeeperTestSuite) SetupTest() {
app := simapp.Setup(suite.T(), false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
func (s *KeeperTestSuite) SetupTest() {
key := sdk.NewKVStoreKey(stakingtypes.StoreKey)
testCtx := testutil.DefaultContextWithDB(s.T(), key, sdk.NewTransientStoreKey("transient_test"))
ctx := testCtx.Ctx.WithBlockHeader(tmproto.Header{Time: tmtime.Now()})
encCfg := moduletestutil.MakeTestEncodingConfig()
querier := keeper.Querier{Keeper: app.StakingKeeper}
ctrl := gomock.NewController(s.T())
accountKeeper := stakingtestutil.NewMockAccountKeeper(ctrl)
accountKeeper.EXPECT().GetModuleAddress(stakingtypes.BondedPoolName).Return(bondedAcc.GetAddress())
accountKeeper.EXPECT().GetModuleAddress(stakingtypes.NotBondedPoolName).Return(notBondedAcc.GetAddress())
bankKeeper := stakingtestutil.NewMockBankKeeper(ctrl)
queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, querier)
queryClient := types.NewQueryClient(queryHelper)
keeper := stakingkeeper.NewKeeper(
encCfg.Codec,
key,
accountKeeper,
bankKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
keeper.SetParams(ctx, stakingtypes.DefaultParams())
suite.msgServer = keeper.NewMsgServerImpl(app.StakingKeeper)
s.ctx = ctx
s.stakingKeeper = keeper
s.bankKeeper = bankKeeper
s.accountKeeper = accountKeeper
addrs, _, validators := createValidators(suite.T(), ctx, app, []int64{9, 8, 7})
header := tmproto.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)
suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals = app, ctx, queryClient, addrs, validators
stakingtypes.RegisterInterfaces(encCfg.InterfaceRegistry)
queryHelper := baseapp.NewQueryServerTestHelper(ctx, encCfg.InterfaceRegistry)
stakingtypes.RegisterQueryServer(queryHelper, stakingkeeper.Querier{Keeper: keeper})
s.queryClient = stakingtypes.NewQueryClient(queryHelper)
s.msgServer = stakingkeeper.NewMsgServerImpl(keeper)
}
func TestParams(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
func (s *KeeperTestSuite) TestParams() {
ctx, keeper := s.ctx, s.stakingKeeper
require := s.Require()
expParams := types.DefaultParams()
expParams := stakingtypes.DefaultParams()
expParams.MaxValidators = 555
expParams.MaxEntries = 111
keeper.SetParams(ctx, expParams)
resParams := keeper.GetParams(ctx)
require.True(expParams.Equal(resParams))
}
// check that the empty keeper loads the default
resParams := app.StakingKeeper.GetParams(ctx)
require.True(t, expParams.Equal(resParams))
func (s *KeeperTestSuite) TestLastTotalPower() {
ctx, keeper := s.ctx, s.stakingKeeper
require := s.Require()
// modify a params, save, and retrieve
expParams.MaxValidators = 777
app.StakingKeeper.SetParams(ctx, expParams)
resParams = app.StakingKeeper.GetParams(ctx)
require.True(t, expParams.Equal(resParams))
expTotalPower := math.NewInt(10 ^ 9)
keeper.SetLastTotalPower(ctx, expTotalPower)
resTotalPower := keeper.GetLastTotalPower(ctx)
require.True(expTotalPower.Equal(resTotalPower))
}
func TestKeeperTestSuite(t *testing.T) {
+54 -194
View File
@@ -2,189 +2,49 @@ package keeper_test
import (
"testing"
"time"
"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank/testutil"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
func TestCancelUnbondingDelegation(t *testing.T) {
// setup the app
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
msgServer := keeper.NewMsgServerImpl(app.StakingKeeper)
bondDenom := app.StakingKeeper.BondDenom(ctx)
// set the not bonded pool module account
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 5)
require.NoError(t, testutil.FundModuleAccount(app.BankKeeper, ctx, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens))))
app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
moduleBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.NewInt64Coin(bondDenom, startTokens.Int64()), moduleBalance)
// accounts
delAddrs := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(10000))
validators := app.StakingKeeper.GetValidators(ctx, 10)
require.Equal(t, len(validators), 1)
validatorAddr, err := sdk.ValAddressFromBech32(validators[0].OperatorAddress)
require.NoError(t, err)
delegatorAddr := delAddrs[0]
// setting the ubd entry
unbondingAmount := sdk.NewInt64Coin(app.StakingKeeper.BondDenom(ctx), 5)
ubd := types.NewUnbondingDelegation(
delegatorAddr, validatorAddr, 10,
ctx.BlockTime().Add(time.Minute*10),
unbondingAmount.Amount,
)
// set and retrieve a record
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
resUnbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr)
require.True(t, found)
require.Equal(t, ubd, resUnbond)
testCases := []struct {
Name string
ExceptErr bool
req types.MsgCancelUnbondingDelegation
}{
{
Name: "invalid height",
ExceptErr: true,
req: types.MsgCancelUnbondingDelegation{
DelegatorAddress: resUnbond.DelegatorAddress,
ValidatorAddress: resUnbond.ValidatorAddress,
Amount: sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(4)),
CreationHeight: 0,
},
},
{
Name: "invalid coin",
ExceptErr: true,
req: types.MsgCancelUnbondingDelegation{
DelegatorAddress: resUnbond.DelegatorAddress,
ValidatorAddress: resUnbond.ValidatorAddress,
Amount: sdk.NewCoin("dump_coin", sdk.NewInt(4)),
CreationHeight: 0,
},
},
{
Name: "validator not exists",
ExceptErr: true,
req: types.MsgCancelUnbondingDelegation{
DelegatorAddress: resUnbond.DelegatorAddress,
ValidatorAddress: sdk.ValAddress(sdk.AccAddress("asdsad")).String(),
Amount: unbondingAmount,
CreationHeight: 0,
},
},
{
Name: "invalid delegator address",
ExceptErr: true,
req: types.MsgCancelUnbondingDelegation{
DelegatorAddress: "invalid_delegator_addrtess",
ValidatorAddress: resUnbond.ValidatorAddress,
Amount: unbondingAmount,
CreationHeight: 0,
},
},
{
Name: "invalid amount",
ExceptErr: true,
req: types.MsgCancelUnbondingDelegation{
DelegatorAddress: resUnbond.DelegatorAddress,
ValidatorAddress: resUnbond.ValidatorAddress,
Amount: unbondingAmount.Add(sdk.NewInt64Coin(bondDenom, 10)),
CreationHeight: 10,
},
},
{
Name: "success",
ExceptErr: false,
req: types.MsgCancelUnbondingDelegation{
DelegatorAddress: resUnbond.DelegatorAddress,
ValidatorAddress: resUnbond.ValidatorAddress,
Amount: unbondingAmount.Sub(sdk.NewInt64Coin(bondDenom, 1)),
CreationHeight: 10,
},
},
{
Name: "success",
ExceptErr: false,
req: types.MsgCancelUnbondingDelegation{
DelegatorAddress: resUnbond.DelegatorAddress,
ValidatorAddress: resUnbond.ValidatorAddress,
Amount: unbondingAmount.Sub(unbondingAmount.Sub(sdk.NewInt64Coin(bondDenom, 1))),
CreationHeight: 10,
},
},
}
for _, testCase := range testCases {
t.Run(testCase.Name, func(t *testing.T) {
_, err := msgServer.CancelUnbondingDelegation(ctx, &testCase.req)
if testCase.ExceptErr {
require.Error(t, err)
} else {
require.NoError(t, err)
balanceForNotBondedPool := app.BankKeeper.GetBalance(ctx, sdk.AccAddress(notBondedPool.GetAddress()), bondDenom)
require.Equal(t, balanceForNotBondedPool, moduleBalance.Sub(testCase.req.Amount))
moduleBalance = moduleBalance.Sub(testCase.req.Amount)
}
})
}
}
func TestMsgUpdateParams(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
msgServer := keeper.NewMsgServerImpl(app.StakingKeeper)
func (s *KeeperTestSuite) TestMsgUpdateParams() {
ctx, keeper, msgServer := s.ctx, s.stakingKeeper, s.msgServer
require := s.Require()
testCases := []struct {
name string
input *types.MsgUpdateParams
input *stakingtypes.MsgUpdateParams
expErr bool
expErrMsg string
}{
{
name: "valid params",
input: &types.MsgUpdateParams{
Authority: app.StakingKeeper.GetAuthority(),
Params: types.DefaultParams(),
input: &stakingtypes.MsgUpdateParams{
Authority: keeper.GetAuthority(),
Params: stakingtypes.DefaultParams(),
},
expErr: false,
},
{
name: "invalid authority",
input: &types.MsgUpdateParams{
input: &stakingtypes.MsgUpdateParams{
Authority: "invalid",
Params: types.DefaultParams(),
Params: stakingtypes.DefaultParams(),
},
expErr: true,
expErrMsg: "invalid authority",
},
{
name: "negative commission rate",
input: &types.MsgUpdateParams{
Authority: app.StakingKeeper.GetAuthority(),
Params: types.Params{
input: &stakingtypes.MsgUpdateParams{
Authority: keeper.GetAuthority(),
Params: stakingtypes.Params{
MinCommissionRate: math.LegacyNewDec(-10),
UnbondingTime: types.DefaultUnbondingTime,
MaxValidators: types.DefaultMaxValidators,
MaxEntries: types.DefaultMaxEntries,
HistoricalEntries: types.DefaultHistoricalEntries,
BondDenom: types.BondStatusBonded,
UnbondingTime: stakingtypes.DefaultUnbondingTime,
MaxValidators: stakingtypes.DefaultMaxValidators,
MaxEntries: stakingtypes.DefaultMaxEntries,
HistoricalEntries: stakingtypes.DefaultHistoricalEntries,
BondDenom: stakingtypes.BondStatusBonded,
},
},
expErr: true,
@@ -192,15 +52,15 @@ func TestMsgUpdateParams(t *testing.T) {
},
{
name: "commission rate cannot be bigger than 100",
input: &types.MsgUpdateParams{
Authority: app.StakingKeeper.GetAuthority(),
Params: types.Params{
input: &stakingtypes.MsgUpdateParams{
Authority: keeper.GetAuthority(),
Params: stakingtypes.Params{
MinCommissionRate: math.LegacyNewDec(2),
UnbondingTime: types.DefaultUnbondingTime,
MaxValidators: types.DefaultMaxValidators,
MaxEntries: types.DefaultMaxEntries,
HistoricalEntries: types.DefaultHistoricalEntries,
BondDenom: types.BondStatusBonded,
UnbondingTime: stakingtypes.DefaultUnbondingTime,
MaxValidators: stakingtypes.DefaultMaxValidators,
MaxEntries: stakingtypes.DefaultMaxEntries,
HistoricalEntries: stakingtypes.DefaultHistoricalEntries,
BondDenom: stakingtypes.BondStatusBonded,
},
},
expErr: true,
@@ -208,14 +68,14 @@ func TestMsgUpdateParams(t *testing.T) {
},
{
name: "invalid bond denom",
input: &types.MsgUpdateParams{
Authority: app.StakingKeeper.GetAuthority(),
Params: types.Params{
MinCommissionRate: types.DefaultMinCommissionRate,
UnbondingTime: types.DefaultUnbondingTime,
MaxValidators: types.DefaultMaxValidators,
MaxEntries: types.DefaultMaxEntries,
HistoricalEntries: types.DefaultHistoricalEntries,
input: &stakingtypes.MsgUpdateParams{
Authority: keeper.GetAuthority(),
Params: stakingtypes.Params{
MinCommissionRate: stakingtypes.DefaultMinCommissionRate,
UnbondingTime: stakingtypes.DefaultUnbondingTime,
MaxValidators: stakingtypes.DefaultMaxValidators,
MaxEntries: stakingtypes.DefaultMaxEntries,
HistoricalEntries: stakingtypes.DefaultHistoricalEntries,
BondDenom: "",
},
},
@@ -224,15 +84,15 @@ func TestMsgUpdateParams(t *testing.T) {
},
{
name: "max validators most be positive",
input: &types.MsgUpdateParams{
Authority: app.StakingKeeper.GetAuthority(),
Params: types.Params{
MinCommissionRate: types.DefaultMinCommissionRate,
UnbondingTime: types.DefaultUnbondingTime,
input: &stakingtypes.MsgUpdateParams{
Authority: keeper.GetAuthority(),
Params: stakingtypes.Params{
MinCommissionRate: stakingtypes.DefaultMinCommissionRate,
UnbondingTime: stakingtypes.DefaultUnbondingTime,
MaxValidators: 0,
MaxEntries: types.DefaultMaxEntries,
HistoricalEntries: types.DefaultHistoricalEntries,
BondDenom: types.BondStatusBonded,
MaxEntries: stakingtypes.DefaultMaxEntries,
HistoricalEntries: stakingtypes.DefaultHistoricalEntries,
BondDenom: stakingtypes.BondStatusBonded,
},
},
expErr: true,
@@ -240,15 +100,15 @@ func TestMsgUpdateParams(t *testing.T) {
},
{
name: "max entries most be positive",
input: &types.MsgUpdateParams{
Authority: app.StakingKeeper.GetAuthority(),
Params: types.Params{
MinCommissionRate: types.DefaultMinCommissionRate,
UnbondingTime: types.DefaultUnbondingTime,
MaxValidators: types.DefaultMaxValidators,
input: &stakingtypes.MsgUpdateParams{
Authority: keeper.GetAuthority(),
Params: stakingtypes.Params{
MinCommissionRate: stakingtypes.DefaultMinCommissionRate,
UnbondingTime: stakingtypes.DefaultUnbondingTime,
MaxValidators: stakingtypes.DefaultMaxValidators,
MaxEntries: 0,
HistoricalEntries: types.DefaultHistoricalEntries,
BondDenom: types.BondStatusBonded,
HistoricalEntries: stakingtypes.DefaultHistoricalEntries,
BondDenom: stakingtypes.BondStatusBonded,
},
},
expErr: true,
@@ -258,13 +118,13 @@ func TestMsgUpdateParams(t *testing.T) {
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
s.T().Run(tc.name, func(t *testing.T) {
_, err := msgServer.UpdateParams(ctx, tc.input)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
require.Error(err)
require.Contains(err.Error(), tc.expErrMsg)
} else {
require.NoError(t, err)
require.NoError(err)
}
})
}
+6 -6
View File
@@ -4,12 +4,12 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
func (suite *KeeperTestSuite) TestTokensToConsensusPower() {
suite.Require().Equal(int64(0), suite.app.StakingKeeper.TokensToConsensusPower(suite.ctx, sdk.DefaultPowerReduction.Sub(sdk.NewInt(1))))
suite.Require().Equal(int64(1), suite.app.StakingKeeper.TokensToConsensusPower(suite.ctx, sdk.DefaultPowerReduction))
func (s *KeeperTestSuite) TestTokensToConsensusPower() {
s.Require().Equal(int64(0), s.stakingKeeper.TokensToConsensusPower(s.ctx, sdk.DefaultPowerReduction.Sub(sdk.NewInt(1))))
s.Require().Equal(int64(1), s.stakingKeeper.TokensToConsensusPower(s.ctx, sdk.DefaultPowerReduction))
}
func (suite *KeeperTestSuite) TestTokensFromConsensusPower() {
suite.Require().Equal(sdk.NewInt(0), suite.app.StakingKeeper.TokensFromConsensusPower(suite.ctx, 0))
suite.Require().Equal(sdk.DefaultPowerReduction, suite.app.StakingKeeper.TokensFromConsensusPower(suite.ctx, 1))
func (s *KeeperTestSuite) TestTokensFromConsensusPower() {
s.Require().Equal(sdk.NewInt(0), s.stakingKeeper.TokensFromConsensusPower(s.ctx, 0))
s.Require().Equal(sdk.DefaultPowerReduction, s.stakingKeeper.TokensFromConsensusPower(s.ctx, 1))
}
+27 -595
View File
@@ -1,618 +1,50 @@
package keeper_test
import (
"testing"
"time"
"cosmossdk.io/math"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank/testutil"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/teststaking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// 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)
addrDels, addrVals := generateAddresses(app, ctx, 100)
amt := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels)))))
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
require.NoError(t, testutil.FundModuleAccount(app.BankKeeper, ctx, notBondedPool.GetName(), totalSupply))
app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
numVals := int64(3)
bondedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(numVals)))
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
// set bonded pool balance
app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
require.NoError(t, testutil.FundModuleAccount(app.BankKeeper, ctx, bondedPool.GetName(), bondedCoins))
for i := int64(0); i < numVals; i++ {
validator := teststaking.NewValidator(t, addrVals[i], PKs[i])
validator, _ = validator.AddTokensFromDel(amt)
validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
}
return app, ctx, addrDels, addrVals
}
// tests Jail, Unjail
func TestRevocation(t *testing.T) {
app, ctx, _, addrVals := bootstrapSlashTest(t, 5)
func (s *KeeperTestSuite) TestRevocation() {
ctx, keeper := s.ctx, s.stakingKeeper
require := s.Require()
valAddr := sdk.ValAddress(PKs[0].Address().Bytes())
consAddr := sdk.ConsAddress(PKs[0].Address())
validator := teststaking.NewValidator(s.T(), valAddr, PKs[0])
// initial state
val, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
require.True(t, found)
require.False(t, val.IsJailed())
keeper.SetValidator(ctx, validator)
keeper.SetValidatorByConsAddr(ctx, validator)
val, found := keeper.GetValidator(ctx, valAddr)
require.True(found)
require.False(val.IsJailed())
// test jail
app.StakingKeeper.Jail(ctx, consAddr)
val, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
require.True(t, found)
require.True(t, val.IsJailed())
keeper.Jail(ctx, consAddr)
val, found = keeper.GetValidator(ctx, valAddr)
require.True(found)
require.True(val.IsJailed())
// test unjail
app.StakingKeeper.Unjail(ctx, consAddr)
val, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
require.True(t, found)
require.False(t, val.IsJailed())
}
// tests slashUnbondingDelegation
func TestSlashUnbondingDelegation(t *testing.T) {
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
fraction := sdk.NewDecWithPrec(5, 1)
// set an unbonding delegation with expiration timestamp (beyond which the
// unbonding delegation shouldn't be slashed)
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0,
time.Unix(5, 0), sdk.NewInt(10))
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
// unbonding started prior to the infraction height, stakw didn't contribute
slashAmount := app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 1, fraction)
require.True(t, slashAmount.Equal(sdk.NewInt(0)))
// after the expiration time, no longer eligible for slashing
ctx = ctx.WithBlockHeader(tmproto.Header{Time: time.Unix(10, 0)})
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction)
require.True(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(tmproto.Header{Time: time.Unix(0, 0)})
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction)
require.True(t, slashAmount.Equal(sdk.NewInt(5)))
ubd, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
require.True(t, found)
require.Len(t, ubd.Entries, 1)
// initial balance unchanged
require.Equal(t, sdk.NewInt(10), ubd.Entries[0].InitialBalance)
// balance decreased
require.Equal(t, sdk.NewInt(5), ubd.Entries[0].Balance)
newUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances...)
require.True(t, diffTokens.AmountOf(app.StakingKeeper.BondDenom(ctx)).Equal(sdk.NewInt(5)))
}
// tests slashRedelegation
func TestSlashRedelegation(t *testing.T) {
app, ctx, 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)
balances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
require.NoError(t, testutil.FundModuleAccount(app.BankKeeper, ctx, bondedPool.GetName(), startCoins))
app.AccountKeeper.SetModuleAccount(ctx, 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))
app.StakingKeeper.SetRedelegation(ctx, rd)
// set the associated delegation
del := types.NewDelegation(addrDels[0], addrVals[1], math.LegacyNewDec(10))
app.StakingKeeper.SetDelegation(ctx, del)
// started redelegating prior to the current height, stake didn't contribute to infraction
validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[1])
require.True(t, found)
slashAmount := app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 1, fraction)
require.True(t, slashAmount.Equal(sdk.NewInt(0)))
// after the expiration time, no longer eligible for slashing
ctx = ctx.WithBlockHeader(tmproto.Header{Time: time.Unix(10, 0)})
app.StakingKeeper.SetRedelegation(ctx, rd)
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
require.True(t, found)
slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction)
require.True(t, slashAmount.Equal(sdk.NewInt(0)))
balances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
// test valid slash, before expiration timestamp and to which stake contributed
ctx = ctx.WithBlockHeader(tmproto.Header{Time: time.Unix(0, 0)})
app.StakingKeeper.SetRedelegation(ctx, rd)
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
require.True(t, found)
slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction)
require.True(t, slashAmount.Equal(sdk.NewInt(5)))
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
require.True(t, found)
require.Len(t, rd.Entries, 1)
// end block
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
// initialbalance unchanged
require.Equal(t, sdk.NewInt(10), rd.Entries[0].InitialBalance)
// shares decreased
del, found = app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[1])
require.True(t, found)
require.Equal(t, int64(5), del.Shares.RoundInt64())
// pool bonded tokens should decrease
burnedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), slashAmount))
require.Equal(t, balances.Sub(burnedCoins...), app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()))
keeper.Unjail(ctx, consAddr)
val, found = keeper.GetValidator(ctx, valAddr)
require.True(found)
require.False(val.IsJailed())
}
// tests Slash at a future height (must panic)
func TestSlashAtFutureHeight(t *testing.T) {
app, ctx, _, _ := bootstrapSlashTest(t, 10)
func (s *KeeperTestSuite) TestSlashAtFutureHeight() {
ctx, keeper := s.ctx, s.stakingKeeper
require := s.Require()
consAddr := sdk.ConsAddress(PKs[0].Address())
validator := teststaking.NewValidator(s.T(), sdk.ValAddress(PKs[0].Address().Bytes()), PKs[0])
keeper.SetValidator(ctx, validator)
err := keeper.SetValidatorByConsAddr(ctx, validator)
require.NoError(err)
fraction := sdk.NewDecWithPrec(5, 1)
require.Panics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 1, 10, fraction) })
}
// 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)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
app.StakingKeeper.Slash(ctx, consAddr, -2, 10, fraction)
// read updated state
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// end block
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
validator, found = app.StakingKeeper.GetValidator(ctx, validator.GetOperator())
require.True(t, found)
// power decreased
require.Equal(t, int64(5), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
// pool bonded shares decreased
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 5).String(), diffTokens.String())
}
// tests Slash at the current height
func TestSlashValidatorAtCurrentHeight(t *testing.T) {
app, ctx, _, _ := 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())
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
app.StakingKeeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction)
// read updated state
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// end block
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
validator, found = app.StakingKeeper.GetValidator(ctx, validator.GetOperator())
assert.True(t, found)
// power decreased
require.Equal(t, int64(5), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
// pool bonded shares decreased
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 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)
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)
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, time.Unix(0, 0), ubdTokens)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
// slash validator for the first time
ctx = ctx.WithBlockHeight(12)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction)
// end block
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
// read updating unbonding delegation
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
require.True(t, found)
require.Len(t, ubd.Entries, 1)
// balance decreased
require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 2), ubd.Entries[0].Balance)
// bonded tokens burned
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 3), diffTokens)
// read updated validator
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(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
require.Equal(t, int64(7), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
// slash validator again
ctx = ctx.WithBlockHeight(13)
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
require.True(t, found)
require.Len(t, ubd.Entries, 1)
// balance decreased again
require.Equal(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))
require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 6), diffTokens)
// read updated validator
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// power decreased by 3 again
require.Equal(t, int64(4), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
// 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 behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440
ctx = ctx.WithBlockHeight(13)
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
require.True(t, found)
require.Len(t, ubd.Entries, 1)
// balance unchanged
require.Equal(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))
require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 9), diffTokens)
// read updated validator
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// power decreased by 3 again
require.Equal(t, int64(1), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
// 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 behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440
ctx = ctx.WithBlockHeight(13)
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
require.True(t, found)
require.Len(t, ubd.Entries, 1)
// balance unchanged
require.Equal(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))
require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 10), diffTokens)
// apply TM updates
applyValidatorSetUpdates(t, ctx, app.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)
require.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)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondDenom := app.StakingKeeper.BondDenom(ctx)
// set a redelegation
rdTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6)
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, time.Unix(0, 0), rdTokens, sdk.NewDecFromInt(rdTokens))
app.StakingKeeper.SetRedelegation(ctx, rd)
// set the associated delegation
del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDecFromInt(rdTokens))
app.StakingKeeper.SetDelegation(ctx, del)
// update bonded tokens
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
rdCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdTokens.MulRaw(2)))
require.NoError(t, testutil.FundModuleAccount(app.BankKeeper, ctx, bondedPool.GetName(), rdCoins))
app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
oldBonded := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
// slash validator
ctx = ctx.WithBlockHeight(12)
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction) })
burnAmount := sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 10)).Mul(fraction).TruncateInt()
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
// burn bonded tokens from only from delegations
bondedPoolBalance := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldNotBonded, notBondedPoolBalance))
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
// read updating redelegation
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
require.True(t, found)
require.Len(t, rd.Entries, 1)
// read updated validator
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(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
require.Equal(t, int64(8), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
// slash the validator again
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, math.LegacyOneDec()) })
burnAmount = app.StakingKeeper.TokensFromConsensusPower(ctx, 7)
// read updated pool
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
// seven bonded tokens burned
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
require.True(math.IntEq(t, oldNotBonded, notBondedPoolBalance))
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldNotBonded, notBondedPoolBalance))
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
// read updating redelegation
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
require.True(t, found)
require.Len(t, rd.Entries, 1)
// read updated validator
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// power decreased by 4
require.Equal(t, int64(4), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
// slash the validator again, by 100%
ctx = ctx.WithBlockHeight(12)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, math.LegacyOneDec()) })
burnAmount = sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 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)
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldNotBonded, notBondedPoolBalance))
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
// read updating redelegation
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
require.True(t, found)
require.Len(t, rd.Entries, 1)
// apply TM updates
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
// read updated validator
// validator decreased to zero power, should be in unbonding period
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.Equal(t, validator.GetStatus(), types.Unbonding)
// slash the validator again, by 100%
// no stake remains to be slashed
ctx = ctx.WithBlockHeight(12)
// validator still in unbonding period
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.Equal(t, validator.GetStatus(), types.Unbonding)
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, math.LegacyOneDec()) })
// read updated pool
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldBonded, bondedPoolBalance))
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldNotBonded, notBondedPoolBalance))
// read updating redelegation
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
require.True(t, found)
require.Len(t, rd.Entries, 1)
// read updated validator
// power still zero, still in unbonding period
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.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)
fraction := sdk.NewDecWithPrec(5, 1)
bondDenom := app.StakingKeeper.BondDenom(ctx)
// set a redelegation with expiration timestamp beyond which the
// redelegation shouldn't be slashed
rdATokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6)
rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, time.Unix(0, 0), rdATokens, sdk.NewDecFromInt(rdATokens))
app.StakingKeeper.SetRedelegation(ctx, rdA)
// set the associated delegation
delA := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDecFromInt(rdATokens))
app.StakingKeeper.SetDelegation(ctx, delA)
// set an unbonding delegation with expiration timestamp (beyond which the
// unbonding delegation shouldn't be slashed)
ubdATokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 4)
ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
time.Unix(0, 0), ubdATokens)
app.StakingKeeper.SetUnbondingDelegation(ctx, 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)
require.NoError(t, testutil.FundModuleAccount(app.BankKeeper, ctx, bondedPool.GetName(), bondedCoins))
require.NoError(t, testutil.FundModuleAccount(app.BankKeeper, ctx, notBondedPool.GetName(), notBondedCoins))
app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
oldBonded := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
// slash validator
ctx = ctx.WithBlockHeight(12)
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
require.True(t, found)
consAddr0 := sdk.ConsAddress(PKs[0].Address())
app.StakingKeeper.Slash(ctx, consAddr0, 10, 10, fraction)
burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt()
burnedBondAmount := sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 10)).Mul(fraction).TruncateInt()
burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount)
// read updated pool
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
bondedPoolBalance := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldBonded.Sub(burnedBondAmount), bondedPoolBalance))
notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
require.True(math.IntEq(t, oldNotBonded.Sub(burnedNotBondedAmount), notBondedPoolBalance))
// read updating redelegation
rdA, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
require.True(t, found)
require.Len(t, rdA.Entries, 1)
// read updated validator
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
require.True(t, found)
// power not decreased, all stake was bonded since
require.Equal(t, int64(10), validator.GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
}
func TestSlashAmount(t *testing.T) {
app, ctx, _, _ := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
burnedCoins := app.StakingKeeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction)
require.True(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)
require.True(t, sdk.NewInt(0).Equal(noBurned))
require.Panics(func() { keeper.Slash(ctx, consAddr, 1, 10, fraction) })
}
-29
View File
@@ -1,29 +0,0 @@
package keeper_test
import "testing"
func BenchmarkGetValidator(b *testing.B) {
// 900 is the max number we are allowed to use in order to avoid simtestutil.CreateTestPubKeys
// panic: encoding/hex: odd length hex string
powersNumber := 900
var totalPower int64 = 0
powers := make([]int64, powersNumber)
for i := range powers {
powers[i] = int64(i)
totalPower += int64(i)
}
app, ctx, _, valAddrs, vals := initValidators(b, totalPower, len(powers), powers)
for _, validator := range vals {
app.StakingKeeper.SetValidator(ctx, validator)
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
for _, addr := range valAddrs {
_, _ = app.StakingKeeper.GetValidator(ctx, addr)
}
}
}
File diff suppressed because it is too large Load Diff
+122
View File
@@ -0,0 +1,122 @@
package testutil
import (
_ "github.com/cosmos/cosmos-sdk/x/auth"
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/module"
_ "github.com/cosmos/cosmos-sdk/x/bank"
_ "github.com/cosmos/cosmos-sdk/x/distribution"
_ "github.com/cosmos/cosmos-sdk/x/genutil"
_ "github.com/cosmos/cosmos-sdk/x/mint"
_ "github.com/cosmos/cosmos-sdk/x/params"
_ "github.com/cosmos/cosmos-sdk/x/slashing"
_ "github.com/cosmos/cosmos-sdk/x/staking"
"cosmossdk.io/core/appconfig"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
mintmodulev1 "cosmossdk.io/api/cosmos/mint/module/v1"
paramsmodulev1 "cosmossdk.io/api/cosmos/params/module/v1"
slashingmodulev1 "cosmossdk.io/api/cosmos/slashing/module/v1"
stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1"
txmodulev1 "cosmossdk.io/api/cosmos/tx/module/v1"
)
var AppConfig = appconfig.Compose(&appv1alpha1.Config{
Modules: []*appv1alpha1.ModuleConfig{
{
Name: "runtime",
Config: appconfig.WrapAny(&runtimev1alpha1.Module{
AppName: "StakingApp",
BeginBlockers: []string{
minttypes.ModuleName,
distrtypes.ModuleName,
stakingtypes.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
genutiltypes.ModuleName,
slashingtypes.ModuleName,
paramstypes.ModuleName,
},
EndBlockers: []string{
stakingtypes.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
genutiltypes.ModuleName,
distrtypes.ModuleName,
minttypes.ModuleName,
slashingtypes.ModuleName,
paramstypes.ModuleName,
},
InitGenesis: []string{
authtypes.ModuleName,
banktypes.ModuleName,
distrtypes.ModuleName,
stakingtypes.ModuleName,
minttypes.ModuleName,
slashingtypes.ModuleName,
genutiltypes.ModuleName,
paramstypes.ModuleName,
},
}),
},
{
Name: authtypes.ModuleName,
Config: appconfig.WrapAny(&authmodulev1.Module{
Bech32Prefix: "cosmos",
ModuleAccountPermissions: []*authmodulev1.ModuleAccountPermission{
{Account: authtypes.FeeCollectorName},
{Account: distrtypes.ModuleName},
{Account: minttypes.ModuleName, Permissions: []string{authtypes.Minter}},
{Account: stakingtypes.BondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}},
{Account: stakingtypes.NotBondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}},
},
}),
},
{
Name: banktypes.ModuleName,
Config: appconfig.WrapAny(&bankmodulev1.Module{}),
},
{
Name: stakingtypes.ModuleName,
Config: appconfig.WrapAny(&stakingmodulev1.Module{}),
},
{
Name: slashingtypes.ModuleName,
Config: appconfig.WrapAny(&slashingmodulev1.Module{}),
},
{
Name: paramstypes.ModuleName,
Config: appconfig.WrapAny(&paramsmodulev1.Module{}),
},
{
Name: "tx",
Config: appconfig.WrapAny(&txmodulev1.Module{}),
},
{
Name: genutiltypes.ModuleName,
Config: appconfig.WrapAny(&genutilmodulev1.Module{}),
},
{
Name: minttypes.ModuleName,
Config: appconfig.WrapAny(&mintmodulev1.Module{}),
},
{
Name: distrtypes.ModuleName,
Config: appconfig.WrapAny(&distrmodulev1.Module{}),
},
},
})
@@ -0,0 +1,697 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: x/staking/types/expected_keepers.go
// Package testutil is a generated GoMock package.
package testutil
import (
reflect "reflect"
math "cosmossdk.io/math"
types "github.com/cosmos/cosmos-sdk/types"
types0 "github.com/cosmos/cosmos-sdk/x/auth/types"
types1 "github.com/cosmos/cosmos-sdk/x/staking/types"
gomock "github.com/golang/mock/gomock"
)
// MockDistributionKeeper is a mock of DistributionKeeper interface.
type MockDistributionKeeper struct {
ctrl *gomock.Controller
recorder *MockDistributionKeeperMockRecorder
}
// MockDistributionKeeperMockRecorder is the mock recorder for MockDistributionKeeper.
type MockDistributionKeeperMockRecorder struct {
mock *MockDistributionKeeper
}
// NewMockDistributionKeeper creates a new mock instance.
func NewMockDistributionKeeper(ctrl *gomock.Controller) *MockDistributionKeeper {
mock := &MockDistributionKeeper{ctrl: ctrl}
mock.recorder = &MockDistributionKeeperMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockDistributionKeeper) EXPECT() *MockDistributionKeeperMockRecorder {
return m.recorder
}
// GetFeePoolCommunityCoins mocks base method.
func (m *MockDistributionKeeper) GetFeePoolCommunityCoins(ctx types.Context) types.DecCoins {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetFeePoolCommunityCoins", ctx)
ret0, _ := ret[0].(types.DecCoins)
return ret0
}
// GetFeePoolCommunityCoins indicates an expected call of GetFeePoolCommunityCoins.
func (mr *MockDistributionKeeperMockRecorder) GetFeePoolCommunityCoins(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeePoolCommunityCoins", reflect.TypeOf((*MockDistributionKeeper)(nil).GetFeePoolCommunityCoins), ctx)
}
// GetValidatorOutstandingRewardsCoins mocks base method.
func (m *MockDistributionKeeper) GetValidatorOutstandingRewardsCoins(ctx types.Context, val types.ValAddress) types.DecCoins {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetValidatorOutstandingRewardsCoins", ctx, val)
ret0, _ := ret[0].(types.DecCoins)
return ret0
}
// GetValidatorOutstandingRewardsCoins indicates an expected call of GetValidatorOutstandingRewardsCoins.
func (mr *MockDistributionKeeperMockRecorder) GetValidatorOutstandingRewardsCoins(ctx, val interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorOutstandingRewardsCoins", reflect.TypeOf((*MockDistributionKeeper)(nil).GetValidatorOutstandingRewardsCoins), ctx, val)
}
// MockAccountKeeper is a mock of AccountKeeper interface.
type MockAccountKeeper struct {
ctrl *gomock.Controller
recorder *MockAccountKeeperMockRecorder
}
// MockAccountKeeperMockRecorder is the mock recorder for MockAccountKeeper.
type MockAccountKeeperMockRecorder struct {
mock *MockAccountKeeper
}
// NewMockAccountKeeper creates a new mock instance.
func NewMockAccountKeeper(ctrl *gomock.Controller) *MockAccountKeeper {
mock := &MockAccountKeeper{ctrl: ctrl}
mock.recorder = &MockAccountKeeperMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockAccountKeeper) EXPECT() *MockAccountKeeperMockRecorder {
return m.recorder
}
// GetAccount mocks base method.
func (m *MockAccountKeeper) GetAccount(ctx types.Context, addr types.AccAddress) types0.AccountI {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAccount", ctx, addr)
ret0, _ := ret[0].(types0.AccountI)
return ret0
}
// GetAccount indicates an expected call of GetAccount.
func (mr *MockAccountKeeperMockRecorder) GetAccount(ctx, addr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccount", reflect.TypeOf((*MockAccountKeeper)(nil).GetAccount), ctx, addr)
}
// GetModuleAccount mocks base method.
func (m *MockAccountKeeper) GetModuleAccount(ctx types.Context, moduleName string) types0.ModuleAccountI {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetModuleAccount", ctx, moduleName)
ret0, _ := ret[0].(types0.ModuleAccountI)
return ret0
}
// GetModuleAccount indicates an expected call of GetModuleAccount.
func (mr *MockAccountKeeperMockRecorder) GetModuleAccount(ctx, moduleName interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetModuleAccount", reflect.TypeOf((*MockAccountKeeper)(nil).GetModuleAccount), ctx, moduleName)
}
// GetModuleAddress mocks base method.
func (m *MockAccountKeeper) GetModuleAddress(name string) types.AccAddress {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetModuleAddress", name)
ret0, _ := ret[0].(types.AccAddress)
return ret0
}
// GetModuleAddress indicates an expected call of GetModuleAddress.
func (mr *MockAccountKeeperMockRecorder) GetModuleAddress(name interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetModuleAddress", reflect.TypeOf((*MockAccountKeeper)(nil).GetModuleAddress), name)
}
// IterateAccounts mocks base method.
func (m *MockAccountKeeper) IterateAccounts(ctx types.Context, process func(types0.AccountI) bool) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "IterateAccounts", ctx, process)
}
// IterateAccounts indicates an expected call of IterateAccounts.
func (mr *MockAccountKeeperMockRecorder) IterateAccounts(ctx, process interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateAccounts", reflect.TypeOf((*MockAccountKeeper)(nil).IterateAccounts), ctx, process)
}
// SetModuleAccount mocks base method.
func (m *MockAccountKeeper) SetModuleAccount(arg0 types.Context, arg1 types0.ModuleAccountI) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "SetModuleAccount", arg0, arg1)
}
// SetModuleAccount indicates an expected call of SetModuleAccount.
func (mr *MockAccountKeeperMockRecorder) SetModuleAccount(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetModuleAccount", reflect.TypeOf((*MockAccountKeeper)(nil).SetModuleAccount), arg0, arg1)
}
// MockBankKeeper is a mock of BankKeeper interface.
type MockBankKeeper struct {
ctrl *gomock.Controller
recorder *MockBankKeeperMockRecorder
}
// MockBankKeeperMockRecorder is the mock recorder for MockBankKeeper.
type MockBankKeeperMockRecorder struct {
mock *MockBankKeeper
}
// NewMockBankKeeper creates a new mock instance.
func NewMockBankKeeper(ctrl *gomock.Controller) *MockBankKeeper {
mock := &MockBankKeeper{ctrl: ctrl}
mock.recorder = &MockBankKeeperMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockBankKeeper) EXPECT() *MockBankKeeperMockRecorder {
return m.recorder
}
// BurnCoins mocks base method.
func (m *MockBankKeeper) BurnCoins(ctx types.Context, name string, amt types.Coins) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BurnCoins", ctx, name, amt)
ret0, _ := ret[0].(error)
return ret0
}
// BurnCoins indicates an expected call of BurnCoins.
func (mr *MockBankKeeperMockRecorder) BurnCoins(ctx, name, amt interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BurnCoins", reflect.TypeOf((*MockBankKeeper)(nil).BurnCoins), ctx, name, amt)
}
// DelegateCoinsFromAccountToModule mocks base method.
func (m *MockBankKeeper) DelegateCoinsFromAccountToModule(ctx types.Context, senderAddr types.AccAddress, recipientModule string, amt types.Coins) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DelegateCoinsFromAccountToModule", ctx, senderAddr, recipientModule, amt)
ret0, _ := ret[0].(error)
return ret0
}
// DelegateCoinsFromAccountToModule indicates an expected call of DelegateCoinsFromAccountToModule.
func (mr *MockBankKeeperMockRecorder) DelegateCoinsFromAccountToModule(ctx, senderAddr, recipientModule, amt interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelegateCoinsFromAccountToModule", reflect.TypeOf((*MockBankKeeper)(nil).DelegateCoinsFromAccountToModule), ctx, senderAddr, recipientModule, amt)
}
// GetAllBalances mocks base method.
func (m *MockBankKeeper) GetAllBalances(ctx types.Context, addr types.AccAddress) types.Coins {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAllBalances", ctx, addr)
ret0, _ := ret[0].(types.Coins)
return ret0
}
// GetAllBalances indicates an expected call of GetAllBalances.
func (mr *MockBankKeeperMockRecorder) GetAllBalances(ctx, addr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllBalances", reflect.TypeOf((*MockBankKeeper)(nil).GetAllBalances), ctx, addr)
}
// GetBalance mocks base method.
func (m *MockBankKeeper) GetBalance(ctx types.Context, addr types.AccAddress, denom string) types.Coin {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBalance", ctx, addr, denom)
ret0, _ := ret[0].(types.Coin)
return ret0
}
// GetBalance indicates an expected call of GetBalance.
func (mr *MockBankKeeperMockRecorder) GetBalance(ctx, addr, denom interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalance", reflect.TypeOf((*MockBankKeeper)(nil).GetBalance), ctx, addr, denom)
}
// GetSupply mocks base method.
func (m *MockBankKeeper) GetSupply(ctx types.Context, denom string) types.Coin {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSupply", ctx, denom)
ret0, _ := ret[0].(types.Coin)
return ret0
}
// GetSupply indicates an expected call of GetSupply.
func (mr *MockBankKeeperMockRecorder) GetSupply(ctx, denom interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSupply", reflect.TypeOf((*MockBankKeeper)(nil).GetSupply), ctx, denom)
}
// LockedCoins mocks base method.
func (m *MockBankKeeper) LockedCoins(ctx types.Context, addr types.AccAddress) types.Coins {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "LockedCoins", ctx, addr)
ret0, _ := ret[0].(types.Coins)
return ret0
}
// LockedCoins indicates an expected call of LockedCoins.
func (mr *MockBankKeeperMockRecorder) LockedCoins(ctx, addr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedCoins", reflect.TypeOf((*MockBankKeeper)(nil).LockedCoins), ctx, addr)
}
// SendCoinsFromModuleToModule mocks base method.
func (m *MockBankKeeper) SendCoinsFromModuleToModule(ctx types.Context, senderPool, recipientPool string, amt types.Coins) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SendCoinsFromModuleToModule", ctx, senderPool, recipientPool, amt)
ret0, _ := ret[0].(error)
return ret0
}
// SendCoinsFromModuleToModule indicates an expected call of SendCoinsFromModuleToModule.
func (mr *MockBankKeeperMockRecorder) SendCoinsFromModuleToModule(ctx, senderPool, recipientPool, amt interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromModuleToModule", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromModuleToModule), ctx, senderPool, recipientPool, amt)
}
// SpendableCoins mocks base method.
func (m *MockBankKeeper) SpendableCoins(ctx types.Context, addr types.AccAddress) types.Coins {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SpendableCoins", ctx, addr)
ret0, _ := ret[0].(types.Coins)
return ret0
}
// SpendableCoins indicates an expected call of SpendableCoins.
func (mr *MockBankKeeperMockRecorder) SpendableCoins(ctx, addr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpendableCoins", reflect.TypeOf((*MockBankKeeper)(nil).SpendableCoins), ctx, addr)
}
// UndelegateCoinsFromModuleToAccount mocks base method.
func (m *MockBankKeeper) UndelegateCoinsFromModuleToAccount(ctx types.Context, senderModule string, recipientAddr types.AccAddress, amt types.Coins) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UndelegateCoinsFromModuleToAccount", ctx, senderModule, recipientAddr, amt)
ret0, _ := ret[0].(error)
return ret0
}
// UndelegateCoinsFromModuleToAccount indicates an expected call of UndelegateCoinsFromModuleToAccount.
func (mr *MockBankKeeperMockRecorder) UndelegateCoinsFromModuleToAccount(ctx, senderModule, recipientAddr, amt interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UndelegateCoinsFromModuleToAccount", reflect.TypeOf((*MockBankKeeper)(nil).UndelegateCoinsFromModuleToAccount), ctx, senderModule, recipientAddr, amt)
}
// MockValidatorSet is a mock of ValidatorSet interface.
type MockValidatorSet struct {
ctrl *gomock.Controller
recorder *MockValidatorSetMockRecorder
}
// MockValidatorSetMockRecorder is the mock recorder for MockValidatorSet.
type MockValidatorSetMockRecorder struct {
mock *MockValidatorSet
}
// NewMockValidatorSet creates a new mock instance.
func NewMockValidatorSet(ctrl *gomock.Controller) *MockValidatorSet {
mock := &MockValidatorSet{ctrl: ctrl}
mock.recorder = &MockValidatorSetMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockValidatorSet) EXPECT() *MockValidatorSetMockRecorder {
return m.recorder
}
// Delegation mocks base method.
func (m *MockValidatorSet) Delegation(arg0 types.Context, arg1 types.AccAddress, arg2 types.ValAddress) types1.DelegationI {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delegation", arg0, arg1, arg2)
ret0, _ := ret[0].(types1.DelegationI)
return ret0
}
// Delegation indicates an expected call of Delegation.
func (mr *MockValidatorSetMockRecorder) Delegation(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delegation", reflect.TypeOf((*MockValidatorSet)(nil).Delegation), arg0, arg1, arg2)
}
// IterateBondedValidatorsByPower mocks base method.
func (m *MockValidatorSet) IterateBondedValidatorsByPower(arg0 types.Context, arg1 func(int64, types1.ValidatorI) bool) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "IterateBondedValidatorsByPower", arg0, arg1)
}
// IterateBondedValidatorsByPower indicates an expected call of IterateBondedValidatorsByPower.
func (mr *MockValidatorSetMockRecorder) IterateBondedValidatorsByPower(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateBondedValidatorsByPower", reflect.TypeOf((*MockValidatorSet)(nil).IterateBondedValidatorsByPower), arg0, arg1)
}
// IterateLastValidators mocks base method.
func (m *MockValidatorSet) IterateLastValidators(arg0 types.Context, arg1 func(int64, types1.ValidatorI) bool) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "IterateLastValidators", arg0, arg1)
}
// IterateLastValidators indicates an expected call of IterateLastValidators.
func (mr *MockValidatorSetMockRecorder) IterateLastValidators(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateLastValidators", reflect.TypeOf((*MockValidatorSet)(nil).IterateLastValidators), arg0, arg1)
}
// IterateValidators mocks base method.
func (m *MockValidatorSet) IterateValidators(arg0 types.Context, arg1 func(int64, types1.ValidatorI) bool) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "IterateValidators", arg0, arg1)
}
// IterateValidators indicates an expected call of IterateValidators.
func (mr *MockValidatorSetMockRecorder) IterateValidators(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateValidators", reflect.TypeOf((*MockValidatorSet)(nil).IterateValidators), arg0, arg1)
}
// Jail mocks base method.
func (m *MockValidatorSet) Jail(arg0 types.Context, arg1 types.ConsAddress) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "Jail", arg0, arg1)
}
// Jail indicates an expected call of Jail.
func (mr *MockValidatorSetMockRecorder) Jail(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Jail", reflect.TypeOf((*MockValidatorSet)(nil).Jail), arg0, arg1)
}
// MaxValidators mocks base method.
func (m *MockValidatorSet) MaxValidators(arg0 types.Context) uint32 {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "MaxValidators", arg0)
ret0, _ := ret[0].(uint32)
return ret0
}
// MaxValidators indicates an expected call of MaxValidators.
func (mr *MockValidatorSetMockRecorder) MaxValidators(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaxValidators", reflect.TypeOf((*MockValidatorSet)(nil).MaxValidators), arg0)
}
// Slash mocks base method.
func (m *MockValidatorSet) Slash(arg0 types.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 types.Dec) math.Int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Slash", arg0, arg1, arg2, arg3, arg4)
ret0, _ := ret[0].(math.Int)
return ret0
}
// Slash indicates an expected call of Slash.
func (mr *MockValidatorSetMockRecorder) Slash(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Slash", reflect.TypeOf((*MockValidatorSet)(nil).Slash), arg0, arg1, arg2, arg3, arg4)
}
// StakingTokenSupply mocks base method.
func (m *MockValidatorSet) StakingTokenSupply(arg0 types.Context) math.Int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "StakingTokenSupply", arg0)
ret0, _ := ret[0].(math.Int)
return ret0
}
// StakingTokenSupply indicates an expected call of StakingTokenSupply.
func (mr *MockValidatorSetMockRecorder) StakingTokenSupply(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StakingTokenSupply", reflect.TypeOf((*MockValidatorSet)(nil).StakingTokenSupply), arg0)
}
// TotalBondedTokens mocks base method.
func (m *MockValidatorSet) TotalBondedTokens(arg0 types.Context) math.Int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "TotalBondedTokens", arg0)
ret0, _ := ret[0].(math.Int)
return ret0
}
// TotalBondedTokens indicates an expected call of TotalBondedTokens.
func (mr *MockValidatorSetMockRecorder) TotalBondedTokens(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TotalBondedTokens", reflect.TypeOf((*MockValidatorSet)(nil).TotalBondedTokens), arg0)
}
// Unjail mocks base method.
func (m *MockValidatorSet) Unjail(arg0 types.Context, arg1 types.ConsAddress) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "Unjail", arg0, arg1)
}
// Unjail indicates an expected call of Unjail.
func (mr *MockValidatorSetMockRecorder) Unjail(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unjail", reflect.TypeOf((*MockValidatorSet)(nil).Unjail), arg0, arg1)
}
// Validator mocks base method.
func (m *MockValidatorSet) Validator(arg0 types.Context, arg1 types.ValAddress) types1.ValidatorI {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Validator", arg0, arg1)
ret0, _ := ret[0].(types1.ValidatorI)
return ret0
}
// Validator indicates an expected call of Validator.
func (mr *MockValidatorSetMockRecorder) Validator(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validator", reflect.TypeOf((*MockValidatorSet)(nil).Validator), arg0, arg1)
}
// ValidatorByConsAddr mocks base method.
func (m *MockValidatorSet) ValidatorByConsAddr(arg0 types.Context, arg1 types.ConsAddress) types1.ValidatorI {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ValidatorByConsAddr", arg0, arg1)
ret0, _ := ret[0].(types1.ValidatorI)
return ret0
}
// ValidatorByConsAddr indicates an expected call of ValidatorByConsAddr.
func (mr *MockValidatorSetMockRecorder) ValidatorByConsAddr(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorByConsAddr", reflect.TypeOf((*MockValidatorSet)(nil).ValidatorByConsAddr), arg0, arg1)
}
// MockDelegationSet is a mock of DelegationSet interface.
type MockDelegationSet struct {
ctrl *gomock.Controller
recorder *MockDelegationSetMockRecorder
}
// MockDelegationSetMockRecorder is the mock recorder for MockDelegationSet.
type MockDelegationSetMockRecorder struct {
mock *MockDelegationSet
}
// NewMockDelegationSet creates a new mock instance.
func NewMockDelegationSet(ctrl *gomock.Controller) *MockDelegationSet {
mock := &MockDelegationSet{ctrl: ctrl}
mock.recorder = &MockDelegationSetMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockDelegationSet) EXPECT() *MockDelegationSetMockRecorder {
return m.recorder
}
// GetValidatorSet mocks base method.
func (m *MockDelegationSet) GetValidatorSet() types1.ValidatorSet {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetValidatorSet")
ret0, _ := ret[0].(types1.ValidatorSet)
return ret0
}
// GetValidatorSet indicates an expected call of GetValidatorSet.
func (mr *MockDelegationSetMockRecorder) GetValidatorSet() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorSet", reflect.TypeOf((*MockDelegationSet)(nil).GetValidatorSet))
}
// IterateDelegations mocks base method.
func (m *MockDelegationSet) IterateDelegations(ctx types.Context, delegator types.AccAddress, fn func(int64, types1.DelegationI) bool) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "IterateDelegations", ctx, delegator, fn)
}
// IterateDelegations indicates an expected call of IterateDelegations.
func (mr *MockDelegationSetMockRecorder) IterateDelegations(ctx, delegator, fn interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateDelegations", reflect.TypeOf((*MockDelegationSet)(nil).IterateDelegations), ctx, delegator, fn)
}
// MockStakingHooks is a mock of StakingHooks interface.
type MockStakingHooks struct {
ctrl *gomock.Controller
recorder *MockStakingHooksMockRecorder
}
// MockStakingHooksMockRecorder is the mock recorder for MockStakingHooks.
type MockStakingHooksMockRecorder struct {
mock *MockStakingHooks
}
// NewMockStakingHooks creates a new mock instance.
func NewMockStakingHooks(ctrl *gomock.Controller) *MockStakingHooks {
mock := &MockStakingHooks{ctrl: ctrl}
mock.recorder = &MockStakingHooksMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockStakingHooks) EXPECT() *MockStakingHooksMockRecorder {
return m.recorder
}
// AfterDelegationModified mocks base method.
func (m *MockStakingHooks) AfterDelegationModified(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AfterDelegationModified", ctx, delAddr, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// AfterDelegationModified indicates an expected call of AfterDelegationModified.
func (mr *MockStakingHooksMockRecorder) AfterDelegationModified(ctx, delAddr, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterDelegationModified", reflect.TypeOf((*MockStakingHooks)(nil).AfterDelegationModified), ctx, delAddr, valAddr)
}
// AfterValidatorBeginUnbonding mocks base method.
func (m *MockStakingHooks) AfterValidatorBeginUnbonding(ctx types.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AfterValidatorBeginUnbonding", ctx, consAddr, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// AfterValidatorBeginUnbonding indicates an expected call of AfterValidatorBeginUnbonding.
func (mr *MockStakingHooksMockRecorder) AfterValidatorBeginUnbonding(ctx, consAddr, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterValidatorBeginUnbonding", reflect.TypeOf((*MockStakingHooks)(nil).AfterValidatorBeginUnbonding), ctx, consAddr, valAddr)
}
// AfterValidatorBonded mocks base method.
func (m *MockStakingHooks) AfterValidatorBonded(ctx types.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AfterValidatorBonded", ctx, consAddr, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// AfterValidatorBonded indicates an expected call of AfterValidatorBonded.
func (mr *MockStakingHooksMockRecorder) AfterValidatorBonded(ctx, consAddr, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterValidatorBonded", reflect.TypeOf((*MockStakingHooks)(nil).AfterValidatorBonded), ctx, consAddr, valAddr)
}
// AfterValidatorCreated mocks base method.
func (m *MockStakingHooks) AfterValidatorCreated(ctx types.Context, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AfterValidatorCreated", ctx, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// AfterValidatorCreated indicates an expected call of AfterValidatorCreated.
func (mr *MockStakingHooksMockRecorder) AfterValidatorCreated(ctx, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterValidatorCreated", reflect.TypeOf((*MockStakingHooks)(nil).AfterValidatorCreated), ctx, valAddr)
}
// AfterValidatorRemoved mocks base method.
func (m *MockStakingHooks) AfterValidatorRemoved(ctx types.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AfterValidatorRemoved", ctx, consAddr, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// AfterValidatorRemoved indicates an expected call of AfterValidatorRemoved.
func (mr *MockStakingHooksMockRecorder) AfterValidatorRemoved(ctx, consAddr, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterValidatorRemoved", reflect.TypeOf((*MockStakingHooks)(nil).AfterValidatorRemoved), ctx, consAddr, valAddr)
}
// BeforeDelegationCreated mocks base method.
func (m *MockStakingHooks) BeforeDelegationCreated(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BeforeDelegationCreated", ctx, delAddr, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// BeforeDelegationCreated indicates an expected call of BeforeDelegationCreated.
func (mr *MockStakingHooksMockRecorder) BeforeDelegationCreated(ctx, delAddr, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeforeDelegationCreated", reflect.TypeOf((*MockStakingHooks)(nil).BeforeDelegationCreated), ctx, delAddr, valAddr)
}
// BeforeDelegationRemoved mocks base method.
func (m *MockStakingHooks) BeforeDelegationRemoved(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BeforeDelegationRemoved", ctx, delAddr, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// BeforeDelegationRemoved indicates an expected call of BeforeDelegationRemoved.
func (mr *MockStakingHooksMockRecorder) BeforeDelegationRemoved(ctx, delAddr, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeforeDelegationRemoved", reflect.TypeOf((*MockStakingHooks)(nil).BeforeDelegationRemoved), ctx, delAddr, valAddr)
}
// BeforeDelegationSharesModified mocks base method.
func (m *MockStakingHooks) BeforeDelegationSharesModified(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BeforeDelegationSharesModified", ctx, delAddr, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// BeforeDelegationSharesModified indicates an expected call of BeforeDelegationSharesModified.
func (mr *MockStakingHooksMockRecorder) BeforeDelegationSharesModified(ctx, delAddr, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeforeDelegationSharesModified", reflect.TypeOf((*MockStakingHooks)(nil).BeforeDelegationSharesModified), ctx, delAddr, valAddr)
}
// BeforeValidatorModified mocks base method.
func (m *MockStakingHooks) BeforeValidatorModified(ctx types.Context, valAddr types.ValAddress) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BeforeValidatorModified", ctx, valAddr)
ret0, _ := ret[0].(error)
return ret0
}
// BeforeValidatorModified indicates an expected call of BeforeValidatorModified.
func (mr *MockStakingHooksMockRecorder) BeforeValidatorModified(ctx, valAddr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeforeValidatorModified", reflect.TypeOf((*MockStakingHooks)(nil).BeforeValidatorModified), ctx, valAddr)
}
// BeforeValidatorSlashed mocks base method.
func (m *MockStakingHooks) BeforeValidatorSlashed(ctx types.Context, valAddr types.ValAddress, fraction types.Dec) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BeforeValidatorSlashed", ctx, valAddr, fraction)
ret0, _ := ret[0].(error)
return ret0
}
// BeforeValidatorSlashed indicates an expected call of BeforeValidatorSlashed.
func (mr *MockStakingHooksMockRecorder) BeforeValidatorSlashed(ctx, valAddr, fraction interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeforeValidatorSlashed", reflect.TypeOf((*MockStakingHooks)(nil).BeforeValidatorSlashed), ctx, valAddr, fraction)
}