Merge branch 'master' into jonathan/5684-prune-syncable

This commit is contained in:
Alexander Bezobchuk 2020-02-28 12:45:59 -08:00 committed by GitHub
commit db855fba07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1742 additions and 1548 deletions

2
.github/CODEOWNERS vendored
View File

@ -1,4 +1,4 @@
# CODEOWNERS: https://help.github.com/articles/about-codeowners/
# Primary repo maintainers
* @alexanderbez @jackzampolin @alessio @fedekunze
* @alexanderbez @alessio @fedekunze @nylira @hschoenburg

View File

@ -1,6 +1,10 @@
package simapp
import (
"bytes"
"encoding/hex"
"fmt"
"strconv"
"testing"
"github.com/stretchr/testify/require"
@ -77,15 +81,56 @@ func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances ..
return app
}
// AddTestAddrs constructs and returns accNum amount of accounts with an
// initial balance of accAmt
func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress {
type GenerateAccountStrategy func(int) []sdk.AccAddress
// createRandomAccounts is a strategy used by addTestAddrs() in order to generated addresses in random order.
func createRandomAccounts(accNum int) []sdk.AccAddress {
testAddrs := make([]sdk.AccAddress, accNum)
for i := 0; i < accNum; i++ {
pk := ed25519.GenPrivKey().PubKey()
testAddrs[i] = sdk.AccAddress(pk.Address())
}
return testAddrs
}
// createIncrementalAccounts is a strategy used by addTestAddrs() in order to generated addresses in ascending order.
func createIncrementalAccounts(accNum int) []sdk.AccAddress {
var addresses []sdk.AccAddress
var buffer bytes.Buffer
// start at 100 so we can make up to 999 test addresses with valid test addresses
for i := 100; i < (accNum + 100); i++ {
numString := strconv.Itoa(i)
buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string
buffer.WriteString(numString) //adding on final two digits to make addresses unique
res, _ := sdk.AccAddressFromHex(buffer.String())
bech := res.String()
addr, _ := TestAddr(buffer.String(), bech)
addresses = append(addresses, addr)
buffer.Reset()
}
return addresses
}
// AddTestAddrs constructs and returns accNum amount of accounts with an
// initial balance of accAmt in random order
func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress {
return addTestAddrs(app, ctx, accNum, accAmt, createRandomAccounts)
}
// AddTestAddrs constructs and returns accNum amount of accounts with an
// initial balance of accAmt in random order
func AddTestAddrsIncremental(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress {
return addTestAddrs(app, ctx, accNum, accAmt, createIncrementalAccounts)
}
func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int, strategy GenerateAccountStrategy) []sdk.AccAddress {
testAddrs := strategy(accNum)
initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt))
totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt.MulRaw(int64(len(testAddrs)))))
prevSupply := app.SupplyKeeper.GetSupply(ctx)
@ -104,6 +149,38 @@ func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sd
return testAddrs
}
// ConvertAddrsToValAddrs converts the provided addresses to ValAddress.
func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress {
valAddrs := make([]sdk.ValAddress, len(addrs))
for i, addr := range addrs {
valAddrs[i] = sdk.ValAddress(addr)
}
return valAddrs
}
func TestAddr(addr string, bech string) (sdk.AccAddress, error) {
res, err := sdk.AccAddressFromHex(addr)
if err != nil {
return nil, err
}
bechexpected := res.String()
if bech != bechexpected {
return nil, fmt.Errorf("bech encoding doesn't match reference")
}
bechres, err := sdk.AccAddressFromBech32(bech)
if err != nil {
return nil, err
}
if !bytes.Equal(bechres, res) {
return nil, err
}
return res, nil
}
// CheckBalance checks the balance of an account.
func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.Coins) {
ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
@ -187,3 +264,31 @@ func incrementAllSequenceNumbers(initSeqNums []uint64) {
initSeqNums[i]++
}
}
// CreateTestPubKeys returns a total of numPubKeys public keys in ascending order.
func CreateTestPubKeys(numPubKeys int) []crypto.PubKey {
var publicKeys []crypto.PubKey
var buffer bytes.Buffer
// start at 10 to avoid changing 1 to 01, 2 to 02, etc
for i := 100; i < (numPubKeys + 100); i++ {
numString := strconv.Itoa(i)
buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") // base pubkey string
buffer.WriteString(numString) // adding on final two digits to make pubkeys unique
publicKeys = append(publicKeys, NewPubKeyFromHex(buffer.String()))
buffer.Reset()
}
return publicKeys
}
// NewPubKeyFromHex returns a PubKey from a hex string.
func NewPubKeyFromHex(pk string) (res crypto.PubKey) {
pkBytes, err := hex.DecodeString(pk)
if err != nil {
panic(err)
}
var pkEd ed25519.PubKeyEd25519
copy(pkEd[:], pkBytes)
return pkEd
}

View File

@ -2,7 +2,6 @@ package version
import (
"encoding/json"
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@ -21,29 +20,31 @@ func init() {
var Cmd = &cobra.Command{
Use: "version",
Short: "Print the app version",
RunE: func(_ *cobra.Command, _ []string) error {
verInfo := NewInfo()
if !viper.GetBool(flagLong) {
fmt.Println(verInfo.Version)
return nil
}
var bz []byte
var err error
switch viper.GetString(cli.OutputFlag) {
case "json":
bz, err = json.Marshal(verInfo)
default:
bz, err = yaml.Marshal(&verInfo)
}
if err != nil {
return err
}
_, err = fmt.Println(string(bz))
return err
},
RunE: runVersionCmd,
}
func runVersionCmd(cmd *cobra.Command, args []string) error {
verInfo := NewInfo()
if !viper.GetBool(flagLong) {
cmd.Println(verInfo.Version)
return nil
}
var bz []byte
var err error
switch viper.GetString(cli.OutputFlag) {
case "json":
bz, err = json.Marshal(verInfo)
default:
bz, err = yaml.Marshal(&verInfo)
}
if err != nil {
return err
}
cmd.Println(string(bz))
return nil
}

60
version/version_test.go Normal file
View File

@ -0,0 +1,60 @@
package version
import (
"encoding/json"
"fmt"
"runtime"
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/tests"
)
func TestNewInfo(t *testing.T) {
info := NewInfo()
want := fmt.Sprintf(`:
git commit:
build tags:
%s`, fmt.Sprintf("go version %s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH))
require.Equal(t, want, info.String())
}
func TestInfo_String(t *testing.T) {
info := Info{
Name: "testapp",
ServerName: "testappd",
ClientName: "testappcli",
Version: "1.0.0",
GitCommit: "1b78457135a4104bc3af97f20654d49e2ea87454",
BuildTags: "netgo,ledger",
GoVersion: "go version go1.14 linux/amd64",
}
want := fmt.Sprintf(`testapp: 1.0.0
git commit: 1b78457135a4104bc3af97f20654d49e2ea87454
build tags: netgo,ledger
go version go1.14 linux/amd64`)
require.Equal(t, want, info.String())
}
func Test_runVersionCmd(t *testing.T) {
require.NotNil(t, Cmd)
_, mockOut, _ := tests.ApplyMockIO(Cmd)
viper.Set(cli.OutputFlag, "")
viper.Set(flagLong, false)
require.NoError(t, runVersionCmd(Cmd, nil))
assert.Equal(t, "\n", mockOut.String())
mockOut.Reset()
viper.Set(cli.OutputFlag, "json")
viper.Set(flagLong, true)
info := NewInfo()
stringInfo, err := json.Marshal(info)
require.NoError(t, err)
require.NoError(t, runVersionCmd(Cmd, nil))
assert.Equal(t, string(stringInfo)+"\n", mockOut.String())
}

View File

@ -1,12 +1,16 @@
package staking_test
import (
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp"
cdc "github.com/cosmos/cosmos-sdk/simapp/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
@ -16,16 +20,10 @@ var (
addr1 = sdk.AccAddress(priv1.PubKey().Address())
priv2 = secp256k1.GenPrivKey()
addr2 = sdk.AccAddress(priv2.PubKey().Address())
addr3 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
priv4 = secp256k1.GenPrivKey()
addr4 = sdk.AccAddress(priv4.PubKey().Address())
coins = sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(10))}
fee = auth.NewStdFee(
100000,
sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(0))},
)
commissionRates = staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
PKs = simapp.CreateTestPubKeys(500)
)
func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) staking.MsgCreateValidator {
@ -38,3 +36,31 @@ func NewTestMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk.
amount := sdk.NewCoin(sdk.DefaultBondDenom, amt)
return staking.NewMsgDelegate(delAddr, valAddr, amount)
}
// getBaseSimappWithCustomKeeper Returns a simapp with custom StakingKeeper
// to avoid messing with the hooks.
func getBaseSimappWithCustomKeeper() (*codec.Codec, *simapp.SimApp, sdk.Context) {
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, abci.Header{})
appCodec := cdc.NewAppCodec(codec.New())
app.StakingKeeper = keeper.NewKeeper(
appCodec,
app.GetKey(staking.StoreKey),
app.BankKeeper,
app.SupplyKeeper,
app.GetSubspace(staking.ModuleName),
)
app.StakingKeeper.SetParams(ctx, types.DefaultParams())
return codec.New(), app, ctx
}
// generateAddresses generates numAddrs of normal AccAddrs and ValAddrs
func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int, accAmount int64) ([]sdk.AccAddress, []sdk.ValAddress) {
addrDels := simapp.AddTestAddrsIncremental(app, ctx, numAddrs, sdk.NewInt(accAmount))
addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
return addrDels, addrVals
}

View File

@ -1,64 +1,83 @@
package staking
package staking_test
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
keep "github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/cosmos/cosmos-sdk/x/supply"
)
func bootstrapGenesisTest(t *testing.T, power int64, numAddrs int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) {
_, app, ctx := getBaseSimappWithCustomKeeper()
addrDels, addrVals := generateAddresses(app, ctx, numAddrs, 10000)
amt := sdk.TokensFromConsensusPower(power)
totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels)))))
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply)
require.NoError(t, err)
app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool)
app.SupplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
return app, ctx, addrDels, addrVals
}
func TestInitGenesis(t *testing.T) {
ctx, accKeeper, bk, keeper, supplyKeeper := keep.CreateTestInput(t, false, 1000)
app, ctx, addrs, _ := bootstrapGenesisTest(t, 1000, 10)
valTokens := sdk.TokensFromConsensusPower(1)
params := keeper.GetParams(ctx)
validators := make([]Validator, 2)
var delegations []Delegation
params := app.StakingKeeper.GetParams(ctx)
validators := make([]types.Validator, 2)
var delegations []types.Delegation
pk0, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, keep.PKs[0])
pk0, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, PKs[0])
require.NoError(t, err)
pk1, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, keep.PKs[1])
pk1, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, PKs[1])
require.NoError(t, err)
// initialize the validators
validators[0].OperatorAddress = sdk.ValAddress(keep.Addrs[0])
validators[0].OperatorAddress = sdk.ValAddress(addrs[0])
validators[0].ConsensusPubkey = pk0
validators[0].Description = NewDescription("hoop", "", "", "", "")
validators[0].Description = types.NewDescription("hoop", "", "", "", "")
validators[0].Status = sdk.Bonded
validators[0].Tokens = valTokens
validators[0].DelegatorShares = valTokens.ToDec()
validators[1].OperatorAddress = sdk.ValAddress(keep.Addrs[1])
validators[1].OperatorAddress = sdk.ValAddress(addrs[1])
validators[1].ConsensusPubkey = pk1
validators[1].Description = NewDescription("bloop", "", "", "", "")
validators[1].Description = types.NewDescription("bloop", "", "", "", "")
validators[1].Status = sdk.Bonded
validators[1].Tokens = valTokens
validators[1].DelegatorShares = valTokens.ToDec()
genesisState := types.NewGenesisState(params, validators, delegations)
vals := InitGenesis(ctx, keeper, accKeeper, bk, supplyKeeper, genesisState)
vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.SupplyKeeper, genesisState)
actualGenesis := ExportGenesis(ctx, keeper)
actualGenesis := staking.ExportGenesis(ctx, app.StakingKeeper)
require.Equal(t, genesisState.Params, actualGenesis.Params)
require.Equal(t, genesisState.Delegations, actualGenesis.Delegations)
require.EqualValues(t, keeper.GetAllValidators(ctx), actualGenesis.Validators)
require.EqualValues(t, app.StakingKeeper.GetAllValidators(ctx), actualGenesis.Validators)
// now make sure the validators are bonded and intra-tx counters are correct
resVal, found := keeper.GetValidator(ctx, sdk.ValAddress(keep.Addrs[0]))
resVal, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[0]))
require.True(t, found)
require.Equal(t, sdk.Bonded, resVal.Status)
resVal, found = keeper.GetValidator(ctx, sdk.ValAddress(keep.Addrs[1]))
resVal, found = app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[1]))
require.True(t, found)
require.Equal(t, sdk.Bonded, resVal.Status)
@ -74,15 +93,15 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
size := 200
require.True(t, size > 100)
ctx, accKeeper, bk, keeper, supplyKeeper := keep.CreateTestInput(t, false, 1000)
app, ctx, addrs, _ := bootstrapGenesisTest(t, 1000, 200)
params := keeper.GetParams(ctx)
delegations := []Delegation{}
validators := make([]Validator, size)
params := app.StakingKeeper.GetParams(ctx)
delegations := []types.Delegation{}
validators := make([]types.Validator, size)
for i := range validators {
validators[i] = NewValidator(sdk.ValAddress(keep.Addrs[i]),
keep.PKs[i], NewDescription(fmt.Sprintf("#%d", i), "", "", "", ""))
validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]),
PKs[i], types.NewDescription(fmt.Sprintf("#%d", i), "", "", "", ""))
validators[i].Status = sdk.Bonded
@ -95,7 +114,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
}
genesisState := types.NewGenesisState(params, validators, delegations)
vals := InitGenesis(ctx, keeper, accKeeper, bk, supplyKeeper, genesisState)
vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.SupplyKeeper, genesisState)
abcivals := make([]abci.ValidatorUpdate, 100)
for i, val := range validators[:100] {
@ -140,9 +159,9 @@ func TestValidateGenesis(t *testing.T) {
genesisState := types.DefaultGenesisState()
tt.mutate(&genesisState)
if tt.wantErr {
assert.Error(t, ValidateGenesis(genesisState))
assert.Error(t, staking.ValidateGenesis(genesisState))
} else {
assert.NoError(t, ValidateGenesis(genesisState))
assert.NoError(t, staking.ValidateGenesis(genesisState))
}
})
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
package keeper_test
import (
"testing"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp"
cdc "github.com/cosmos/cosmos-sdk/simapp/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
abci "github.com/tendermint/tendermint/abci/types"
)
var (
PKs = simapp.CreateTestPubKeys(500)
)
// createTestInput Returns a simapp with custom StakingKeeper
// to avoid messing with the hooks.
func createTestInput() (*codec.Codec, *simapp.SimApp, sdk.Context) {
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, abci.Header{})
appCodec := cdc.NewAppCodec(codec.New())
app.StakingKeeper = keeper.NewKeeper(
appCodec,
app.GetKey(staking.StoreKey),
app.BankKeeper,
app.SupplyKeeper,
app.GetSubspace(staking.ModuleName),
)
return codec.New(), 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 := simapp.ConvertAddrsToValAddrs(addrDels)
return addrDels, addrVals
}

View File

@ -548,7 +548,7 @@ func (k Keeper) Delegate(
}
// unbond a particular delegation and perform associated store operations
func (k Keeper) unbond(
func (k Keeper) Unbond(
ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec,
) (amount sdk.Int, err error) {
@ -654,7 +654,7 @@ func (k Keeper) Undelegate(
return time.Time{}, types.ErrMaxUnbondingDelegationEntries
}
returnAmount, err := k.unbond(ctx, delAddr, valAddr, sharesAmount)
returnAmount, err := k.Unbond(ctx, delAddr, valAddr, sharesAmount)
if err != nil {
return time.Time{}, err
}
@ -751,7 +751,7 @@ func (k Keeper) BeginRedelegation(
return time.Time{}, types.ErrMaxRedelegationEntries
}
returnAmount, err := k.unbond(ctx, delAddr, valSrcAddr, sharesAmount)
returnAmount, err := k.Unbond(ctx, delAddr, valSrcAddr, sharesAmount)
if err != nil {
return time.Time{}, err
}

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,13 @@
package keeper
package keeper_test
import (
"sort"
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/stretchr/testify/require"
@ -12,7 +15,11 @@ import (
)
func TestHistoricalInfo(t *testing.T) {
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10)
_, app, ctx := createTestInput()
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0))
addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
validators := make([]types.Validator, len(addrVals))
for i, valAddr := range addrVals {
@ -21,27 +28,30 @@ func TestHistoricalInfo(t *testing.T) {
hi := types.NewHistoricalInfo(ctx.BlockHeader(), validators)
keeper.SetHistoricalInfo(ctx, 2, hi)
app.StakingKeeper.SetHistoricalInfo(ctx, 2, hi)
recv, found := keeper.GetHistoricalInfo(ctx, 2)
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, sort.IsSorted(types.Validators(recv.Valset)), "HistoricalInfo validators is not sorted")
keeper.DeleteHistoricalInfo(ctx, 2)
app.StakingKeeper.DeleteHistoricalInfo(ctx, 2)
recv, found = keeper.GetHistoricalInfo(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")
}
func TestTrackHistoricalInfo(t *testing.T) {
ctx, _, _, k, _ := CreateTestInput(t, false, 10)
_, app, ctx := createTestInput()
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0))
addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
// set historical entries in params to 5
params := types.DefaultParams()
params.HistoricalEntries = 5
k.SetParams(ctx, params)
app.StakingKeeper.SetParams(ctx, params)
// set historical info at 5, 4 which should be pruned
// and check that it has been stored
@ -54,29 +64,29 @@ func TestTrackHistoricalInfo(t *testing.T) {
Height: 5,
}
valSet := []types.Validator{
types.NewValidator(sdk.ValAddress(Addrs[0]), PKs[0], types.Description{}),
types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}),
types.NewValidator(addrVals[0], PKs[0], types.Description{}),
types.NewValidator(addrVals[1], PKs[1], types.Description{}),
}
hi4 := types.NewHistoricalInfo(h4, valSet)
hi5 := types.NewHistoricalInfo(h5, valSet)
k.SetHistoricalInfo(ctx, 4, hi4)
k.SetHistoricalInfo(ctx, 5, hi5)
recv, found := k.GetHistoricalInfo(ctx, 4)
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 = k.GetHistoricalInfo(ctx, 5)
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 5)
require.True(t, found)
require.Equal(t, hi5, recv)
// Set last validators in keeper
val1 := types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{})
k.SetValidator(ctx, val1)
k.SetLastValidatorPower(ctx, val1.OperatorAddress, 10)
val2 := types.NewValidator(sdk.ValAddress(Addrs[3]), PKs[3], types.Description{})
val1 := types.NewValidator(addrVals[2], PKs[2], types.Description{})
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetLastValidatorPower(ctx, val1.OperatorAddress, 10)
val2 := types.NewValidator(addrVals[3], PKs[3], types.Description{})
vals := []types.Validator{val1, val2}
sort.Sort(types.Validators(vals))
k.SetValidator(ctx, val2)
k.SetLastValidatorPower(ctx, val2.OperatorAddress, 8)
app.StakingKeeper.SetValidator(ctx, val2)
app.StakingKeeper.SetLastValidatorPower(ctx, val2.OperatorAddress, 8)
// Set Header for BeginBlock context
header := abci.Header{
@ -85,22 +95,22 @@ func TestTrackHistoricalInfo(t *testing.T) {
}
ctx = ctx.WithBlockHeader(header)
k.TrackHistoricalInfo(ctx)
app.StakingKeeper.TrackHistoricalInfo(ctx)
// Check HistoricalInfo at height 10 is persisted
expected := types.HistoricalInfo{
Header: header,
Valset: vals,
}
recv, found = k.GetHistoricalInfo(ctx, 10)
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 10)
require.True(t, found, "GetHistoricalInfo failed after BeginBlock")
require.Equal(t, expected, recv, "GetHistoricalInfo returned eunexpected result")
// Check HistoricalInfo at height 5, 4 is pruned
recv, found = k.GetHistoricalInfo(ctx, 4)
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 = k.GetHistoricalInfo(ctx, 5)
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")
}

View File

@ -37,6 +37,10 @@ func NewKeeper(
cdc codec.Marshaler, key sdk.StoreKey, bk types.BankKeeper, sk types.SupplyKeeper, ps paramtypes.Subspace,
) Keeper {
if !ps.HasKeyTable() {
ps = ps.WithKeyTable(ParamKeyTable())
}
// ensure bonded and not bonded module accounts are set
if addr := sk.GetModuleAddress(types.BondedPoolName); addr == nil {
panic(fmt.Sprintf("%s module account has not been set", types.BondedPoolName))
@ -51,7 +55,7 @@ func NewKeeper(
cdc: cdc,
bankKeeper: bk,
supplyKeeper: sk,
paramstore: ps.WithKeyTable(ParamKeyTable()),
paramstore: ps,
hooks: nil,
validatorCache: make(map[string]cachedValidator, aminoCacheSize),
validatorCacheList: list.New(),

View File

@ -1,24 +1,28 @@
package keeper
package keeper_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/x/staking/types"
abci "github.com/tendermint/tendermint/abci/types"
)
func TestParams(t *testing.T) {
ctx, _, _, keeper, _ := CreateTestInput(t, false, 0)
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, abci.Header{})
expParams := types.DefaultParams()
//check that the empty keeper loads the default
resParams := keeper.GetParams(ctx)
resParams := app.StakingKeeper.GetParams(ctx)
require.True(t, expParams.Equal(resParams))
//modify a params, save, and retrieve
expParams.MaxValidators = 777
keeper.SetParams(ctx, expParams)
resParams = keeper.GetParams(ctx)
app.StakingKeeper.SetParams(ctx, expParams)
resParams = app.StakingKeeper.GetParams(ctx)
require.True(t, expParams.Equal(resParams))
}

View File

@ -1,34 +1,34 @@
package keeper
package keeper_test
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
var (
addrAcc1, addrAcc2 = Addrs[0], Addrs[1]
addrVal1, addrVal2 = sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1])
pk1, pk2 = PKs[0], PKs[1]
)
func TestNewQuerier(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000)
cdc, app, ctx := createTestInput()
addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.NewInt(10000))
_, addrAcc2 := addrs[0], addrs[1]
addrVal1, _ := sdk.ValAddress(addrs[0]), sdk.ValAddress(addrs[1])
// Create Validators
amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8)}
var validators [2]types.Validator
for i, amt := range amts {
validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{})
validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{})
validators[i], _ = validators[i].AddTokensFromDel(amt)
keeper.SetValidator(ctx, validators[i])
keeper.SetValidatorByPowerIndex(ctx, validators[i])
app.StakingKeeper.SetValidator(ctx, validators[i])
app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i])
}
header := abci.Header{
@ -36,14 +36,14 @@ func TestNewQuerier(t *testing.T) {
Height: 5,
}
hi := types.NewHistoricalInfo(header, validators[:])
keeper.SetHistoricalInfo(ctx, 5, hi)
app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi)
query := abci.RequestQuery{
Path: "",
Data: []byte{},
}
querier := NewQuerier(keeper)
querier := staking.NewQuerier(app.StakingKeeper)
bz, err := querier(ctx, []string{"other"}, query)
require.Error(t, err)
@ -106,50 +106,54 @@ func TestNewQuerier(t *testing.T) {
}
func TestQueryParametersPool(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000)
cdc, app, ctx := createTestInput()
querier := staking.NewQuerier(app.StakingKeeper)
bondDenom := sdk.DefaultBondDenom
res, err := queryParameters(ctx, keeper)
res, err := querier(ctx, []string{staking.QueryParameters}, abci.RequestQuery{})
require.NoError(t, err)
var params types.Params
errRes := cdc.UnmarshalJSON(res, &params)
require.NoError(t, errRes)
require.Equal(t, keeper.GetParams(ctx), params)
require.Equal(t, app.StakingKeeper.GetParams(ctx), params)
res, err = queryPool(ctx, keeper)
res, err = querier(ctx, []string{staking.QueryPool}, abci.RequestQuery{})
require.NoError(t, err)
var pool types.Pool
bondedPool := keeper.GetBondedPool(ctx)
notBondedPool := keeper.GetNotBondedPool(ctx)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
require.NoError(t, cdc.UnmarshalJSON(res, &pool))
require.Equal(t, keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, pool.NotBondedTokens)
require.Equal(t, keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, pool.BondedTokens)
require.Equal(t, app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, pool.NotBondedTokens)
require.Equal(t, app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, pool.BondedTokens)
}
func TestQueryValidators(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
params := keeper.GetParams(ctx)
cdc, app, ctx := createTestInput()
params := app.StakingKeeper.GetParams(ctx)
querier := staking.NewQuerier(app.StakingKeeper)
addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.TokensFromConsensusPower(10000))
// Create Validators
amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)}
status := []sdk.BondStatus{sdk.Bonded, sdk.Unbonded, sdk.Unbonding}
var validators [3]types.Validator
for i, amt := range amts {
validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{})
validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{})
validators[i], _ = validators[i].AddTokensFromDel(amt)
validators[i] = validators[i].UpdateStatus(status[i])
}
keeper.SetValidator(ctx, validators[0])
keeper.SetValidator(ctx, validators[1])
keeper.SetValidator(ctx, validators[2])
app.StakingKeeper.SetValidator(ctx, validators[0])
app.StakingKeeper.SetValidator(ctx, validators[1])
app.StakingKeeper.SetValidator(ctx, validators[2])
// Query Validators
queriedValidators := keeper.GetValidators(ctx, params.MaxValidators)
queriedValidators := app.StakingKeeper.GetValidators(ctx, params.MaxValidators)
require.Len(t, queriedValidators, 3)
for i, s := range status {
queryValsParams := types.NewQueryValidatorsParams(1, int(params.MaxValidators), s.String())
@ -161,7 +165,7 @@ func TestQueryValidators(t *testing.T) {
Data: bz,
}
res, err := queryValidators(ctx, req, keeper)
res, err := querier(ctx, []string{types.QueryValidators}, req)
require.NoError(t, err)
var validatorsResp []types.Validator
@ -170,47 +174,56 @@ func TestQueryValidators(t *testing.T) {
require.Equal(t, 1, len(validatorsResp))
require.ElementsMatch(t, validators[i].OperatorAddress, validatorsResp[0].OperatorAddress)
}
// Query each validator
queryParams := types.NewQueryValidatorParams(addrVal1)
bz, err := cdc.MarshalJSON(queryParams)
require.NoError(t, err)
for _, validator := range validators {
queryParams := types.NewQueryValidatorParams(validator.OperatorAddress)
bz, err := cdc.MarshalJSON(queryParams)
require.NoError(t, err)
query := abci.RequestQuery{
Path: "/custom/staking/validator",
Data: bz,
query := abci.RequestQuery{
Path: "/custom/staking/validator",
Data: bz,
}
res, err := querier(ctx, []string{types.QueryValidator}, query)
require.NoError(t, err)
var queriedValidator types.Validator
err = cdc.UnmarshalJSON(res, &queriedValidator)
require.NoError(t, err)
require.Equal(t, validator, queriedValidator)
}
res, err := queryValidator(ctx, query, keeper)
require.NoError(t, err)
var validator types.Validator
err = cdc.UnmarshalJSON(res, &validator)
require.NoError(t, err)
require.Equal(t, queriedValidators[0], validator)
}
func TestQueryDelegation(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
params := keeper.GetParams(ctx)
cdc, app, ctx := createTestInput()
params := app.StakingKeeper.GetParams(ctx)
querier := staking.NewQuerier(app.StakingKeeper)
addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000))
addrAcc1, addrAcc2 := addrs[0], addrs[1]
addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2)
pubKeys := simapp.CreateTestPubKeys(2)
pk1, pk2 := pubKeys[0], pubKeys[1]
// Create Validators and Delegation
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
keeper.SetValidator(ctx, val1)
keeper.SetValidatorByPowerIndex(ctx, val1)
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetValidatorByPowerIndex(ctx, val1)
val2 := types.NewValidator(addrVal2, pk2, types.Description{})
keeper.SetValidator(ctx, val2)
keeper.SetValidatorByPowerIndex(ctx, val2)
app.StakingKeeper.SetValidator(ctx, val2)
app.StakingKeeper.SetValidatorByPowerIndex(ctx, val2)
delTokens := sdk.TokensFromConsensusPower(20)
keeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true)
_, err := app.StakingKeeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true)
require.NoError(t, err)
// apply TM updates
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
// Query Delegator bonded validators
queryParams := types.NewQueryDelegatorParams(addrAcc2)
@ -222,9 +235,9 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
delValidators := keeper.GetDelegatorValidators(ctx, addrAcc2, params.MaxValidators)
delValidators := app.StakingKeeper.GetDelegatorValidators(ctx, addrAcc2, params.MaxValidators)
res, err := queryDelegatorValidators(ctx, query, keeper)
res, err := querier(ctx, []string{types.QueryDelegatorValidators}, query)
require.NoError(t, err)
var validatorsResp []types.Validator
@ -237,7 +250,7 @@ func TestQueryDelegation(t *testing.T) {
// error unknown request
query.Data = bz[:len(bz)-1]
_, err = queryDelegatorValidators(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryDelegatorValidators}, query)
require.Error(t, err)
// Query bonded validator
@ -250,7 +263,7 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
res, err = queryDelegatorValidator(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegatorValidator}, query)
require.NoError(t, err)
var validator types.Validator
@ -262,7 +275,7 @@ func TestQueryDelegation(t *testing.T) {
// error unknown request
query.Data = bz[:len(bz)-1]
_, err = queryDelegatorValidator(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryDelegatorValidator}, query)
require.Error(t, err)
// Query delegation
@ -272,10 +285,10 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
delegation, found := keeper.GetDelegation(ctx, addrAcc2, addrVal1)
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc2, addrVal1)
require.True(t, found)
res, err = queryDelegation(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegation}, query)
require.NoError(t, err)
var delegationRes types.DelegationResponse
@ -292,7 +305,7 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
res, err = queryDelegatorDelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegatorDelegations}, query)
require.NoError(t, err)
var delegatorDelegations types.DelegationResponses
@ -306,11 +319,10 @@ func TestQueryDelegation(t *testing.T) {
// error unknown request
query.Data = bz[:len(bz)-1]
_, err = queryDelegation(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryDelegation}, query)
require.Error(t, err)
// Query validator delegations
bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1))
require.NoError(t, errRes)
@ -319,7 +331,7 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
res, err = queryValidatorDelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryValidatorDelegations}, query)
require.NoError(t, err)
var delegationsRes types.DelegationResponses
@ -330,9 +342,9 @@ func TestQueryDelegation(t *testing.T) {
require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress)
require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance)
// Query unbonging delegation
// Query unbonding delegation
unbondingTokens := sdk.TokensFromConsensusPower(10)
_, err = keeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec())
_, err = app.StakingKeeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec())
require.NoError(t, err)
queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1)
@ -344,10 +356,10 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
unbond, found := keeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1)
unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1)
require.True(t, found)
res, err = queryUnbondingDelegation(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query)
require.NoError(t, err)
var unbondRes types.UnbondingDelegation
@ -359,7 +371,7 @@ func TestQueryDelegation(t *testing.T) {
// error unknown request
query.Data = bz[:len(bz)-1]
_, err = queryUnbondingDelegation(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query)
require.Error(t, err)
// Query Delegator Delegations
@ -369,7 +381,7 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
require.NoError(t, err)
var delegatorUbds []types.UnbondingDelegation
@ -380,15 +392,15 @@ func TestQueryDelegation(t *testing.T) {
// error unknown request
query.Data = bz[:len(bz)-1]
_, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
require.Error(t, err)
// Query redelegation
redelegationTokens := sdk.TokensFromConsensusPower(10)
_, err = keeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress,
_, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress,
val2.OperatorAddress, redelegationTokens.ToDec())
require.NoError(t, err)
redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress)
redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress)
require.True(t, found)
bz, errRes = cdc.MarshalJSON(types.NewQueryRedelegationParams(addrAcc2, val1.OperatorAddress, val2.OperatorAddress))
@ -399,7 +411,7 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
res, err = queryRedelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryRedelegations}, query)
require.NoError(t, err)
var redelRes types.RedelegationResponses
@ -413,24 +425,28 @@ func TestQueryDelegation(t *testing.T) {
}
func TestQueryRedelegations(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
cdc, app, ctx := createTestInput()
querier := staking.NewQuerier(app.StakingKeeper)
addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000))
addrAcc1, addrAcc2 := addrs[0], addrs[1]
addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2)
// Create Validators and Delegation
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
val2 := types.NewValidator(addrVal2, pk2, types.Description{})
keeper.SetValidator(ctx, val1)
keeper.SetValidator(ctx, val2)
val1 := types.NewValidator(addrVal1, PKs[0], types.Description{})
val2 := types.NewValidator(addrVal2, PKs[1], types.Description{})
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetValidator(ctx, val2)
delAmount := sdk.TokensFromConsensusPower(100)
keeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true)
_ = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true)
_ = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
rdAmount := sdk.TokensFromConsensusPower(20)
keeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec())
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec())
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress)
redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress)
require.True(t, found)
// delegator redelegations
@ -443,7 +459,7 @@ func TestQueryRedelegations(t *testing.T) {
Data: bz,
}
res, err := queryRedelegations(ctx, query, keeper)
res, err := querier(ctx, []string{types.QueryRedelegations}, query)
require.NoError(t, err)
var redelRes types.RedelegationResponses
@ -465,7 +481,7 @@ func TestQueryRedelegations(t *testing.T) {
Data: bz,
}
res, err = queryRedelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryRedelegations}, query)
require.NoError(t, err)
errRes = cdc.UnmarshalJSON(res, &redelRes)
@ -478,26 +494,30 @@ func TestQueryRedelegations(t *testing.T) {
}
func TestQueryUnbondingDelegation(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
cdc, app, ctx := createTestInput()
querier := staking.NewQuerier(app.StakingKeeper)
addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000))
addrAcc1, addrAcc2 := addrs[0], addrs[1]
addrVal1 := sdk.ValAddress(addrAcc1)
// Create Validators and Delegation
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
keeper.SetValidator(ctx, val1)
val1 := types.NewValidator(addrVal1, PKs[0], types.Description{})
app.StakingKeeper.SetValidator(ctx, val1)
// delegate
delAmount := sdk.TokensFromConsensusPower(100)
_, err := keeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true)
_, err := app.StakingKeeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true)
require.NoError(t, err)
_ = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
_ = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
// undelegate
undelAmount := sdk.TokensFromConsensusPower(20)
_, err = keeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec())
_, err = app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec())
require.NoError(t, err)
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
_, found := keeper.GetUnbondingDelegation(ctx, addrAcc1, val1.OperatorAddress)
_, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc1, val1.OperatorAddress)
require.True(t, found)
//
@ -510,7 +530,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
Path: "/custom/staking/unbondingDelegation",
Data: bz,
}
res, err := queryUnbondingDelegation(ctx, query, keeper)
res, err := querier(ctx, []string{types.QueryUnbondingDelegation}, query)
require.NoError(t, err)
require.NotNil(t, res)
var ubDel types.UnbondingDelegation
@ -529,7 +549,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
Path: "/custom/staking/unbondingDelegation",
Data: bz,
}
_, err = queryUnbondingDelegation(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query)
require.Error(t, err)
//
@ -542,7 +562,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
Path: "/custom/staking/delegatorUnbondingDelegations",
Data: bz,
}
res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
require.NoError(t, err)
require.NotNil(t, res)
var ubDels []types.UnbondingDelegation
@ -561,7 +581,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
Path: "/custom/staking/delegatorUnbondingDelegations",
Data: bz,
}
res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
require.NoError(t, err)
require.NotNil(t, res)
require.NoError(t, cdc.UnmarshalJSON(res, &ubDels))
@ -569,22 +589,26 @@ func TestQueryUnbondingDelegation(t *testing.T) {
}
func TestQueryHistoricalInfo(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
cdc, app, ctx := createTestInput()
querier := staking.NewQuerier(app.StakingKeeper)
addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000))
addrAcc1, addrAcc2 := addrs[0], addrs[1]
addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2)
// Create Validators and Delegation
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
val2 := types.NewValidator(addrVal2, pk2, types.Description{})
val1 := types.NewValidator(addrVal1, PKs[0], types.Description{})
val2 := types.NewValidator(addrVal2, PKs[1], types.Description{})
vals := []types.Validator{val1, val2}
keeper.SetValidator(ctx, val1)
keeper.SetValidator(ctx, val2)
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetValidator(ctx, val2)
header := abci.Header{
ChainID: "HelloChain",
Height: 5,
}
hi := types.NewHistoricalInfo(header, vals)
keeper.SetHistoricalInfo(ctx, 5, hi)
app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi)
queryHistoricalParams := types.NewQueryHistoricalInfoParams(4)
bz, errRes := cdc.MarshalJSON(queryHistoricalParams)
@ -593,7 +617,7 @@ func TestQueryHistoricalInfo(t *testing.T) {
Path: "/custom/staking/historicalInfo",
Data: bz,
}
res, err := queryHistoricalInfo(ctx, query, keeper)
res, err := querier(ctx, []string{types.QueryHistoricalInfo}, query)
require.Error(t, err, "Invalid query passed")
require.Nil(t, res, "Invalid query returned non-nil result")
@ -601,7 +625,7 @@ func TestQueryHistoricalInfo(t *testing.T) {
bz, errRes = cdc.MarshalJSON(queryHistoricalParams)
require.NoError(t, errRes)
query.Data = bz
res, err = queryHistoricalInfo(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryHistoricalInfo}, query)
require.NoError(t, err, "Valid query passed")
require.NotNil(t, res, "Valid query returned nil result")

View File

@ -82,7 +82,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
// Iterate through unbonding delegations from slashed validator
unbondingDelegations := k.GetUnbondingDelegationsFromValidator(ctx, operatorAddress)
for _, unbondingDelegation := range unbondingDelegations {
amountSlashed := k.slashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor)
amountSlashed := k.SlashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor)
if amountSlashed.IsZero() {
continue
}
@ -92,7 +92,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
// Iterate through redelegations from slashed source validator
redelegations := k.GetRedelegationsFromSrcValidator(ctx, operatorAddress)
for _, redelegation := range redelegations {
amountSlashed := k.slashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor)
amountSlashed := k.SlashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor)
if amountSlashed.IsZero() {
continue
}
@ -160,7 +160,7 @@ func (k Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress) {
// the unbonding delegation had enough stake to slash
// (the amount actually slashed may be less if there's
// insufficient stake remaining)
func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation types.UnbondingDelegation,
func (k Keeper) SlashUnbondingDelegation(ctx sdk.Context, unbondingDelegation types.UnbondingDelegation,
infractionHeight int64, slashFactor sdk.Dec) (totalSlashAmount sdk.Int) {
now := ctx.BlockHeader().Time
@ -215,7 +215,7 @@ func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation ty
// (the amount actually slashed may be less if there's
// insufficient stake remaining)
// NOTE this is only slashing for prior infractions from the source validator
func (k Keeper) slashRedelegation(ctx sdk.Context, srcValidator types.Validator, redelegation types.Redelegation,
func (k Keeper) SlashRedelegation(ctx sdk.Context, srcValidator types.Validator, redelegation types.Redelegation,
infractionHeight int64, slashFactor sdk.Dec) (totalSlashAmount sdk.Int) {
now := ctx.BlockHeader().Time
@ -254,7 +254,7 @@ func (k Keeper) slashRedelegation(ctx sdk.Context, srcValidator types.Validator,
sharesToUnbond = delegation.Shares
}
tokensToBurn, err := k.unbond(ctx, redelegation.DelegatorAddress, redelegation.ValidatorDstAddress, sharesToUnbond)
tokensToBurn, err := k.Unbond(ctx, redelegation.DelegatorAddress, redelegation.ValidatorDstAddress, sharesToUnbond)
if err != nil {
panic(fmt.Errorf("error unbonding delegator: %v", err))
}

View File

@ -1,72 +1,83 @@
package keeper
package keeper_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/assert"
"github.com/cosmos/cosmos-sdk/x/supply"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/cosmos/cosmos-sdk/simapp"
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/stretchr/testify/require"
)
// TODO integrate with test_common.go helper (CreateTestInput)
// setup helper function - creates two validators
func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) {
// setup
ctx, _, _, keeper, _ := CreateTestInput(t, false, power)
params := keeper.GetParams(ctx)
numVals := int64(3)
// 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()
addrDels, addrVals := generateAddresses(app, ctx, 100)
amt := sdk.TokensFromConsensusPower(power)
bondedCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), amt.MulRaw(numVals)))
totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels)))))
bondedPool := keeper.GetBondedPool(ctx)
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedCoins))
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply)
require.NoError(t, err)
app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool)
numVals := int64(3)
bondedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(numVals)))
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedCoins)
require.NoError(t, err)
app.SupplyKeeper.SetModuleAccount(ctx, bondedPool)
app.SupplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
// add numVals validators
for i := int64(0); i < numVals; i++ {
validator := types.NewValidator(addrVals[i], PKs[i], types.Description{})
validator, _ = validator.AddTokensFromDel(amt)
validator = TestingUpdateValidator(keeper, ctx, validator, true)
keeper.SetValidatorByConsAddr(ctx, validator)
validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
}
return ctx, keeper, params
return app, ctx, addrDels, addrVals
}
//_________________________________________________________________________________
// tests Jail, Unjail
func TestRevocation(t *testing.T) {
// setup
ctx, keeper, _ := setupHelper(t, 10)
addr := addrVals[0]
app, ctx, _, addrVals := bootstrapSlashTest(t, 5)
consAddr := sdk.ConsAddress(PKs[0].Address())
// initial state
val, found := keeper.GetValidator(ctx, addr)
val, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
require.True(t, found)
require.False(t, val.IsJailed())
// test jail
keeper.Jail(ctx, consAddr)
val, found = keeper.GetValidator(ctx, addr)
app.StakingKeeper.Jail(ctx, consAddr)
val, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
require.True(t, found)
require.True(t, val.IsJailed())
// test unjail
keeper.Unjail(ctx, consAddr)
val, found = keeper.GetValidator(ctx, addr)
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) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
fraction := sdk.NewDecWithPrec(5, 1)
// set an unbonding delegation with expiration timestamp (beyond which the
@ -74,26 +85,26 @@ func TestSlashUnbondingDelegation(t *testing.T) {
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0,
time.Unix(5, 0), sdk.NewInt(10))
keeper.SetUnbondingDelegation(ctx, ubd)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
// unbonding started prior to the infraction height, stakw didn't contribute
slashAmount := keeper.slashUnbondingDelegation(ctx, ubd, 1, fraction)
slashAmount := app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 1, fraction)
require.Equal(t, int64(0), slashAmount.Int64())
// after the expiration time, no longer eligible for slashing
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
keeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction)
require.Equal(t, int64(0), slashAmount.Int64())
// test valid slash, before expiration timestamp and to which stake contributed
notBondedPool := keeper.GetNotBondedPool(ctx)
oldUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
oldUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
keeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction)
require.Equal(t, int64(5), slashAmount.Int64())
ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
ubd, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
require.True(t, found)
require.Len(t, ubd.Entries, 1)
@ -102,153 +113,157 @@ func TestSlashUnbondingDelegation(t *testing.T) {
// balance decreased
require.Equal(t, sdk.NewInt(5), ubd.Entries[0].Balance)
newUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
newUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances)
require.Equal(t, int64(5), diffTokens.AmountOf(keeper.BondDenom(ctx)).Int64())
require.Equal(t, int64(5), diffTokens.AmountOf(app.StakingKeeper.BondDenom(ctx)).Int64())
}
// tests slashRedelegation
func TestSlashRedelegation(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
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(keeper.BondDenom(ctx), 15))
bondedPool := keeper.GetBondedPool(ctx)
balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
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, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(startCoins...)))
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
require.NoError(t, app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(startCoins...)))
app.SupplyKeeper.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), sdk.NewDec(10))
keeper.SetRedelegation(ctx, rd)
app.StakingKeeper.SetRedelegation(ctx, rd)
// set the associated delegation
del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDec(10))
keeper.SetDelegation(ctx, del)
app.StakingKeeper.SetDelegation(ctx, del)
// started redelegating prior to the current height, stake didn't contribute to infraction
validator, found := keeper.GetValidator(ctx, addrVals[1])
validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[1])
require.True(t, found)
slashAmount := keeper.slashRedelegation(ctx, validator, rd, 1, fraction)
slashAmount := app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 1, fraction)
require.Equal(t, int64(0), slashAmount.Int64())
// after the expiration time, no longer eligible for slashing
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
keeper.SetRedelegation(ctx, rd)
validator, found = keeper.GetValidator(ctx, addrVals[1])
app.StakingKeeper.SetRedelegation(ctx, rd)
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
require.True(t, found)
slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction)
slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction)
require.Equal(t, int64(0), slashAmount.Int64())
balances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
balances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
// test valid slash, before expiration timestamp and to which stake contributed
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
keeper.SetRedelegation(ctx, rd)
validator, found = keeper.GetValidator(ctx, addrVals[1])
app.StakingKeeper.SetRedelegation(ctx, rd)
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
require.True(t, found)
slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction)
slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction)
require.Equal(t, int64(5), slashAmount.Int64())
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
require.True(t, found)
require.Len(t, rd.Entries, 1)
// end block
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
require.Equal(t, 1, len(updates))
// initialbalance unchanged
require.Equal(t, sdk.NewInt(10), rd.Entries[0].InitialBalance)
// shares decreased
del, found = keeper.GetDelegation(ctx, addrDels[0], addrVals[1])
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(keeper.BondDenom(ctx), slashAmount))
require.Equal(t, balances.Sub(burnedCoins), keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()))
burnedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), slashAmount))
require.Equal(t, balances.Sub(burnedCoins), app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()))
}
// tests Slash at a future height (must panic)
func TestSlashAtFutureHeight(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, _, _ := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
require.Panics(t, func() { keeper.Slash(ctx, consAddr, 1, 10, fraction) })
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) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, _, _ := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondedPool := keeper.GetBondedPool(ctx)
oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
keeper.Slash(ctx, consAddr, -2, 10, fraction)
app.StakingKeeper.Slash(ctx, consAddr, -2, 10, fraction)
// read updated state
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// end block
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates)
validator = keeper.mustGetValidator(ctx, validator.OperatorAddress)
validator, found = app.StakingKeeper.GetValidator(ctx, validator.OperatorAddress)
require.True(t, found)
// power decreased
require.Equal(t, int64(5), validator.GetConsensusPower())
// pool bonded shares decreased
newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String())
}
// tests Slash at the current height
func TestSlashValidatorAtCurrentHeight(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, _, _ := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondedPool := keeper.GetBondedPool(ctx)
oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
keeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction)
app.StakingKeeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction)
// read updated state
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// end block
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates)
validator = keeper.mustGetValidator(ctx, validator.OperatorAddress)
validator, found = app.StakingKeeper.GetValidator(ctx, validator.OperatorAddress)
assert.True(t, found)
// power decreased
require.Equal(t, int64(5), validator.GetConsensusPower())
// pool bonded shares decreased
newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String())
}
// tests Slash at a previous height with an unbonding delegation
func TestSlashWithUnbondingDelegation(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
@ -257,23 +272,23 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
ubdTokens := sdk.TokensFromConsensusPower(4)
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
time.Unix(0, 0), ubdTokens)
keeper.SetUnbondingDelegation(ctx, ubd)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
// slash validator for the first time
ctx = ctx.WithBlockHeight(12)
bondedPool := keeper.GetBondedPool(ctx)
oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
keeper.Slash(ctx, consAddr, 10, 10, fraction)
app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction)
// end block
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
require.Equal(t, 1, len(updates))
// read updating unbonding delegation
ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
require.True(t, found)
require.Len(t, ubd.Entries, 1)
@ -281,12 +296,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
require.Equal(t, sdk.TokensFromConsensusPower(2), ubd.Entries[0].Balance)
// bonded tokens burned
newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(3), diffTokens)
// read updated validator
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// power decreased by 3 - 6 stake originally bonded at the time of infraction
@ -297,9 +312,9 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
// slash validator again
ctx = ctx.WithBlockHeight(13)
keeper.Slash(ctx, consAddr, 9, 10, fraction)
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
require.True(t, found)
require.Len(t, ubd.Entries, 1)
@ -307,12 +322,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
// bonded tokens burned again
newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(6), diffTokens)
// read updated validator
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// power decreased by 3 again
@ -323,9 +338,9 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
// 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)
keeper.Slash(ctx, consAddr, 9, 10, fraction)
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
require.True(t, found)
require.Len(t, ubd.Entries, 1)
@ -333,12 +348,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
// bonded tokens burned again
newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(9), diffTokens)
// read updated validator
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// power decreased by 3 again
@ -349,9 +364,9 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
// 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)
keeper.Slash(ctx, consAddr, 9, 10, fraction)
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
require.True(t, found)
require.Len(t, ubd.Entries, 1)
@ -359,76 +374,77 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
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 = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(10), diffTokens)
// apply TM updates
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
// read updated validator
// power decreased by 1 again, validator is out of stake
// validator should be in unbonding period
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
}
//_________________________________________________________________________________
// tests Slash at a previous height with a redelegation
func TestSlashWithRedelegation(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondDenom := keeper.BondDenom(ctx)
bondDenom := app.StakingKeeper.BondDenom(ctx)
// set a redelegation
rdTokens := sdk.TokensFromConsensusPower(6)
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11,
time.Unix(0, 0), rdTokens, rdTokens.ToDec())
keeper.SetRedelegation(ctx, rd)
app.StakingKeeper.SetRedelegation(ctx, rd)
// set the associated delegation
del := types.NewDelegation(addrDels[0], addrVals[1], rdTokens.ToDec())
keeper.SetDelegation(ctx, del)
app.StakingKeeper.SetDelegation(ctx, del)
// update bonded tokens
bondedPool := keeper.GetBondedPool(ctx)
notBondedPool := keeper.GetNotBondedPool(ctx)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
rdCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdTokens.MulRaw(2)))
balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
err := keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(rdCoins...))
balances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
err := app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(rdCoins...))
require.NoError(t, err)
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
app.SupplyKeeper.SetModuleAccount(ctx, bondedPool)
oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
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 := keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, fraction) })
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction) })
burnAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt()
bondedPool = keeper.GetBondedPool(ctx)
notBondedPool = keeper.GetNotBondedPool(ctx)
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
// burn bonded tokens from only from delegations
bondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
notBondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
// read updating redelegation
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
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 = keeper.GetValidatorByConsAddr(ctx, consAddr)
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
@ -437,102 +453,102 @@ func TestSlashWithRedelegation(t *testing.T) {
require.Equal(t, int64(8), validator.GetConsensusPower())
// slash the validator again
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
burnAmount = sdk.TokensFromConsensusPower(7)
// read updated pool
bondedPool = keeper.GetBondedPool(ctx)
notBondedPool = keeper.GetNotBondedPool(ctx)
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
// seven bonded tokens burned
bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
// read updating redelegation
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
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 = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// power decreased by 4
require.Equal(t, int64(4), validator.GetConsensusPower())
// slash the validator again, by 100%
ctx = ctx.WithBlockHeight(12)
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
burnAmount = sdk.TokensFromConsensusPower(10).ToDec().Mul(sdk.OneDec()).TruncateInt()
burnAmount = burnAmount.Sub(sdk.OneDec().MulInt(rdTokens).TruncateInt())
// read updated pool
bondedPool = keeper.GetBondedPool(ctx)
notBondedPool = keeper.GetNotBondedPool(ctx)
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
// read updating redelegation
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
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
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
// read updated validator
// validator decreased to zero power, should be in unbonding period
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
// slash the validator again, by 100%
// no stake remains to be slashed
ctx = ctx.WithBlockHeight(12)
// validator still in unbonding period
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
// read updated pool
bondedPool = keeper.GetBondedPool(ctx)
notBondedPool = keeper.GetNotBondedPool(ctx)
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldBonded, bondedPoolBalance))
notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
// read updating redelegation
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
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, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
}
// tests Slash at a previous height with both an unbonding delegation and a redelegation
func TestSlashBoth(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
fraction := sdk.NewDecWithPrec(5, 1)
bondDenom := keeper.BondDenom(ctx)
bondDenom := app.StakingKeeper.BondDenom(ctx)
// set a redelegation with expiration timestamp beyond which the
// redelegation shouldn't be slashed
@ -540,64 +556,64 @@ func TestSlashBoth(t *testing.T) {
rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11,
time.Unix(0, 0), rdATokens,
rdATokens.ToDec())
keeper.SetRedelegation(ctx, rdA)
app.StakingKeeper.SetRedelegation(ctx, rdA)
// set the associated delegation
delA := types.NewDelegation(addrDels[0], addrVals[1], rdATokens.ToDec())
keeper.SetDelegation(ctx, delA)
app.StakingKeeper.SetDelegation(ctx, delA)
// set an unbonding delegation with expiration timestamp (beyond which the
// unbonding delegation shouldn't be slashed)
ubdATokens := sdk.TokensFromConsensusPower(4)
ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
time.Unix(0, 0), ubdATokens)
keeper.SetUnbondingDelegation(ctx, ubdA)
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 := keeper.GetBondedPool(ctx)
notBondedPool := keeper.GetNotBondedPool(ctx)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
bondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedPoolBalances.Add(bondedCoins...)))
bondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
require.NoError(t, app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedPoolBalances.Add(bondedCoins...)))
notBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), notBondedPoolBalances.Add(notBondedCoins...)))
notBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
require.NoError(t, app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), notBondedPoolBalances.Add(notBondedCoins...)))
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool)
app.SupplyKeeper.SetModuleAccount(ctx, bondedPool)
app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool)
oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
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 := keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
require.True(t, found)
consAddr0 := sdk.ConsAddress(PKs[0].Address())
keeper.Slash(ctx, consAddr0, 10, 10, fraction)
app.StakingKeeper.Slash(ctx, consAddr0, 10, 10, fraction)
burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt()
burnedBondAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt()
burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount)
// read updated pool
bondedPool = keeper.GetBondedPool(ctx)
notBondedPool = keeper.GetNotBondedPool(ctx)
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
bondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
bondedPoolBalance := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldBonded.Sub(burnedBondAmount), bondedPoolBalance))
notBondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
require.True(sdk.IntEq(t, oldNotBonded.Sub(burnedNotBondedAmount), notBondedPoolBalance))
// read updating redelegation
rdA, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
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 = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
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())

View File

@ -1,248 +1,13 @@
package keeper
// noalias
package keeper // noalias
import (
"bytes"
"encoding/hex"
"math/rand"
"strconv"
"testing"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/codec"
simappcodec "github.com/cosmos/cosmos-sdk/simapp/codec"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/params/keeper"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/cosmos/cosmos-sdk/x/params/types/proposal"
"github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/cosmos/cosmos-sdk/x/supply"
)
// dummy addresses used for testing
// nolint:unused, deadcode
var (
Addrs = createTestAddrs(500)
PKs = createTestPubKeys(500)
addrDels = []sdk.AccAddress{
Addrs[0],
Addrs[1],
}
addrVals = []sdk.ValAddress{
sdk.ValAddress(Addrs[2]),
sdk.ValAddress(Addrs[3]),
sdk.ValAddress(Addrs[4]),
sdk.ValAddress(Addrs[5]),
sdk.ValAddress(Addrs[6]),
}
)
//_______________________________________________________________________________________
// 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
}
//_______________________________________________________________________________________
// create a codec used only for testing
func MakeTestCodec() *codec.Codec {
var cdc = codec.New()
// Register Msgs
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
cdc.RegisterConcrete(bank.MsgSend{}, "test/staking/Send", nil)
cdc.RegisterConcrete(types.MsgCreateValidator{}, "test/staking/CreateValidator", nil)
cdc.RegisterConcrete(types.MsgEditValidator{}, "test/staking/EditValidator", nil)
cdc.RegisterConcrete(types.MsgUndelegate{}, "test/staking/Undelegate", nil)
cdc.RegisterConcrete(types.MsgBeginRedelegate{}, "test/staking/BeginRedelegate", nil)
// Register AppAccount
cdc.RegisterInterface((*authexported.Account)(nil), nil)
cdc.RegisterConcrete(&auth.BaseAccount{}, "test/staking/BaseAccount", nil)
supply.RegisterCodec(cdc)
codec.RegisterCrypto(cdc)
return cdc
}
// Hogpodge of all sorts of input required for testing.
// `initPower` is converted to an amount of tokens.
// If `initPower` is 0, no addrs get created.
func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context, auth.AccountKeeper, types.BankKeeper, Keeper, types.SupplyKeeper) {
keyStaking := sdk.NewKVStoreKey(types.StoreKey)
keyAcc := sdk.NewKVStoreKey(auth.StoreKey)
bankKey := sdk.NewKVStoreKey(bank.StoreKey)
keyParams := sdk.NewKVStoreKey(paramtypes.StoreKey)
tkeyParams := sdk.NewTransientStoreKey(paramtypes.TStoreKey)
keySupply := sdk.NewKVStoreKey(supply.StoreKey)
db := dbm.NewMemDB()
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(bankKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
ms.MountStoreWithDB(keySupply, sdk.StoreTypeIAVL, db)
err := ms.LoadLatestVersion()
require.Nil(t, err)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger())
ctx = ctx.WithConsensusParams(
&abci.ConsensusParams{
Validator: &abci.ValidatorParams{
PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519},
},
},
)
cdc := MakeTestCodec()
appCodec := simappcodec.NewAppCodec(cdc)
feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName)
notBondedPool := supply.NewEmptyModuleAccount(types.NotBondedPoolName, supply.Burner, supply.Staking)
bondPool := supply.NewEmptyModuleAccount(types.BondedPoolName, supply.Burner, supply.Staking)
blacklistedAddrs := make(map[string]bool)
blacklistedAddrs[feeCollectorAcc.GetAddress().String()] = true
blacklistedAddrs[notBondedPool.GetAddress().String()] = true
blacklistedAddrs[bondPool.GetAddress().String()] = true
pk := keeper.NewKeeper(proposal.ModuleCdc, keyParams, tkeyParams)
accountKeeper := auth.NewAccountKeeper(
appCodec,
keyAcc,
pk.Subspace(auth.DefaultParamspace),
auth.ProtoBaseAccount,
)
bk := bank.NewBaseKeeper(
appCodec,
bankKey,
accountKeeper,
pk.Subspace(bank.DefaultParamspace),
blacklistedAddrs,
)
maccPerms := map[string][]string{
auth.FeeCollectorName: nil,
types.NotBondedPoolName: {supply.Burner, supply.Staking},
types.BondedPoolName: {supply.Burner, supply.Staking},
}
supplyKeeper := supply.NewKeeper(appCodec, keySupply, accountKeeper, bk, maccPerms)
initTokens := sdk.TokensFromConsensusPower(initPower)
initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))
totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(int64(len(Addrs)))))
supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
keeper := NewKeeper(types.ModuleCdc, keyStaking, bk, supplyKeeper, pk.Subspace(DefaultParamspace))
keeper.SetParams(ctx, types.DefaultParams())
// set module accounts
require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply))
supplyKeeper.SetModuleAccount(ctx, feeCollectorAcc)
supplyKeeper.SetModuleAccount(ctx, bondPool)
supplyKeeper.SetModuleAccount(ctx, notBondedPool)
// fill all the addresses with some coins, set the loose pool tokens simultaneously
for i, addr := range Addrs {
accountKeeper.SetAccount(ctx, auth.NewBaseAccount(addr, PKs[i], uint64(i), 0))
require.NoError(t, bk.SetBalances(ctx, addr, initCoins))
}
return ctx, accountKeeper, bk, keeper, supplyKeeper
}
func NewPubKey(pk string) (res crypto.PubKey) {
pkBytes, err := hex.DecodeString(pk)
if err != nil {
panic(err)
}
//res, err = crypto.PubKeyFromBytes(pkBytes)
var pkEd ed25519.PubKeyEd25519
copy(pkEd[:], pkBytes)
return pkEd
}
// for incode address generation
func TestAddr(addr string, bech string) sdk.AccAddress {
res, err := sdk.AccAddressFromHex(addr)
if err != nil {
panic(err)
}
bechexpected := res.String()
if bech != bechexpected {
panic("Bech encoding doesn't match reference")
}
bechres, err := sdk.AccAddressFromBech32(bech)
if err != nil {
panic(err)
}
if !bytes.Equal(bechres, res) {
panic("Bech decode and hex decode don't match")
}
return res
}
// nolint: unparam
func createTestAddrs(numAddrs int) []sdk.AccAddress {
var addresses []sdk.AccAddress
var buffer bytes.Buffer
// start at 100 so we can make up to 999 test addresses with valid test addresses
for i := 100; i < (numAddrs + 100); i++ {
numString := strconv.Itoa(i)
buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string
buffer.WriteString(numString) //adding on final two digits to make addresses unique
res, _ := sdk.AccAddressFromHex(buffer.String())
bech := res.String()
addresses = append(addresses, TestAddr(buffer.String(), bech))
buffer.Reset()
}
return addresses
}
// nolint: unparam
func createTestPubKeys(numPubKeys int) []crypto.PubKey {
var publicKeys []crypto.PubKey
var buffer bytes.Buffer
//start at 10 to avoid changing 1 to 01, 2 to 02, etc
for i := 100; i < (numPubKeys + 100); i++ {
numString := strconv.Itoa(i)
buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") //base pubkey string
buffer.WriteString(numString) //adding on final two digits to make pubkeys unique
publicKeys = append(publicKeys, NewPubKey(buffer.String()))
buffer.Reset()
}
return publicKeys
}
//_____________________________________________________________________________________
// does a certain by-power index record exist
func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) bool {
store := ctx.KVStore(keeper.storeKey)
@ -291,12 +56,6 @@ func TestingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Vali
return validator
}
// nolint:deadcode, unused
func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool {
store := ctx.KVStore(k.storeKey)
return store.Has(power)
}
// RandomValidator returns a random validator given access to the keeper and ctx
func RandomValidator(r *rand.Rand, keeper Keeper, ctx sdk.Context) (val types.Validator, ok bool) {
vals := keeper.GetAllValidators(ctx)

View File

@ -210,7 +210,7 @@ func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) typ
}
// switches a validator from unbonding state to unbonded state
func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) types.Validator {
func (k Keeper) UnbondingToUnbonded(ctx sdk.Context, validator types.Validator) types.Validator {
if !validator.IsUnbonding() {
panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator))
}

View File

@ -441,7 +441,7 @@ func (k Keeper) UnbondAllMatureValidatorQueue(ctx sdk.Context) {
panic("unexpected validator in unbonding queue; status was not unbonding")
}
val = k.unbondingToUnbonded(ctx, val)
val = k.UnbondingToUnbonded(ctx, val)
if val.GetDelegatorShares().IsZero() {
k.RemoveValidator(ctx, val.OperatorAddress)
}

File diff suppressed because it is too large Load Diff