Skip to content

Commit

Permalink
test(x/staking): write integration tests (#15890)
Browse files Browse the repository at this point in the history
  • Loading branch information
likhita-809 authored May 2, 2023
1 parent 946f3d6 commit 672b1f9
Show file tree
Hide file tree
Showing 19 changed files with 1,282 additions and 3,158 deletions.
770 changes: 0 additions & 770 deletions tests/e2e/staking/grpc.go

This file was deleted.

1,423 changes: 0 additions & 1,423 deletions tests/e2e/staking/suite.go

Large diffs are not rendered by default.

154 changes: 112 additions & 42 deletions tests/integration/staking/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,48 @@ import (
"math/big"
"testing"

"cosmossdk.io/simapp"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
"gotest.tools/v3/assert"

cmtprototypes "github.com/cometbft/cometbft/proto/tendermint/types"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil/integration"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/auth"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/testutil"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)

var PKs = simtestutil.CreateTestPubKeys(500)

func init() {
sdk.DefaultPowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))
type fixture struct {
app *integration.App

sdkCtx sdk.Context
cdc codec.Codec
keys map[string]*storetypes.KVStoreKey

accountKeeper authkeeper.AccountKeeper
bankKeeper bankkeeper.Keeper
stakingKeeper *stakingkeeper.Keeper
}

// createTestInput Returns a simapp with custom StakingKeeper
// to avoid messing with the hooks.
func createTestInput(t *testing.T) (*codec.LegacyAmino, *simapp.SimApp, sdk.Context) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})

app.StakingKeeper = keeper.NewKeeper(
app.AppCodec(),
app.GetKey(types.StoreKey),
app.AccountKeeper,
app.BankKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
return app.LegacyAmino(), app, ctx
func init() {
sdk.DefaultPowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))
}

// intended to be used with require/assert: require.True(ValEq(...))
Expand All @@ -47,44 +54,107 @@ func ValEq(t *testing.T, exp, got types.Validator) (*testing.T, bool, string, ty
}

// generateAddresses generates numAddrs of normal AccAddrs and ValAddrs
func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int) ([]sdk.AccAddress, []sdk.ValAddress) {
addrDels := simtestutil.AddTestAddrsIncremental(app.BankKeeper, app.StakingKeeper, ctx, numAddrs, sdk.NewInt(10000))
func generateAddresses(f *fixture, numAddrs int) ([]sdk.AccAddress, []sdk.ValAddress) {
addrDels := simtestutil.AddTestAddrsIncremental(f.bankKeeper, f.stakingKeeper, f.sdkCtx, numAddrs, sdk.NewInt(10000))
addrVals := simtestutil.ConvertAddrsToValAddrs(addrDels)

return addrDels, addrVals
}

func createValidators(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers []int64) ([]sdk.AccAddress, []sdk.ValAddress, []types.Validator) {
addrs := simtestutil.AddTestAddrsIncremental(app.BankKeeper, app.StakingKeeper, ctx, 5, app.StakingKeeper.TokensFromConsensusPower(ctx, 300))
func createValidators(t *testing.T, f *fixture, powers []int64) ([]sdk.AccAddress, []sdk.ValAddress, []types.Validator) {
addrs := simtestutil.AddTestAddrsIncremental(f.bankKeeper, f.stakingKeeper, f.sdkCtx, 5, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 300))
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs)
pks := simtestutil.CreateTestPubKeys(5)
cdc := moduletestutil.MakeTestEncodingConfig().Codec
app.StakingKeeper = keeper.NewKeeper(
cdc,
app.GetKey(types.StoreKey),
app.AccountKeeper,
app.BankKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

val1 := testutil.NewValidator(t, valAddrs[0], pks[0])
val2 := testutil.NewValidator(t, valAddrs[1], pks[1])
vals := []types.Validator{val1, val2}

app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetValidator(ctx, val2)
app.StakingKeeper.SetValidatorByConsAddr(ctx, val1)
app.StakingKeeper.SetValidatorByConsAddr(ctx, val2)
app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val1)
app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val2)
f.stakingKeeper.SetValidator(f.sdkCtx, val1)
f.stakingKeeper.SetValidator(f.sdkCtx, val2)
f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, val1)
f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, val2)
f.stakingKeeper.SetNewValidatorByPowerIndex(f.sdkCtx, val1)
f.stakingKeeper.SetNewValidatorByPowerIndex(f.sdkCtx, val2)

_, err := app.StakingKeeper.Delegate(ctx, addrs[0], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[0]), types.Unbonded, val1, true)
_, err := f.stakingKeeper.Delegate(f.sdkCtx, addrs[0], f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, powers[0]), types.Unbonded, val1, true)
assert.NilError(t, err)
_, err = app.StakingKeeper.Delegate(ctx, addrs[1], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[1]), types.Unbonded, val2, true)
_, err = f.stakingKeeper.Delegate(f.sdkCtx, addrs[1], f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, powers[1]), types.Unbonded, val2, true)
assert.NilError(t, err)
_, err = app.StakingKeeper.Delegate(ctx, addrs[0], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[2]), types.Unbonded, val2, true)
_, err = f.stakingKeeper.Delegate(f.sdkCtx, addrs[0], f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, powers[2]), types.Unbonded, val2, true)
assert.NilError(t, err)
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
applyValidatorSetUpdates(t, f.sdkCtx, f.stakingKeeper, -1)

return addrs, valAddrs, vals
}

func initFixture(t testing.TB) *fixture {
keys := storetypes.NewKVStoreKeys(
authtypes.StoreKey, banktypes.StoreKey, types.StoreKey,
)
cdc := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, staking.AppModuleBasic{}).Codec

logger := log.NewTestLogger(t)
cms := integration.CreateMultiStore(keys, logger)

newCtx := sdk.NewContext(cms, cmtprototypes.Header{}, true, logger)

authority := authtypes.NewModuleAddress("gov")

maccPerms := map[string][]string{
minttypes.ModuleName: {authtypes.Minter},
types.ModuleName: {authtypes.Minter},
types.BondedPoolName: {authtypes.Burner, authtypes.Staking},
types.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
}

accountKeeper := authkeeper.NewAccountKeeper(
cdc,
runtime.NewKVStoreService(keys[authtypes.StoreKey]),
authtypes.ProtoBaseAccount,
maccPerms,
sdk.Bech32MainPrefix,
authority.String(),
)

blockedAddresses := map[string]bool{
accountKeeper.GetAuthority(): false,
}
bankKeeper := bankkeeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
log.NewNopLogger(),
)

stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[types.StoreKey], accountKeeper, bankKeeper, authority.String())

authModule := auth.NewAppModule(cdc, accountKeeper, authsims.RandomGenesisAccounts, nil)
bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper, nil)
stakingModule := staking.NewAppModule(cdc, stakingKeeper, accountKeeper, bankKeeper, nil)

integrationApp := integration.NewIntegrationApp(newCtx, logger, keys, cdc, authModule, bankModule, stakingModule)

sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context())

// Register MsgServer and QueryServer
types.RegisterMsgServer(integrationApp.MsgServiceRouter(), stakingkeeper.NewMsgServerImpl(stakingKeeper))
types.RegisterQueryServer(integrationApp.QueryHelper(), stakingkeeper.NewQuerier(stakingKeeper))

// set default staking params
stakingKeeper.SetParams(sdkCtx, types.DefaultParams())

f := fixture{
app: integrationApp,
sdkCtx: sdkCtx,
cdc: cdc,
keys: keys,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
stakingKeeper: stakingKeeper,
}

return &f
}
76 changes: 45 additions & 31 deletions tests/integration/staking/keeper/delegation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"cosmossdk.io/math"
"gotest.tools/v3/assert"

simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
Expand All @@ -16,36 +15,51 @@ import (
)

func TestUnbondingDelegationsMaxEntries(t *testing.T) {
_, app, ctx := createTestInput(t)
t.Parallel()
f := initFixture(t)

addrDels := simtestutil.AddTestAddrsIncremental(app.BankKeeper, app.StakingKeeper, ctx, 1, sdk.NewInt(10000))
addrVals := simtestutil.ConvertAddrsToValAddrs(addrDels)
ctx := f.sdkCtx

startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
initTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, int64(1000))
f.bankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)))

bondDenom := app.StakingKeeper.BondDenom(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
addrDel := sdk.AccAddress([]byte("addr"))
accAmt := sdk.NewInt(10000)
initCoins := sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(ctx), accAmt))
if err := f.bankKeeper.MintCoins(ctx, types.ModuleName, initCoins); err != nil {
panic(err)
}

if err := f.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addrDel, initCoins); err != nil {
panic(err)
}
addrVal := sdk.ValAddress(addrDel)

startTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, 10)

bondDenom := f.stakingKeeper.BondDenom(ctx)
notBondedPool := f.stakingKeeper.GetNotBondedPool(ctx)

assert.NilError(t, banktestutil.FundModuleAccount(ctx, app.BankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
assert.NilError(t, banktestutil.FundModuleAccount(ctx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
f.accountKeeper.SetModuleAccount(ctx, notBondedPool)

// create a validator and a delegator to that validator
validator := testutil.NewValidator(t, addrVals[0], PKs[0])
validator := testutil.NewValidator(t, addrVal, PKs[0])

validator, issuedShares := validator.AddTokensFromDel(startTokens)
assert.DeepEqual(t, startTokens, issuedShares.RoundInt())

validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
validator = keeper.TestingUpdateValidator(f.stakingKeeper, ctx, validator, true)
assert.Assert(math.IntEq(t, startTokens, validator.BondedTokens()))
assert.Assert(t, validator.IsBonded())

delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares)
app.StakingKeeper.SetDelegation(ctx, delegation)
delegation := types.NewDelegation(addrDel, addrVal, issuedShares)
f.stakingKeeper.SetDelegation(ctx, delegation)

maxEntries := app.StakingKeeper.MaxEntries(ctx)
maxEntries := f.stakingKeeper.MaxEntries(ctx)

oldBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
oldBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount

// should all pass
var completionTime time.Time
Expand All @@ -54,49 +68,49 @@ func TestUnbondingDelegationsMaxEntries(t *testing.T) {
var err error
ctx = ctx.WithBlockHeight(i)
var amount math.Int
completionTime, amount, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
completionTime, amount, err = f.stakingKeeper.Undelegate(ctx, addrDel, addrVal, math.LegacyNewDec(1))
totalUnbonded = totalUnbonded.Add(amount)
assert.NilError(t, err)
}

newBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
newBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries))))
assert.Assert(math.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries))))
assert.Assert(math.IntEq(t, totalUnbonded, oldBonded.Sub(newBonded)))
assert.Assert(math.IntEq(t, totalUnbonded, newNotBonded.Sub(oldNotBonded)))

oldBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
oldBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount

// an additional unbond should fail due to max entries
_, _, err := app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
_, _, err := f.stakingKeeper.Undelegate(ctx, addrDel, addrVal, math.LegacyNewDec(1))
assert.Error(t, err, "too many unbonding delegation entries for (delegator, validator) tuple")

newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
newBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount

assert.Assert(math.IntEq(t, newBonded, oldBonded))
assert.Assert(math.IntEq(t, newNotBonded, oldNotBonded))

// mature unbonding delegations
ctx = ctx.WithBlockTime(completionTime)
_, err = app.StakingKeeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0])
_, err = f.stakingKeeper.CompleteUnbonding(ctx, addrDel, addrVal)
assert.NilError(t, err)

newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
newBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, newBonded, oldBonded))
assert.Assert(math.IntEq(t, newNotBonded, oldNotBonded.SubRaw(int64(maxEntries))))

oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount

// unbonding should work again
_, _, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
_, _, err = f.stakingKeeper.Undelegate(ctx, addrDel, addrVal, math.LegacyNewDec(1))
assert.NilError(t, err)

newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
newBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, newBonded, oldBonded.SubRaw(1)))
assert.Assert(math.IntEq(t, newNotBonded, oldNotBonded.AddRaw(1)))
}
Loading

0 comments on commit 672b1f9

Please sign in to comment.