refactor(x/staking)!: KVStoreService, return errors and use context.Context (#16324)
Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
This commit is contained in:
parent
c44957890a
commit
1be7d9805e
@ -45,6 +45,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
### API Breaking Changes
|
||||
|
||||
* (x/staking) [#16324](https://github.com/cosmos/cosmos-sdk/pull/16324) `NewKeeper` now takes a `KVStoreService` instead of a `StoreKey`, and methods in the `Keeper` now take a `context.Context` instead of a `sdk.Context` and return an `error`. Notable changes:
|
||||
* `Validator` method now returns `types.ErrNoValidatorFound` instead of `nil` when not found.
|
||||
* (x/distribution) [#16440](https://github.com/cosmos/cosmos-sdk/pull/16440) use collections for `DelegatorWithdrawAddresState`:
|
||||
* remove `Keeper`: `SetDelegatorWithdrawAddr`, `DeleteDelegatorWithdrawAddr`, `IterateDelegatorWithdrawAddrs`.
|
||||
* (x/distribution) [#16459](https://github.com/cosmos/cosmos-sdk/pull/16459) use collections for `ValidatorCurrentRewards` state management:
|
||||
|
||||
@ -321,7 +321,7 @@ func NewSimApp(
|
||||
logger,
|
||||
)
|
||||
app.StakingKeeper = stakingkeeper.NewKeeper(
|
||||
appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
|
||||
appCodec, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
|
||||
)
|
||||
app.MintKeeper = mintkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[minttypes.StoreKey]), app.StakingKeeper, app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())
|
||||
|
||||
|
||||
@ -77,13 +77,20 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []
|
||||
/* Handle fee distribution state. */
|
||||
|
||||
// withdraw all validator commission
|
||||
app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
err := app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// withdraw all delegator rewards
|
||||
dels := app.StakingKeeper.GetAllDelegations(ctx)
|
||||
dels, err := app.StakingKeeper.GetAllDelegations(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, delegation := range dels {
|
||||
valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
|
||||
if err != nil {
|
||||
@ -156,7 +163,10 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []
|
||||
for i := range red.Entries {
|
||||
red.Entries[i].CreationHeight = 0
|
||||
}
|
||||
app.StakingKeeper.SetRedelegation(ctx, red)
|
||||
err = app.StakingKeeper.SetRedelegation(ctx, red)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
@ -165,7 +175,10 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []
|
||||
for i := range ubd.Entries {
|
||||
ubd.Entries[i].CreationHeight = 0
|
||||
}
|
||||
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||
err = app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
@ -177,8 +190,8 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
|
||||
validator, found := app.StakingKeeper.GetValidator(ctx, addr)
|
||||
if !found {
|
||||
validator, err := app.StakingKeeper.GetValidator(ctx, addr)
|
||||
if err != nil {
|
||||
panic("expected validator, not found")
|
||||
}
|
||||
|
||||
@ -196,7 +209,7 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []
|
||||
return
|
||||
}
|
||||
|
||||
_, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
_, err = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@ -190,8 +190,12 @@ func AddTestAddrsIncremental(app *SimApp, ctx sdk.Context, accNum int, accAmt sd
|
||||
|
||||
func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdkmath.Int, strategy simtestutil.GenerateAccountStrategy) []sdk.AccAddress {
|
||||
testAddrs := strategy(accNum)
|
||||
bondDenom, err := app.StakingKeeper.BondDenom(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt))
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, accAmt))
|
||||
|
||||
for _, addr := range testAddrs {
|
||||
initAccountWithCoins(app, ctx, addr, initCoins)
|
||||
|
||||
@ -95,12 +95,14 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"delayed vesting has vested, multiple delegations less than the total account balance",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(200)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(200)))
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().Unix())
|
||||
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0))
|
||||
|
||||
err := accountKeeper.Params.Set(ctx, authtypes.DefaultParams())
|
||||
err = accountKeeper.Params.Set(ctx, authtypes.DefaultParams())
|
||||
require.NoError(t, err)
|
||||
|
||||
accountKeeper.SetAccount(ctx, delayedAccount)
|
||||
@ -121,9 +123,10 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
{
|
||||
"delayed vesting has vested, single delegations which exceed the vested amount",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(200)))
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(200)))
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().Unix())
|
||||
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0))
|
||||
@ -143,7 +146,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"delayed vesting has vested, multiple delegations which exceed the vested amount",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(200)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(200)))
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().Unix())
|
||||
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0))
|
||||
@ -167,7 +172,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"delayed vesting has not vested, single delegations which exceed the vested amount",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(200)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(200)))
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(1, 0, 0).Unix())
|
||||
|
||||
accountKeeper.SetAccount(ctx, delayedAccount)
|
||||
@ -185,7 +192,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"delayed vesting has not vested, multiple delegations which exceed the vested amount",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(200)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(200)))
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(1, 0, 0).Unix())
|
||||
|
||||
accountKeeper.SetAccount(ctx, delayedAccount)
|
||||
@ -207,7 +216,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"not end time",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(300)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(300)))
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(1, 0, 0).Unix())
|
||||
|
||||
accountKeeper.SetAccount(ctx, delayedAccount)
|
||||
@ -229,7 +240,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"delayed vesting has not vested, single delegation greater than the total account balance",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(300)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(300)))
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(1, 0, 0).Unix())
|
||||
|
||||
accountKeeper.SetAccount(ctx, delayedAccount)
|
||||
@ -247,7 +260,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"delayed vesting has vested, single delegation greater than the total account balance",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(300)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(300)))
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().Unix())
|
||||
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0))
|
||||
@ -269,7 +284,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
startTime := ctx.BlockTime().AddDate(1, 0, 0).Unix()
|
||||
endTime := ctx.BlockTime().AddDate(2, 0, 0).Unix()
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(300)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(300)))
|
||||
delayedAccount := types.NewContinuousVestingAccount(baseAccount, vestedCoins, startTime, endTime)
|
||||
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0))
|
||||
@ -291,7 +308,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
startTime := ctx.BlockTime().AddDate(-1, 0, 0).Unix()
|
||||
endTime := ctx.BlockTime().AddDate(2, 0, 0).Unix()
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(300)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(300)))
|
||||
delayedAccount := types.NewContinuousVestingAccount(baseAccount, vestedCoins, startTime, endTime)
|
||||
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0))
|
||||
@ -313,7 +332,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
startTime := ctx.BlockTime().AddDate(-2, 0, 0).Unix()
|
||||
endTime := ctx.BlockTime().AddDate(-1, 0, 0).Unix()
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(300)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(300)))
|
||||
delayedAccount := types.NewContinuousVestingAccount(baseAccount, vestedCoins, startTime, endTime)
|
||||
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0))
|
||||
@ -333,7 +354,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"periodic vesting account, yet to be vested, some rewards delegated",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdkmath.NewInt(100)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(100)))
|
||||
|
||||
start := ctx.BlockTime().Unix() + int64(time.Hour/time.Second)
|
||||
|
||||
@ -371,19 +394,21 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
*/
|
||||
startTime := int64(1601042400)
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(3666666670000)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdkmath.NewInt(3666666670000)))
|
||||
periods := []types.Period{
|
||||
{
|
||||
Length: 31536000,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(1833333335000))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(1833333335000))),
|
||||
},
|
||||
{
|
||||
Length: 15638400,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(916666667500))),
|
||||
},
|
||||
{
|
||||
Length: 15897600,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(916666667500))),
|
||||
},
|
||||
}
|
||||
|
||||
@ -415,19 +440,21 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
*/
|
||||
startTime := int64(1601042400)
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(3666666670000)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(3666666670000)))
|
||||
periods := []types.Period{
|
||||
{
|
||||
Length: 31536000,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(1833333335000))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(1833333335000))),
|
||||
},
|
||||
{
|
||||
Length: 15638400,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(916666667500))),
|
||||
},
|
||||
{
|
||||
Length: 15897600,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(916666667500))),
|
||||
},
|
||||
}
|
||||
|
||||
@ -461,19 +488,21 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
*/
|
||||
startTime := int64(1601042400)
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(3666666670000)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(3666666670000)))
|
||||
periods := []types.Period{
|
||||
{
|
||||
Length: 31536000,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(1833333335000))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(1833333335000))),
|
||||
},
|
||||
{
|
||||
Length: 15638400,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(916666667500))),
|
||||
},
|
||||
{
|
||||
Length: 15897600,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(916666667500))),
|
||||
},
|
||||
}
|
||||
|
||||
@ -507,19 +536,21 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
*/
|
||||
startTime := int64(1601042400)
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(3666666670000)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(3666666670000)))
|
||||
periods := []types.Period{
|
||||
{
|
||||
Length: 31536000,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(1833333335000))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(1833333335000))),
|
||||
},
|
||||
{
|
||||
Length: 15638400,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(916666667500))),
|
||||
},
|
||||
{
|
||||
Length: 15897600,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(916666667500))),
|
||||
},
|
||||
}
|
||||
|
||||
@ -543,7 +574,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"vesting account has unbonding delegations in place",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(300)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(300)))
|
||||
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(10, 0, 0).Unix())
|
||||
|
||||
@ -572,7 +605,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"vesting account has never delegated anything",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(300)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(300)))
|
||||
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(10, 0, 0).Unix())
|
||||
|
||||
@ -588,7 +623,9 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
"vesting account has no delegation but dirty DelegatedFree and DelegatedVesting fields",
|
||||
func(ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) {
|
||||
baseAccount := createBaseAccount(delegatorAddr)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(300)))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
vestedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(300)))
|
||||
|
||||
delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(10, 0, 0).Unix())
|
||||
|
||||
@ -612,8 +649,8 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
delegatorAddr := addrs[0]
|
||||
|
||||
_, valAddr := createValidator(t, ctx, bankKeeper, stakingKeeper, tc.tokenAmount*2)
|
||||
validator, found := stakingKeeper.GetValidator(ctx, valAddr)
|
||||
require.True(t, found)
|
||||
validator, err := stakingKeeper.GetValidator(ctx, valAddr)
|
||||
require.NoError(t, err)
|
||||
|
||||
tc.prepareFunc(ctx, validator, delegatorAddr)
|
||||
|
||||
@ -633,12 +670,15 @@ func TestMigrateVestingAccounts(t *testing.T) {
|
||||
var expVested sdk.Coins
|
||||
var expFree sdk.Coins
|
||||
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if tc.expVested != 0 {
|
||||
expVested = sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(tc.expVested)))
|
||||
expVested = sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(tc.expVested)))
|
||||
}
|
||||
|
||||
if tc.expFree != 0 {
|
||||
expFree = sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), sdk.NewInt(tc.expFree)))
|
||||
expFree = sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(tc.expFree)))
|
||||
}
|
||||
|
||||
trackingCorrected(
|
||||
|
||||
@ -96,7 +96,7 @@ func initFixture(t testing.TB) *fixture {
|
||||
log.NewNopLogger(),
|
||||
)
|
||||
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[stakingtypes.StoreKey], accountKeeper, bankKeeper, authority.String())
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), accountKeeper, bankKeeper, authority.String())
|
||||
|
||||
distrKeeper := distrkeeper.NewKeeper(
|
||||
cdc, runtime.NewKVStoreService(keys[distrtypes.StoreKey]), accountKeeper, bankKeeper, stakingKeeper, distrtypes.ModuleName, authority.String(),
|
||||
@ -245,7 +245,7 @@ func TestMsgWithdrawDelegatorReward(t *testing.T) {
|
||||
ValidatorAddress: f.valAddr.String(),
|
||||
},
|
||||
expErr: true,
|
||||
expErrMsg: "no delegation distribution info",
|
||||
expErrMsg: "no delegation for (address, validator) tuple",
|
||||
},
|
||||
{
|
||||
name: "validator with no delegations",
|
||||
@ -254,7 +254,7 @@ func TestMsgWithdrawDelegatorReward(t *testing.T) {
|
||||
ValidatorAddress: sdk.ValAddress(sdk.AccAddress(PKS[2].Address())).String(),
|
||||
},
|
||||
expErr: true,
|
||||
expErrMsg: "no validator distribution info",
|
||||
expErrMsg: "validator does not exist",
|
||||
},
|
||||
{
|
||||
name: "valid msg",
|
||||
@ -891,6 +891,9 @@ func TestMsgDepositValidatorRewardsPool(t *testing.T) {
|
||||
f.bankKeeper.MintCoins(f.sdkCtx, distrtypes.ModuleName, amt)
|
||||
f.bankKeeper.SendCoinsFromModuleToAccount(f.sdkCtx, distrtypes.ModuleName, addr, amt)
|
||||
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
msg *distrtypes.MsgDepositValidatorRewardsPool
|
||||
@ -902,7 +905,7 @@ func TestMsgDepositValidatorRewardsPool(t *testing.T) {
|
||||
msg: &distrtypes.MsgDepositValidatorRewardsPool{
|
||||
Depositor: addr.String(),
|
||||
ValidatorAddress: valAddr1.String(),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), sdk.NewInt(100))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(100))),
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -918,7 +921,7 @@ func TestMsgDepositValidatorRewardsPool(t *testing.T) {
|
||||
msg: &distrtypes.MsgDepositValidatorRewardsPool{
|
||||
Depositor: addr.String(),
|
||||
ValidatorAddress: sdk.ValAddress([]byte("addr1_______________")).String(),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), sdk.NewInt(100))),
|
||||
Amount: sdk.NewCoins(sdk.NewCoin(bondDenom, sdk.NewInt(100))),
|
||||
},
|
||||
expErr: true,
|
||||
expErrMsg: "validator does not exist",
|
||||
|
||||
@ -117,7 +117,7 @@ func initFixture(t testing.TB) *fixture {
|
||||
log.NewNopLogger(),
|
||||
)
|
||||
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[stakingtypes.StoreKey], accountKeeper, bankKeeper, authority.String())
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), accountKeeper, bankKeeper, authority.String())
|
||||
|
||||
slashingKeeper := slashingkeeper.NewKeeper(cdc, codec.NewLegacyAmino(), runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), stakingKeeper, authority.String())
|
||||
|
||||
@ -164,35 +164,40 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||
populateValidators(t, f)
|
||||
|
||||
power := int64(100)
|
||||
stakingParams := f.stakingKeeper.GetParams(ctx)
|
||||
operatorAddr, val := valAddresses[0], pubkeys[0]
|
||||
stakingParams, err := f.stakingKeeper.GetParams(ctx)
|
||||
assert.NilError(t, err)
|
||||
operatorAddr, valpubkey := valAddresses[0], pubkeys[0]
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, f.stakingKeeper)
|
||||
|
||||
selfDelegation := tstaking.CreateValidatorWithValPower(operatorAddr, val, power, true)
|
||||
selfDelegation := tstaking.CreateValidatorWithValPower(operatorAddr, valpubkey, power, true)
|
||||
|
||||
// execute end-blocker and verify validator attributes
|
||||
_, err := f.stakingKeeper.EndBlocker(f.sdkCtx)
|
||||
_, err = f.stakingKeeper.EndBlocker(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t,
|
||||
f.bankKeeper.GetAllBalances(ctx, sdk.AccAddress(operatorAddr)).String(),
|
||||
sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(selfDelegation))).String(),
|
||||
)
|
||||
assert.DeepEqual(t, selfDelegation, f.stakingKeeper.Validator(ctx, operatorAddr).GetBondedTokens())
|
||||
val, err := f.stakingKeeper.Validator(ctx, operatorAddr)
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, selfDelegation, val.GetBondedTokens())
|
||||
|
||||
assert.NilError(t, f.slashingKeeper.AddPubkey(f.sdkCtx, val))
|
||||
assert.NilError(t, f.slashingKeeper.AddPubkey(f.sdkCtx, valpubkey))
|
||||
|
||||
info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(val.Address()), f.sdkCtx.BlockHeight(), int64(0), time.Unix(0, 0), false, int64(0))
|
||||
f.slashingKeeper.SetValidatorSigningInfo(f.sdkCtx, sdk.ConsAddress(val.Address()), info)
|
||||
info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(valpubkey.Address()), f.sdkCtx.BlockHeight(), int64(0), time.Unix(0, 0), false, int64(0))
|
||||
f.slashingKeeper.SetValidatorSigningInfo(f.sdkCtx, sdk.ConsAddress(valpubkey.Address()), info)
|
||||
|
||||
// handle a signature to set signing info
|
||||
f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), selfDelegation.Int64(), comet.BlockIDFlagCommit)
|
||||
f.slashingKeeper.HandleValidatorSignature(ctx, valpubkey.Address(), selfDelegation.Int64(), comet.BlockIDFlagCommit)
|
||||
|
||||
// double sign less than max age
|
||||
oldTokens := f.stakingKeeper.Validator(ctx, operatorAddr).GetTokens()
|
||||
val, err = f.stakingKeeper.Validator(ctx, operatorAddr)
|
||||
assert.NilError(t, err)
|
||||
oldTokens := val.GetTokens()
|
||||
|
||||
nci := NewCometInfo(abci.RequestFinalizeBlock{
|
||||
Misbehavior: []abci.Misbehavior{{
|
||||
Validator: abci.Validator{Address: val.Address(), Power: power},
|
||||
Validator: abci.Validator{Address: valpubkey.Address(), Power: power},
|
||||
Type: abci.MisbehaviorType_DUPLICATE_VOTE,
|
||||
Time: time.Now().UTC(),
|
||||
Height: 1,
|
||||
@ -203,18 +208,22 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||
assert.NilError(t, f.evidenceKeeper.BeginBlocker(ctx.WithCometInfo(nci)))
|
||||
|
||||
// should be jailed and tombstoned
|
||||
assert.Assert(t, f.stakingKeeper.Validator(ctx, operatorAddr).IsJailed())
|
||||
assert.Assert(t, f.slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address())))
|
||||
val, err = f.stakingKeeper.Validator(ctx, operatorAddr)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, val.IsJailed())
|
||||
assert.Assert(t, f.slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(valpubkey.Address())))
|
||||
|
||||
// tokens should be decreased
|
||||
newTokens := f.stakingKeeper.Validator(ctx, operatorAddr).GetTokens()
|
||||
newTokens := val.GetTokens()
|
||||
assert.Assert(t, newTokens.LT(oldTokens))
|
||||
|
||||
// submit duplicate evidence
|
||||
assert.NilError(t, f.evidenceKeeper.BeginBlocker(ctx))
|
||||
|
||||
// tokens should be the same (capped slash)
|
||||
assert.Assert(t, f.stakingKeeper.Validator(ctx, operatorAddr).GetTokens().Equal(newTokens))
|
||||
val, err = f.stakingKeeper.Validator(ctx, operatorAddr)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, val.GetTokens().Equal(newTokens))
|
||||
|
||||
// jump to past the unbonding period
|
||||
ctx = ctx.WithBlockTime(time.Unix(1, 0).Add(stakingParams.UnbondingTime))
|
||||
@ -247,25 +256,28 @@ func TestHandleDoubleSign_TooOld(t *testing.T) {
|
||||
populateValidators(t, f)
|
||||
|
||||
power := int64(100)
|
||||
stakingParams := f.stakingKeeper.GetParams(ctx)
|
||||
operatorAddr, val := valAddresses[0], pubkeys[0]
|
||||
stakingParams, err := f.stakingKeeper.GetParams(ctx)
|
||||
assert.NilError(t, err)
|
||||
operatorAddr, valpubkey := valAddresses[0], pubkeys[0]
|
||||
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, f.stakingKeeper)
|
||||
|
||||
amt := tstaking.CreateValidatorWithValPower(operatorAddr, val, power, true)
|
||||
amt := tstaking.CreateValidatorWithValPower(operatorAddr, valpubkey, power, true)
|
||||
|
||||
// execute end-blocker and verify validator attributes
|
||||
_, err := f.stakingKeeper.EndBlocker(f.sdkCtx)
|
||||
_, err = f.stakingKeeper.EndBlocker(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t,
|
||||
f.bankKeeper.GetAllBalances(ctx, sdk.AccAddress(operatorAddr)),
|
||||
sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(amt))),
|
||||
)
|
||||
assert.DeepEqual(t, amt, f.stakingKeeper.Validator(ctx, operatorAddr).GetBondedTokens())
|
||||
val, err := f.stakingKeeper.Validator(ctx, operatorAddr)
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, amt, val.GetBondedTokens())
|
||||
|
||||
nci := NewCometInfo(abci.RequestFinalizeBlock{
|
||||
Misbehavior: []abci.Misbehavior{{
|
||||
Validator: abci.Validator{Address: val.Address(), Power: power},
|
||||
Validator: abci.Validator{Address: valpubkey.Address(), Power: power},
|
||||
Type: abci.MisbehaviorType_DUPLICATE_VOTE,
|
||||
Time: ctx.BlockTime(),
|
||||
Height: 0,
|
||||
@ -282,8 +294,10 @@ func TestHandleDoubleSign_TooOld(t *testing.T) {
|
||||
|
||||
assert.NilError(t, f.evidenceKeeper.BeginBlocker(ctx))
|
||||
|
||||
assert.Assert(t, f.stakingKeeper.Validator(ctx, operatorAddr).IsJailed() == false)
|
||||
assert.Assert(t, f.slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address())) == false)
|
||||
val, err = f.stakingKeeper.Validator(ctx, operatorAddr)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, val.IsJailed() == false)
|
||||
assert.Assert(t, f.slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(valpubkey.Address())) == false)
|
||||
}
|
||||
|
||||
func populateValidators(t assert.TestingT, f *fixture) {
|
||||
|
||||
@ -87,7 +87,7 @@ func initFixture(t testing.TB) *fixture {
|
||||
log.NewNopLogger(),
|
||||
)
|
||||
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[stakingtypes.StoreKey], accountKeeper, bankKeeper, authority.String())
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), accountKeeper, bankKeeper, authority.String())
|
||||
|
||||
// set default staking params
|
||||
stakingKeeper.SetParams(newCtx, stakingtypes.DefaultParams())
|
||||
|
||||
@ -88,7 +88,7 @@ func initFixture(t testing.TB) *fixture {
|
||||
log.NewNopLogger(),
|
||||
)
|
||||
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[stakingtypes.StoreKey], accountKeeper, bankKeeper, authority.String())
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), accountKeeper, bankKeeper, authority.String())
|
||||
|
||||
slashingKeeper := slashingkeeper.NewKeeper(cdc, &codec.LegacyAmino{}, runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), stakingKeeper, authority.String())
|
||||
|
||||
@ -133,7 +133,8 @@ func TestUnJailNotBonded(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
p := f.stakingKeeper.GetParams(f.ctx)
|
||||
p, err := f.stakingKeeper.GetParams(f.ctx)
|
||||
assert.NilError(t, err)
|
||||
p.MaxValidators = 5
|
||||
f.stakingKeeper.SetParams(f.ctx, p)
|
||||
|
||||
@ -212,7 +213,7 @@ func TestHandleNewValidator(t *testing.T) {
|
||||
f := initFixture(t)
|
||||
|
||||
pks := simtestutil.CreateTestPubKeys(1)
|
||||
addr, val := f.valAddrs[0], pks[0]
|
||||
addr, valpubkey := f.valAddrs[0], pks[0]
|
||||
tstaking := stakingtestutil.NewHelper(t, f.ctx, f.stakingKeeper)
|
||||
signedBlocksWindow, err := f.slashingKeeper.SignedBlocksWindow(f.ctx)
|
||||
assert.NilError(t, err)
|
||||
@ -220,27 +221,33 @@ func TestHandleNewValidator(t *testing.T) {
|
||||
|
||||
assert.NilError(t, f.slashingKeeper.AddPubkey(f.ctx, pks[0]))
|
||||
|
||||
info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(val.Address()), f.ctx.BlockHeight(), int64(0), time.Unix(0, 0), false, int64(0))
|
||||
err = f.slashingKeeper.SetValidatorSigningInfo(f.ctx, sdk.ConsAddress(val.Address()), info)
|
||||
assert.NilError(t, err)
|
||||
info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(valpubkey.Address()), f.ctx.BlockHeight(), int64(0), time.Unix(0, 0), false, int64(0))
|
||||
assert.NilError(t, f.slashingKeeper.SetValidatorSigningInfo(f.ctx, sdk.ConsAddress(valpubkey.Address()), info))
|
||||
|
||||
// Validator created
|
||||
amt := tstaking.CreateValidatorWithValPower(addr, val, 100, true)
|
||||
amt := tstaking.CreateValidatorWithValPower(addr, valpubkey, 100, true)
|
||||
|
||||
_, err = f.stakingKeeper.EndBlocker(f.ctx)
|
||||
assert.NilError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.DeepEqual(
|
||||
t, f.bankKeeper.GetAllBalances(f.ctx, sdk.AccAddress(addr)),
|
||||
sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.GetParams(f.ctx).BondDenom, testutil.InitTokens.Sub(amt))),
|
||||
sdk.NewCoins(sdk.NewCoin(bondDenom, testutil.InitTokens.Sub(amt))),
|
||||
)
|
||||
assert.DeepEqual(t, amt, f.stakingKeeper.Validator(f.ctx, addr).GetBondedTokens())
|
||||
|
||||
val, err := f.stakingKeeper.Validator(f.ctx, addr)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, amt, val.GetBondedTokens())
|
||||
|
||||
// Now a validator, for two blocks
|
||||
assert.NilError(t, f.slashingKeeper.HandleValidatorSignature(f.ctx, val.Address(), 100, comet.BlockIDFlagCommit))
|
||||
assert.NilError(t, f.slashingKeeper.HandleValidatorSignature(f.ctx, valpubkey.Address(), 100, comet.BlockIDFlagCommit))
|
||||
f.ctx = f.ctx.WithBlockHeight(signedBlocksWindow + 2)
|
||||
assert.NilError(t, f.slashingKeeper.HandleValidatorSignature(f.ctx, val.Address(), 100, comet.BlockIDFlagAbsent))
|
||||
assert.NilError(t, f.slashingKeeper.HandleValidatorSignature(f.ctx, valpubkey.Address(), 100, comet.BlockIDFlagAbsent))
|
||||
|
||||
info, found := f.slashingKeeper.GetValidatorSigningInfo(f.ctx, sdk.ConsAddress(val.Address()))
|
||||
info, found := f.slashingKeeper.GetValidatorSigningInfo(f.ctx, sdk.ConsAddress(valpubkey.Address()))
|
||||
assert.Assert(t, found)
|
||||
assert.Equal(t, signedBlocksWindow+1, info.StartHeight)
|
||||
assert.Equal(t, int64(2), info.IndexOffset)
|
||||
@ -248,11 +255,11 @@ func TestHandleNewValidator(t *testing.T) {
|
||||
assert.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil)
|
||||
|
||||
// validator should be bonded still, should not have been jailed or slashed
|
||||
validator, _ := f.stakingKeeper.GetValidatorByConsAddr(f.ctx, sdk.GetConsAddress(val))
|
||||
validator, _ := f.stakingKeeper.GetValidatorByConsAddr(f.ctx, sdk.GetConsAddress(valpubkey))
|
||||
assert.Equal(t, stakingtypes.Bonded, validator.GetStatus())
|
||||
bondPool := f.stakingKeeper.GetBondedPool(f.ctx)
|
||||
expTokens := f.stakingKeeper.TokensFromConsensusPower(f.ctx, 100)
|
||||
assert.Assert(t, expTokens.Equal(f.bankKeeper.GetBalance(f.ctx, bondPool.GetAddress(), f.stakingKeeper.BondDenom(f.ctx)).Amount))
|
||||
assert.Assert(t, expTokens.Equal(f.bankKeeper.GetBalance(f.ctx, bondPool.GetAddress(), bondDenom).Amount))
|
||||
}
|
||||
|
||||
// Test a jailed validator being "down" twice
|
||||
@ -326,7 +333,8 @@ func TestValidatorDippingInAndOut(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
params := f.stakingKeeper.GetParams(f.ctx)
|
||||
params, err := f.stakingKeeper.GetParams(f.ctx)
|
||||
require.NoError(t, err)
|
||||
params.MaxValidators = 1
|
||||
f.stakingKeeper.SetParams(f.ctx, params)
|
||||
power := int64(100)
|
||||
|
||||
@ -71,12 +71,12 @@ func createValidators(t *testing.T, f *fixture, powers []int64) ([]sdk.AccAddres
|
||||
val2 := testutil.NewValidator(t, valAddrs[1], pks[1])
|
||||
vals := []types.Validator{val1, val2}
|
||||
|
||||
f.stakingKeeper.SetValidator(f.sdkCtx, val1)
|
||||
f.stakingKeeper.SetValidator(f.sdkCtx, val2)
|
||||
f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, val1)
|
||||
f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, val2)
|
||||
f.stakingKeeper.SetNewValidatorByPowerIndex(f.sdkCtx, val1)
|
||||
f.stakingKeeper.SetNewValidatorByPowerIndex(f.sdkCtx, val2)
|
||||
assert.NilError(t, f.stakingKeeper.SetValidator(f.sdkCtx, val1))
|
||||
assert.NilError(t, f.stakingKeeper.SetValidator(f.sdkCtx, val2))
|
||||
assert.NilError(t, f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, val1))
|
||||
assert.NilError(t, f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, val2))
|
||||
assert.NilError(t, f.stakingKeeper.SetNewValidatorByPowerIndex(f.sdkCtx, val1))
|
||||
assert.NilError(t, f.stakingKeeper.SetNewValidatorByPowerIndex(f.sdkCtx, val2))
|
||||
|
||||
_, err := f.stakingKeeper.Delegate(f.sdkCtx, addrs[0], f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, powers[0]), types.Unbonded, val1, true)
|
||||
assert.NilError(t, err)
|
||||
@ -130,7 +130,7 @@ func initFixture(t testing.TB) *fixture {
|
||||
log.NewNopLogger(),
|
||||
)
|
||||
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[types.StoreKey], accountKeeper, bankKeeper, authority.String())
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, runtime.NewKVStoreService(keys[types.StoreKey]), accountKeeper, bankKeeper, authority.String())
|
||||
|
||||
authModule := auth.NewAppModule(cdc, accountKeeper, authsims.RandomGenesisAccounts, nil)
|
||||
bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper, nil)
|
||||
@ -145,7 +145,7 @@ func initFixture(t testing.TB) *fixture {
|
||||
types.RegisterQueryServer(integrationApp.QueryHelper(), stakingkeeper.NewQuerier(stakingKeeper))
|
||||
|
||||
// set default staking params
|
||||
stakingKeeper.SetParams(sdkCtx, types.DefaultParams())
|
||||
assert.NilError(t, stakingKeeper.SetParams(sdkCtx, types.DefaultParams()))
|
||||
|
||||
f := fixture{
|
||||
app: integrationApp,
|
||||
|
||||
@ -21,23 +21,20 @@ func TestUnbondingDelegationsMaxEntries(t *testing.T) {
|
||||
ctx := f.sdkCtx
|
||||
|
||||
initTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, int64(1000))
|
||||
f.bankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)))
|
||||
assert.NilError(t, f.bankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))))
|
||||
|
||||
addrDel := sdk.AccAddress([]byte("addr"))
|
||||
accAmt := sdk.NewInt(10000)
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(ctx), accAmt))
|
||||
if err := f.bankKeeper.MintCoins(ctx, types.ModuleName, initCoins); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(ctx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
if err := f.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addrDel, initCoins); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, accAmt))
|
||||
assert.NilError(t, f.bankKeeper.MintCoins(ctx, types.ModuleName, initCoins))
|
||||
assert.NilError(t, f.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addrDel, initCoins))
|
||||
addrVal := sdk.ValAddress(addrDel)
|
||||
|
||||
startTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, 10)
|
||||
|
||||
bondDenom := f.stakingKeeper.BondDenom(ctx)
|
||||
notBondedPool := f.stakingKeeper.GetNotBondedPool(ctx)
|
||||
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(ctx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
|
||||
@ -54,9 +51,10 @@ func TestUnbondingDelegationsMaxEntries(t *testing.T) {
|
||||
assert.Assert(t, validator.IsBonded())
|
||||
|
||||
delegation := types.NewDelegation(addrDel, addrVal, issuedShares)
|
||||
f.stakingKeeper.SetDelegation(ctx, delegation)
|
||||
assert.NilError(t, f.stakingKeeper.SetDelegation(ctx, delegation))
|
||||
|
||||
maxEntries := f.stakingKeeper.MaxEntries(ctx)
|
||||
maxEntries, err := f.stakingKeeper.MaxEntries(ctx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
oldBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
|
||||
oldNotBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
|
||||
@ -69,8 +67,8 @@ func TestUnbondingDelegationsMaxEntries(t *testing.T) {
|
||||
ctx = ctx.WithBlockHeight(i)
|
||||
var amount math.Int
|
||||
completionTime, amount, err = f.stakingKeeper.Undelegate(ctx, addrDel, addrVal, math.LegacyNewDec(1))
|
||||
totalUnbonded = totalUnbonded.Add(amount)
|
||||
assert.NilError(t, err)
|
||||
totalUnbonded = totalUnbonded.Add(amount)
|
||||
}
|
||||
|
||||
newBonded := f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
|
||||
@ -84,7 +82,7 @@ func TestUnbondingDelegationsMaxEntries(t *testing.T) {
|
||||
oldNotBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
|
||||
|
||||
// an additional unbond should fail due to max entries
|
||||
_, _, err := f.stakingKeeper.Undelegate(ctx, addrDel, addrVal, math.LegacyNewDec(1))
|
||||
_, _, err = f.stakingKeeper.Undelegate(ctx, addrDel, addrVal, math.LegacyNewDec(1))
|
||||
assert.Error(t, err, "too many unbonding delegation entries for (delegator, validator) tuple")
|
||||
|
||||
newBonded = f.bankKeeper.GetBalance(ctx, f.stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
|
||||
|
||||
@ -102,7 +102,7 @@ func initDeterministicFixture(t *testing.T) *deterministicFixture {
|
||||
log.NewNopLogger(),
|
||||
)
|
||||
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[stakingtypes.StoreKey], accountKeeper, bankKeeper, authority.String())
|
||||
stakingKeeper := stakingkeeper.NewKeeper(cdc, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), accountKeeper, bankKeeper, authority.String())
|
||||
|
||||
authModule := auth.NewAppModule(cdc, accountKeeper, authsims.RandomGenesisAccounts, nil)
|
||||
bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper, nil)
|
||||
@ -110,34 +110,35 @@ func initDeterministicFixture(t *testing.T) *deterministicFixture {
|
||||
|
||||
integrationApp := integration.NewIntegrationApp(newCtx, logger, keys, cdc, authModule, bankModule, stakingModule)
|
||||
|
||||
sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context())
|
||||
ctx := integrationApp.Context()
|
||||
|
||||
// Register MsgServer and QueryServer
|
||||
stakingtypes.RegisterMsgServer(integrationApp.MsgServiceRouter(), stakingkeeper.NewMsgServerImpl(stakingKeeper))
|
||||
stakingtypes.RegisterQueryServer(integrationApp.QueryHelper(), stakingkeeper.NewQuerier(stakingKeeper))
|
||||
|
||||
// set default staking params
|
||||
stakingKeeper.SetParams(sdkCtx, stakingtypes.DefaultParams())
|
||||
assert.NilError(t, stakingKeeper.SetParams(ctx, stakingtypes.DefaultParams()))
|
||||
|
||||
// set pools
|
||||
startTokens := stakingKeeper.TokensFromConsensusPower(sdkCtx, 10)
|
||||
bondDenom := stakingKeeper.BondDenom(sdkCtx)
|
||||
notBondedPool := stakingKeeper.GetNotBondedPool(sdkCtx)
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(sdkCtx, bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
|
||||
accountKeeper.SetModuleAccount(sdkCtx, notBondedPool)
|
||||
bondedPool := stakingKeeper.GetBondedPool(sdkCtx)
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(sdkCtx, bankKeeper, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
|
||||
accountKeeper.SetModuleAccount(sdkCtx, bondedPool)
|
||||
startTokens := stakingKeeper.TokensFromConsensusPower(ctx, 10)
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
assert.NilError(t, err)
|
||||
notBondedPool := stakingKeeper.GetNotBondedPool(ctx)
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(ctx, bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
|
||||
accountKeeper.SetModuleAccount(ctx, notBondedPool)
|
||||
bondedPool := stakingKeeper.GetBondedPool(ctx)
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(ctx, bankKeeper, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
|
||||
accountKeeper.SetModuleAccount(ctx, bondedPool)
|
||||
|
||||
qr := integrationApp.QueryHelper()
|
||||
queryClient := stakingtypes.NewQueryClient(qr)
|
||||
|
||||
amt1 := stakingKeeper.TokensFromConsensusPower(sdkCtx, 101)
|
||||
amt2 := stakingKeeper.TokensFromConsensusPower(sdkCtx, 102)
|
||||
amt1 := stakingKeeper.TokensFromConsensusPower(ctx, 101)
|
||||
amt2 := stakingKeeper.TokensFromConsensusPower(ctx, 102)
|
||||
|
||||
f := deterministicFixture{
|
||||
app: integrationApp,
|
||||
ctx: sdkCtx,
|
||||
ctx: sdk.UnwrapSDKContext(ctx),
|
||||
cdc: cdc,
|
||||
keys: keys,
|
||||
accountKeeper: accountKeeper,
|
||||
@ -220,14 +221,14 @@ func createAndSetValidator(rt *rapid.T, f *deterministicFixture, t *testing.T) s
|
||||
}
|
||||
|
||||
func setValidator(f *deterministicFixture, t *testing.T, validator stakingtypes.Validator) {
|
||||
f.stakingKeeper.SetValidator(f.ctx, validator)
|
||||
f.stakingKeeper.SetValidatorByPowerIndex(f.ctx, validator)
|
||||
f.stakingKeeper.SetValidatorByConsAddr(f.ctx, validator)
|
||||
assert.NilError(t, f.stakingKeeper.SetValidator(f.ctx, validator))
|
||||
assert.NilError(t, f.stakingKeeper.SetValidatorByPowerIndex(f.ctx, validator))
|
||||
assert.NilError(t, f.stakingKeeper.SetValidatorByConsAddr(f.ctx, validator))
|
||||
assert.NilError(t, f.stakingKeeper.Hooks().AfterValidatorCreated(f.ctx, validator.GetOperator()))
|
||||
|
||||
delegatorAddress := sdk.AccAddress(validator.GetOperator())
|
||||
coins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, validator.BondedTokens()))
|
||||
banktestutil.FundAccount(f.ctx, f.bankKeeper, delegatorAddress, coins)
|
||||
assert.NilError(t, banktestutil.FundAccount(f.ctx, f.bankKeeper, delegatorAddress, coins))
|
||||
|
||||
_, err := f.stakingKeeper.Delegate(f.ctx, delegatorAddress, validator.BondedTokens(), stakingtypes.Unbonded, validator, true)
|
||||
assert.NilError(t, err)
|
||||
@ -312,7 +313,7 @@ func fundAccountAndDelegate(f *deterministicFixture, t *testing.T, delegator sdk
|
||||
coins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amt))
|
||||
|
||||
assert.NilError(t, f.bankKeeper.MintCoins(f.ctx, minttypes.ModuleName, coins))
|
||||
banktestutil.FundAccount(f.ctx, f.bankKeeper, delegator, coins)
|
||||
assert.NilError(t, banktestutil.FundAccount(f.ctx, f.bankKeeper, delegator, coins))
|
||||
|
||||
shares, err := f.stakingKeeper.Delegate(f.ctx, delegator, amt, stakingtypes.Unbonded, validator, true)
|
||||
return shares, err
|
||||
@ -651,11 +652,11 @@ func TestGRPCHistoricalInfo(t *testing.T) {
|
||||
|
||||
height := rapid.Int64Min(0).Draw(rt, "height")
|
||||
|
||||
f.stakingKeeper.SetHistoricalInfo(
|
||||
assert.NilError(t, f.stakingKeeper.SetHistoricalInfo(
|
||||
f.ctx,
|
||||
height,
|
||||
&historicalInfo,
|
||||
)
|
||||
))
|
||||
|
||||
req := &stakingtypes.QueryHistoricalInfoRequest{
|
||||
Height: height,
|
||||
@ -675,11 +676,11 @@ func TestGRPCHistoricalInfo(t *testing.T) {
|
||||
|
||||
height := int64(127)
|
||||
|
||||
f.stakingKeeper.SetHistoricalInfo(
|
||||
assert.NilError(t, f.stakingKeeper.SetHistoricalInfo(
|
||||
f.ctx,
|
||||
height,
|
||||
&historicalInfo,
|
||||
)
|
||||
))
|
||||
|
||||
req := &stakingtypes.QueryHistoricalInfoRequest{
|
||||
Height: height,
|
||||
|
||||
@ -40,10 +40,14 @@ func TestInitGenesis(t *testing.T) {
|
||||
DelegatorShares: sdk.NewDecFromInt(valTokens),
|
||||
Description: types.NewDescription("hoop", "", "", "", ""),
|
||||
}
|
||||
f.stakingKeeper.SetValidator(f.sdkCtx, bondedVal)
|
||||
assert.NilError(t, f.stakingKeeper.SetValidator(f.sdkCtx, bondedVal))
|
||||
|
||||
params, err := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
validators, err := f.stakingKeeper.GetAllValidators(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
params := (f.stakingKeeper.GetParams(f.sdkCtx))
|
||||
validators := (f.stakingKeeper.GetAllValidators(f.sdkCtx))
|
||||
assert.Assert(t, len(validators) == 1)
|
||||
var delegations []types.Delegation
|
||||
|
||||
@ -87,7 +91,8 @@ func TestInitGenesis(t *testing.T) {
|
||||
),
|
||||
)
|
||||
|
||||
genesisDelegations := (f.stakingKeeper.GetAllDelegations(f.sdkCtx))
|
||||
genesisDelegations, err := f.stakingKeeper.GetAllDelegations(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
delegations = append(delegations, genesisDelegations...)
|
||||
|
||||
genesisState := types.NewGenesisState(params, validators, delegations)
|
||||
@ -96,7 +101,10 @@ func TestInitGenesis(t *testing.T) {
|
||||
actualGenesis := (f.stakingKeeper.ExportGenesis(f.sdkCtx))
|
||||
assert.DeepEqual(t, genesisState.Params, actualGenesis.Params)
|
||||
assert.DeepEqual(t, genesisState.Delegations, actualGenesis.Delegations)
|
||||
assert.DeepEqual(t, (f.stakingKeeper.GetAllValidators(f.sdkCtx)), actualGenesis.Validators)
|
||||
|
||||
allvals, err := f.stakingKeeper.GetAllValidators(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, allvals, actualGenesis.Validators)
|
||||
|
||||
// Ensure validators have addresses.
|
||||
vals2, err := staking.WriteValidators(f.sdkCtx, (f.stakingKeeper))
|
||||
@ -175,14 +183,14 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
|
||||
assert.Assert(t, size > 100)
|
||||
|
||||
f, addrs := bootstrapGenesisTest(t, 200)
|
||||
genesisValidators := f.stakingKeeper.GetAllValidators(f.sdkCtx)
|
||||
genesisValidators, err := f.stakingKeeper.GetAllValidators(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
params := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
params, err := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
delegations := []types.Delegation{}
|
||||
validators := make([]types.Validator, size)
|
||||
|
||||
var err error
|
||||
|
||||
bondedPoolAmt := math.ZeroInt()
|
||||
for i := range validators {
|
||||
validators[i], err = types.NewValidator(
|
||||
|
||||
@ -27,7 +27,7 @@ func createValidatorAccs(t *testing.T, f *fixture) ([]sdk.AccAddress, []types.Va
|
||||
sortedVals := make([]types.Validator, len(validators))
|
||||
copy(sortedVals, validators)
|
||||
hi := types.NewHistoricalInfo(header, sortedVals, f.stakingKeeper.PowerReduction(f.sdkCtx))
|
||||
f.stakingKeeper.SetHistoricalInfo(f.sdkCtx, 5, &hi)
|
||||
assert.NilError(t, f.stakingKeeper.SetHistoricalInfo(f.sdkCtx, 5, &hi))
|
||||
|
||||
return addrs, validators
|
||||
}
|
||||
@ -126,8 +126,10 @@ func TestGRPCQueryDelegatorValidators(t *testing.T) {
|
||||
qr := f.app.QueryHelper()
|
||||
queryClient := types.NewQueryClient(qr)
|
||||
|
||||
params := f.stakingKeeper.GetParams(ctx)
|
||||
delValidators := f.stakingKeeper.GetDelegatorValidators(ctx, addrs[0], params.MaxValidators)
|
||||
params, err := f.stakingKeeper.GetParams(ctx)
|
||||
assert.NilError(t, err)
|
||||
delValidators, err := f.stakingKeeper.GetDelegatorValidators(ctx, addrs[0], params.MaxValidators)
|
||||
assert.NilError(t, err)
|
||||
var req *types.QueryDelegatorValidatorsRequest
|
||||
testCases := []struct {
|
||||
msg string
|
||||
@ -712,7 +714,9 @@ func TestGRPCQueryPoolParameters(t *testing.T) {
|
||||
// Query Params
|
||||
resp, err := queryClient.Params(gocontext.Background(), &types.QueryParamsRequest{})
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, f.stakingKeeper.GetParams(ctx), resp.Params)
|
||||
params, err := f.stakingKeeper.GetParams(ctx)
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, params, resp.Params)
|
||||
}
|
||||
|
||||
func TestGRPCQueryHistoricalInfo(t *testing.T) {
|
||||
|
||||
@ -19,16 +19,17 @@ func TestCancelUnbondingDelegation(t *testing.T) {
|
||||
|
||||
ctx := f.sdkCtx
|
||||
msgServer := keeper.NewMsgServerImpl(f.stakingKeeper)
|
||||
bondDenom := f.stakingKeeper.BondDenom(ctx)
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(ctx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// set the not bonded pool module account
|
||||
notBondedPool := f.stakingKeeper.GetNotBondedPool(ctx)
|
||||
startTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, 5)
|
||||
|
||||
assert.NilError(t, testutil.FundModuleAccount(ctx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(ctx), startTokens))))
|
||||
assert.NilError(t, testutil.FundModuleAccount(ctx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
|
||||
f.accountKeeper.SetModuleAccount(ctx, notBondedPool)
|
||||
|
||||
moduleBalance := f.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), f.stakingKeeper.BondDenom(ctx))
|
||||
moduleBalance := f.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom)
|
||||
assert.DeepEqual(t, sdk.NewInt64Coin(bondDenom, startTokens.Int64()), moduleBalance)
|
||||
|
||||
// accounts
|
||||
@ -40,13 +41,13 @@ func TestCancelUnbondingDelegation(t *testing.T) {
|
||||
validator, err := types.NewValidator(valAddr, PKs[0], types.NewDescription("Validator", "", "", "", ""))
|
||||
validator.Status = types.Bonded
|
||||
assert.NilError(t, err)
|
||||
f.stakingKeeper.SetValidator(ctx, validator)
|
||||
assert.NilError(t, f.stakingKeeper.SetValidator(ctx, validator))
|
||||
|
||||
validatorAddr, err := sdk.ValAddressFromBech32(validator.OperatorAddress)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// setting the ubd entry
|
||||
unbondingAmount := sdk.NewInt64Coin(f.stakingKeeper.BondDenom(ctx), 5)
|
||||
unbondingAmount := sdk.NewInt64Coin(bondDenom, 5)
|
||||
ubd := types.NewUnbondingDelegation(
|
||||
delegatorAddr, validatorAddr, 10,
|
||||
ctx.BlockTime().Add(time.Minute*10),
|
||||
@ -55,7 +56,7 @@ func TestCancelUnbondingDelegation(t *testing.T) {
|
||||
)
|
||||
|
||||
// set and retrieve a record
|
||||
f.stakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||
assert.NilError(t, f.stakingKeeper.SetUnbondingDelegation(ctx, ubd))
|
||||
resUnbond, found := f.stakingKeeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr)
|
||||
assert.Assert(t, found)
|
||||
assert.DeepEqual(t, ubd, resUnbond)
|
||||
@ -72,7 +73,7 @@ func TestCancelUnbondingDelegation(t *testing.T) {
|
||||
req: types.MsgCancelUnbondingDelegation{
|
||||
DelegatorAddress: resUnbond.DelegatorAddress,
|
||||
ValidatorAddress: resUnbond.ValidatorAddress,
|
||||
Amount: sdk.NewCoin(f.stakingKeeper.BondDenom(ctx), sdk.NewInt(4)),
|
||||
Amount: sdk.NewCoin(bondDenom, sdk.NewInt(4)),
|
||||
CreationHeight: 11,
|
||||
},
|
||||
expErrMsg: "unbonding delegation entry is not found at block height",
|
||||
@ -83,7 +84,7 @@ func TestCancelUnbondingDelegation(t *testing.T) {
|
||||
req: types.MsgCancelUnbondingDelegation{
|
||||
DelegatorAddress: resUnbond.DelegatorAddress,
|
||||
ValidatorAddress: resUnbond.ValidatorAddress,
|
||||
Amount: sdk.NewCoin(f.stakingKeeper.BondDenom(ctx), sdk.NewInt(4)),
|
||||
Amount: sdk.NewCoin(bondDenom, sdk.NewInt(4)),
|
||||
CreationHeight: 0,
|
||||
},
|
||||
expErrMsg: "invalid height",
|
||||
|
||||
@ -24,7 +24,9 @@ func bootstrapSlashTest(t *testing.T, power int64) (*fixture, []sdk.AccAddress,
|
||||
addrDels, addrVals := generateAddresses(f, 100)
|
||||
|
||||
amt := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, power)
|
||||
totalSupply := sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), amt.MulRaw(int64(len(addrDels)))))
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
require.NoError(t, err)
|
||||
totalSupply := sdk.NewCoins(sdk.NewCoin(bondDenom, amt.MulRaw(int64(len(addrDels)))))
|
||||
|
||||
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, notBondedPool.GetName(), totalSupply))
|
||||
@ -32,7 +34,7 @@ func bootstrapSlashTest(t *testing.T, power int64) (*fixture, []sdk.AccAddress,
|
||||
f.accountKeeper.SetModuleAccount(f.sdkCtx, notBondedPool)
|
||||
|
||||
numVals := int64(3)
|
||||
bondedCoins := sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), amt.MulRaw(numVals)))
|
||||
bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, amt.MulRaw(numVals)))
|
||||
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
|
||||
|
||||
// set bonded pool balance
|
||||
@ -43,7 +45,7 @@ func bootstrapSlashTest(t *testing.T, power int64) (*fixture, []sdk.AccAddress,
|
||||
validator := testutil.NewValidator(t, addrVals[i], PKs[i])
|
||||
validator, _ = validator.AddTokensFromDel(amt)
|
||||
validator = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validator, true)
|
||||
f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, validator)
|
||||
assert.NilError(t, f.stakingKeeper.SetValidatorByConsAddr(f.sdkCtx, validator))
|
||||
}
|
||||
|
||||
return f, addrDels, addrVals
|
||||
@ -60,24 +62,27 @@ func TestSlashUnbondingDelegation(t *testing.T) {
|
||||
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0,
|
||||
time.Unix(5, 0), sdk.NewInt(10), 0)
|
||||
|
||||
f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd)
|
||||
assert.NilError(t, f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd))
|
||||
|
||||
// unbonding started prior to the infraction height, stakw didn't contribute
|
||||
slashAmount := f.stakingKeeper.SlashUnbondingDelegation(f.sdkCtx, ubd, 1, fraction)
|
||||
slashAmount, err := f.stakingKeeper.SlashUnbondingDelegation(f.sdkCtx, ubd, 1, fraction)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, slashAmount.Equal(sdk.NewInt(0)))
|
||||
|
||||
// after the expiration time, no longer eligible for slashing
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeader(cmtproto.Header{Time: time.Unix(10, 0)})
|
||||
f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd)
|
||||
slashAmount = f.stakingKeeper.SlashUnbondingDelegation(f.sdkCtx, ubd, 0, fraction)
|
||||
assert.NilError(t, f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd))
|
||||
slashAmount, err = f.stakingKeeper.SlashUnbondingDelegation(f.sdkCtx, ubd, 0, fraction)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, slashAmount.Equal(sdk.NewInt(0)))
|
||||
|
||||
// test valid slash, before expiration timestamp and to which stake contributed
|
||||
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
|
||||
oldUnbondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, notBondedPool.GetAddress())
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeader(cmtproto.Header{Time: time.Unix(0, 0)})
|
||||
f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd)
|
||||
slashAmount = f.stakingKeeper.SlashUnbondingDelegation(f.sdkCtx, ubd, 0, fraction)
|
||||
assert.NilError(t, f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd))
|
||||
slashAmount, err = f.stakingKeeper.SlashUnbondingDelegation(f.sdkCtx, ubd, 0, fraction)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, slashAmount.Equal(sdk.NewInt(5)))
|
||||
ubd, found := f.stakingKeeper.GetUnbondingDelegation(f.sdkCtx, addrDels[0], addrVals[0])
|
||||
assert.Assert(t, found)
|
||||
@ -90,7 +95,9 @@ func TestSlashUnbondingDelegation(t *testing.T) {
|
||||
assert.DeepEqual(t, sdk.NewInt(5), ubd.Entries[0].Balance)
|
||||
newUnbondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, notBondedPool.GetAddress())
|
||||
diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances...)
|
||||
assert.Assert(t, diffTokens.AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx)).Equal(sdk.NewInt(5)))
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, diffTokens.AmountOf(bondDenom).Equal(sdk.NewInt(5)))
|
||||
}
|
||||
|
||||
// tests slashRedelegation
|
||||
@ -98,8 +105,11 @@ func TestSlashRedelegation(t *testing.T) {
|
||||
f, addrDels, addrVals := bootstrapSlashTest(t, 10)
|
||||
fraction := sdk.NewDecWithPrec(5, 1)
|
||||
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// add bonded tokens to pool for (re)delegations
|
||||
startCoins := sdk.NewCoins(sdk.NewInt64Coin(f.stakingKeeper.BondDenom(f.sdkCtx), 15))
|
||||
startCoins := sdk.NewCoins(sdk.NewInt64Coin(bondDenom, 15))
|
||||
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
|
||||
_ = f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
|
||||
|
||||
@ -111,34 +121,37 @@ func TestSlashRedelegation(t *testing.T) {
|
||||
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0,
|
||||
time.Unix(5, 0), sdk.NewInt(10), math.LegacyNewDec(10), 0)
|
||||
|
||||
f.stakingKeeper.SetRedelegation(f.sdkCtx, rd)
|
||||
assert.NilError(t, f.stakingKeeper.SetRedelegation(f.sdkCtx, rd))
|
||||
|
||||
// set the associated delegation
|
||||
del := types.NewDelegation(addrDels[0], addrVals[1], math.LegacyNewDec(10))
|
||||
f.stakingKeeper.SetDelegation(f.sdkCtx, del)
|
||||
assert.NilError(t, f.stakingKeeper.SetDelegation(f.sdkCtx, del))
|
||||
|
||||
// started redelegating prior to the current height, stake didn't contribute to infraction
|
||||
validator, found := f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
|
||||
assert.Assert(t, found)
|
||||
slashAmount := f.stakingKeeper.SlashRedelegation(f.sdkCtx, validator, rd, 1, fraction)
|
||||
slashAmount, err := f.stakingKeeper.SlashRedelegation(f.sdkCtx, validator, rd, 1, fraction)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, slashAmount.Equal(sdk.NewInt(0)))
|
||||
|
||||
// after the expiration time, no longer eligible for slashing
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeader(cmtproto.Header{Time: time.Unix(10, 0)})
|
||||
f.stakingKeeper.SetRedelegation(f.sdkCtx, rd)
|
||||
assert.NilError(t, f.stakingKeeper.SetRedelegation(f.sdkCtx, rd))
|
||||
validator, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
|
||||
assert.Assert(t, found)
|
||||
slashAmount = f.stakingKeeper.SlashRedelegation(f.sdkCtx, validator, rd, 0, fraction)
|
||||
slashAmount, err = f.stakingKeeper.SlashRedelegation(f.sdkCtx, validator, rd, 0, fraction)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, slashAmount.Equal(sdk.NewInt(0)))
|
||||
|
||||
balances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
|
||||
|
||||
// test valid slash, before expiration timestamp and to which stake contributed
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeader(cmtproto.Header{Time: time.Unix(0, 0)})
|
||||
f.stakingKeeper.SetRedelegation(f.sdkCtx, rd)
|
||||
assert.NilError(t, f.stakingKeeper.SetRedelegation(f.sdkCtx, rd))
|
||||
validator, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
|
||||
assert.Assert(t, found)
|
||||
slashAmount = f.stakingKeeper.SlashRedelegation(f.sdkCtx, validator, rd, 0, fraction)
|
||||
slashAmount, err = f.stakingKeeper.SlashRedelegation(f.sdkCtx, validator, rd, 0, fraction)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, slashAmount.Equal(sdk.NewInt(5)))
|
||||
rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1])
|
||||
assert.Assert(t, found)
|
||||
@ -156,7 +169,7 @@ func TestSlashRedelegation(t *testing.T) {
|
||||
assert.Equal(t, int64(5), del.Shares.RoundInt64())
|
||||
|
||||
// pool bonded tokens should decrease
|
||||
burnedCoins := sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), slashAmount))
|
||||
burnedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, slashAmount))
|
||||
assert.DeepEqual(t, balances.Sub(burnedCoins...), f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress()))
|
||||
}
|
||||
|
||||
@ -172,7 +185,8 @@ func TestSlashAtNegativeHeight(t *testing.T) {
|
||||
|
||||
_, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
|
||||
assert.Assert(t, found)
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr, -2, 10, fraction)
|
||||
_, err := f.stakingKeeper.Slash(f.sdkCtx, consAddr, -2, 10, fraction)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// read updated state
|
||||
validator, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
|
||||
@ -186,9 +200,12 @@ func TestSlashAtNegativeHeight(t *testing.T) {
|
||||
// power decreased
|
||||
assert.Equal(t, int64(5), validator.GetConsensusPower(f.stakingKeeper.PowerReduction(f.sdkCtx)))
|
||||
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// pool bonded shares decreased
|
||||
newBondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
|
||||
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
|
||||
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(bondDenom)
|
||||
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 5).String(), diffTokens.String())
|
||||
}
|
||||
|
||||
@ -198,12 +215,16 @@ func TestSlashValidatorAtCurrentHeight(t *testing.T) {
|
||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||
fraction := sdk.NewDecWithPrec(5, 1)
|
||||
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
|
||||
oldBondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
|
||||
|
||||
_, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
|
||||
assert.Assert(t, found)
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr, f.sdkCtx.BlockHeight(), 10, fraction)
|
||||
_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr, f.sdkCtx.BlockHeight(), 10, fraction)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// read updated state
|
||||
validator, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
|
||||
@ -219,7 +240,7 @@ func TestSlashValidatorAtCurrentHeight(t *testing.T) {
|
||||
|
||||
// pool bonded shares decreased
|
||||
newBondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
|
||||
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
|
||||
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(bondDenom)
|
||||
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 5).String(), diffTokens.String())
|
||||
}
|
||||
|
||||
@ -230,11 +251,14 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||
fraction := sdk.NewDecWithPrec(5, 1)
|
||||
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// set an unbonding delegation with expiration timestamp beyond which the
|
||||
// unbonding delegation shouldn't be slashed
|
||||
ubdTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 4)
|
||||
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, time.Unix(0, 0), ubdTokens, 0)
|
||||
f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd)
|
||||
assert.NilError(t, f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubd))
|
||||
|
||||
// slash validator for the first time
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(12)
|
||||
@ -243,7 +267,8 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||
|
||||
_, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
|
||||
assert.Assert(t, found)
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, fraction)
|
||||
_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, fraction)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// end block
|
||||
applyValidatorSetUpdates(t, f.sdkCtx, f.stakingKeeper, 1)
|
||||
@ -258,7 +283,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||
|
||||
// bonded tokens burned
|
||||
newBondedPoolBalances := f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
|
||||
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
|
||||
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(bondDenom)
|
||||
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 3), diffTokens)
|
||||
|
||||
// read updated validator
|
||||
@ -273,7 +298,8 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||
|
||||
// slash validator again
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(13)
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 9, 10, fraction)
|
||||
_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr, 9, 10, fraction)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ubd, found = f.stakingKeeper.GetUnbondingDelegation(f.sdkCtx, addrDels[0], addrVals[0])
|
||||
assert.Assert(t, found)
|
||||
@ -284,7 +310,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||
|
||||
// bonded tokens burned again
|
||||
newBondedPoolBalances = f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
|
||||
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
|
||||
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(bondDenom)
|
||||
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 6), diffTokens)
|
||||
|
||||
// read updated validator
|
||||
@ -299,7 +325,8 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||
// on the unbonding delegation, but it will slash stake bonded since the infraction
|
||||
// this may not be the desirable behavior, ref https://github.com/cosmos/cosmos-sdk/issues/1440
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(13)
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 9, 10, fraction)
|
||||
_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr, 9, 10, fraction)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ubd, found = f.stakingKeeper.GetUnbondingDelegation(f.sdkCtx, addrDels[0], addrVals[0])
|
||||
assert.Assert(t, found)
|
||||
@ -310,7 +337,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||
|
||||
// bonded tokens burned again
|
||||
newBondedPoolBalances = f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
|
||||
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
|
||||
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(bondDenom)
|
||||
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 9), diffTokens)
|
||||
|
||||
// read updated validator
|
||||
@ -325,7 +352,8 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||
// on the unbonding delegation, but it will slash stake bonded since the infraction
|
||||
// this may not be the desirable behavior, ref https://github.com/cosmos/cosmos-sdk/issues/1440
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(13)
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 9, 10, fraction)
|
||||
_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr, 9, 10, fraction)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ubd, found = f.stakingKeeper.GetUnbondingDelegation(f.sdkCtx, addrDels[0], addrVals[0])
|
||||
assert.Assert(t, found)
|
||||
@ -336,7 +364,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||
|
||||
// just 1 bonded token burned again since that's all the validator now has
|
||||
newBondedPoolBalances = f.bankKeeper.GetAllBalances(f.sdkCtx, bondedPool.GetAddress())
|
||||
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(f.stakingKeeper.BondDenom(f.sdkCtx))
|
||||
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances...).AmountOf(bondDenom)
|
||||
assert.DeepEqual(t, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10), diffTokens)
|
||||
|
||||
// apply TM updates
|
||||
@ -354,16 +382,17 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||
f, addrDels, addrVals := bootstrapSlashTest(t, 10)
|
||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||
fraction := sdk.NewDecWithPrec(5, 1)
|
||||
bondDenom := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// set a redelegation
|
||||
rdTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 6)
|
||||
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, time.Unix(0, 0), rdTokens, sdk.NewDecFromInt(rdTokens), 0)
|
||||
f.stakingKeeper.SetRedelegation(f.sdkCtx, rd)
|
||||
assert.NilError(t, f.stakingKeeper.SetRedelegation(f.sdkCtx, rd))
|
||||
|
||||
// set the associated delegation
|
||||
del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDecFromInt(rdTokens))
|
||||
f.stakingKeeper.SetDelegation(f.sdkCtx, del)
|
||||
assert.NilError(t, f.stakingKeeper.SetDelegation(f.sdkCtx, del))
|
||||
|
||||
// update bonded tokens
|
||||
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
|
||||
@ -382,9 +411,9 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||
_, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
|
||||
assert.Assert(t, found)
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, fraction)
|
||||
})
|
||||
_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, fraction)
|
||||
assert.NilError(t, err)
|
||||
|
||||
burnAmount := sdk.NewDecFromInt(f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10)).Mul(fraction).TruncateInt()
|
||||
|
||||
bondedPool = f.stakingKeeper.GetBondedPool(f.sdkCtx)
|
||||
@ -415,9 +444,8 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||
_, found = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
|
||||
assert.Assert(t, found)
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, math.LegacyOneDec())
|
||||
})
|
||||
_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, math.LegacyOneDec())
|
||||
assert.NilError(t, err)
|
||||
burnAmount = f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 7)
|
||||
|
||||
// read updated pool
|
||||
@ -451,9 +479,8 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||
_, found = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
|
||||
assert.Assert(t, found)
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, math.LegacyOneDec())
|
||||
})
|
||||
_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, math.LegacyOneDec())
|
||||
assert.NilError(t, err)
|
||||
|
||||
burnAmount = sdk.NewDecFromInt(f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10)).Mul(math.LegacyOneDec()).TruncateInt()
|
||||
burnAmount = burnAmount.Sub(math.LegacyOneDec().MulInt(rdTokens).TruncateInt())
|
||||
@ -486,9 +513,8 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||
validator, _ = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
|
||||
assert.Equal(t, validator.GetStatus(), types.Unbonding)
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, math.LegacyOneDec())
|
||||
})
|
||||
_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, math.LegacyOneDec())
|
||||
assert.NilError(t, err)
|
||||
|
||||
// read updated pool
|
||||
bondedPool = f.stakingKeeper.GetBondedPool(f.sdkCtx)
|
||||
@ -513,24 +539,25 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||
func TestSlashBoth(t *testing.T) {
|
||||
f, addrDels, addrVals := bootstrapSlashTest(t, 10)
|
||||
fraction := sdk.NewDecWithPrec(5, 1)
|
||||
bondDenom := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// set a redelegation with expiration timestamp beyond which the
|
||||
// redelegation shouldn't be slashed
|
||||
rdATokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 6)
|
||||
rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, time.Unix(0, 0), rdATokens, sdk.NewDecFromInt(rdATokens), 0)
|
||||
f.stakingKeeper.SetRedelegation(f.sdkCtx, rdA)
|
||||
assert.NilError(t, f.stakingKeeper.SetRedelegation(f.sdkCtx, rdA))
|
||||
|
||||
// set the associated delegation
|
||||
delA := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDecFromInt(rdATokens))
|
||||
f.stakingKeeper.SetDelegation(f.sdkCtx, delA)
|
||||
assert.NilError(t, f.stakingKeeper.SetDelegation(f.sdkCtx, delA))
|
||||
|
||||
// set an unbonding delegation with expiration timestamp (beyond which the
|
||||
// unbonding delegation shouldn't be slashed)
|
||||
ubdATokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 4)
|
||||
ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
|
||||
time.Unix(0, 0), ubdATokens, 0)
|
||||
f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubdA)
|
||||
assert.NilError(t, f.stakingKeeper.SetUnbondingDelegation(f.sdkCtx, ubdA))
|
||||
|
||||
bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdATokens.MulRaw(2)))
|
||||
notBondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, ubdATokens))
|
||||
@ -552,7 +579,8 @@ func TestSlashBoth(t *testing.T) {
|
||||
_, found := f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, sdk.GetConsAddress(PKs[0]))
|
||||
assert.Assert(t, found)
|
||||
consAddr0 := sdk.ConsAddress(PKs[0].Address())
|
||||
f.stakingKeeper.Slash(f.sdkCtx, consAddr0, 10, 10, fraction)
|
||||
_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr0, 10, 10, fraction)
|
||||
assert.NilError(t, err)
|
||||
|
||||
burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt()
|
||||
burnedBondAmount := sdk.NewDecFromInt(f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10)).Mul(fraction).TruncateInt()
|
||||
@ -583,11 +611,13 @@ func TestSlashAmount(t *testing.T) {
|
||||
f, _, _ := bootstrapSlashTest(t, 10)
|
||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||
fraction := sdk.NewDecWithPrec(5, 1)
|
||||
burnedCoins := f.stakingKeeper.Slash(f.sdkCtx, consAddr, f.sdkCtx.BlockHeight(), 10, fraction)
|
||||
burnedCoins, err := f.stakingKeeper.Slash(f.sdkCtx, consAddr, f.sdkCtx.BlockHeight(), 10, fraction)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, burnedCoins.GT(math.ZeroInt()))
|
||||
|
||||
// test the case where the validator was not found, which should return no coins
|
||||
_, addrVals := generateAddresses(f, 100)
|
||||
noBurned := f.stakingKeeper.Slash(f.sdkCtx, sdk.ConsAddress(addrVals[0]), f.sdkCtx.BlockHeight(), 10, fraction)
|
||||
noBurned, err := f.stakingKeeper.Slash(f.sdkCtx, sdk.ConsAddress(addrVals[0]), f.sdkCtx.BlockHeight(), 10, fraction)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, sdk.NewInt(0).Equal(noBurned))
|
||||
}
|
||||
|
||||
@ -49,11 +49,11 @@ func SetupUnbondingTests(t *testing.T, f *fixture, hookCalled *bool, ubdeID *uin
|
||||
valTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10)
|
||||
startTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 20)
|
||||
|
||||
bondDenom = f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
|
||||
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
|
||||
f.bankKeeper.SendCoinsFromModuleToModule(f.sdkCtx, types.BondedPoolName, types.NotBondedPoolName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, startTokens)))
|
||||
f.accountKeeper.SetModuleAccount(f.sdkCtx, notBondedPool)
|
||||
|
||||
// Create a validator
|
||||
@ -67,7 +67,7 @@ func SetupUnbondingTests(t *testing.T, f *fixture, hookCalled *bool, ubdeID *uin
|
||||
|
||||
// Create a delegator
|
||||
delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares1)
|
||||
f.stakingKeeper.SetDelegation(f.sdkCtx, delegation)
|
||||
assert.NilError(t, f.stakingKeeper.SetDelegation(f.sdkCtx, delegation))
|
||||
|
||||
// Create a validator to redelegate to
|
||||
validator2 := testutil.NewValidator(t, addrVals[1], PKs[1])
|
||||
@ -110,7 +110,8 @@ func doUnbondingDelegation(
|
||||
assert.Assert(math.IntEq(t, notBondedAmt1.AddRaw(1), notBondedAmt2))
|
||||
|
||||
// Check that the unbonding happened- we look up the entry and see that it has the correct number of shares
|
||||
unbondingDelegations := stakingKeeper.GetUnbondingDelegationsFromValidator(ctx, addrVals[0])
|
||||
unbondingDelegations, err := stakingKeeper.GetUnbondingDelegationsFromValidator(ctx, addrVals[0])
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, math.NewInt(1), unbondingDelegations[0].Entries[0].Balance)
|
||||
|
||||
// check that our hook was called
|
||||
@ -132,7 +133,8 @@ func doRedelegation(
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Check that the redelegation happened- we look up the entry and see that it has the correct number of shares
|
||||
redelegations := stakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
|
||||
redelegations, err := stakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 1, len(redelegations))
|
||||
assert.DeepEqual(t, math.LegacyNewDec(1), redelegations[0].Entries[0].SharesDst)
|
||||
|
||||
@ -188,26 +190,28 @@ func TestValidatorUnbondingOnHold1(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Try to unbond validator
|
||||
f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx)
|
||||
assert.NilError(t, f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx))
|
||||
|
||||
// Check that validator unbonding is not complete (is not mature yet)
|
||||
validator, found := f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[0])
|
||||
assert.Assert(t, found)
|
||||
assert.Equal(t, types.Unbonding, validator.Status)
|
||||
unbondingVals := f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
|
||||
unbondingVals, err := f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 1, len(unbondingVals))
|
||||
assert.Equal(t, validator.OperatorAddress, unbondingVals[0])
|
||||
|
||||
// PROVIDER CHAIN'S UNBONDING PERIOD ENDS - BUT UNBONDING CANNOT COMPLETE
|
||||
f.sdkCtx = f.sdkCtx.WithBlockTime(completionTime.Add(time.Duration(1)))
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(completionHeight + 1)
|
||||
f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx)
|
||||
assert.NilError(t, f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx))
|
||||
|
||||
// Check that validator unbonding is complete
|
||||
validator, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[0])
|
||||
assert.Assert(t, found)
|
||||
assert.Equal(t, types.Unbonded, validator.Status)
|
||||
unbondingVals = f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
|
||||
unbondingVals, err = f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 0, len(unbondingVals))
|
||||
}
|
||||
|
||||
@ -246,7 +250,7 @@ func TestValidatorUnbondingOnHold2(t *testing.T) {
|
||||
// PROVIDER CHAIN'S UNBONDING PERIOD ENDS - BUT UNBONDING CANNOT COMPLETE
|
||||
f.sdkCtx = f.sdkCtx.WithBlockTime(completionTime.Add(time.Duration(1)))
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(completionHeight + 1)
|
||||
f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx)
|
||||
assert.NilError(t, f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx))
|
||||
|
||||
// Check that unbonding is not complete for both validators
|
||||
validator1, found := f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[0])
|
||||
@ -255,17 +259,18 @@ func TestValidatorUnbondingOnHold2(t *testing.T) {
|
||||
validator2, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
|
||||
assert.Assert(t, found)
|
||||
assert.Equal(t, types.Unbonding, validator2.Status)
|
||||
unbondingVals := f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
|
||||
unbondingVals, err := f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 2, len(unbondingVals))
|
||||
assert.Equal(t, validator1.OperatorAddress, unbondingVals[0])
|
||||
assert.Equal(t, validator2.OperatorAddress, unbondingVals[1])
|
||||
|
||||
// CONSUMER CHAIN'S UNBONDING PERIOD ENDS - STOPPED UNBONDING CAN NOW COMPLETE
|
||||
err := f.stakingKeeper.UnbondingCanComplete(f.sdkCtx, ubdeIDs[0])
|
||||
err = f.stakingKeeper.UnbondingCanComplete(f.sdkCtx, ubdeIDs[0])
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Try again to unbond validators
|
||||
f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx)
|
||||
assert.NilError(t, f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx))
|
||||
|
||||
// Check that unbonding is complete for validator1, but not for validator2
|
||||
validator1, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[0])
|
||||
@ -274,7 +279,8 @@ func TestValidatorUnbondingOnHold2(t *testing.T) {
|
||||
validator2, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
|
||||
assert.Assert(t, found)
|
||||
assert.Equal(t, types.Unbonding, validator2.Status)
|
||||
unbondingVals = f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
|
||||
unbondingVals, err = f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 1, len(unbondingVals))
|
||||
assert.Equal(t, validator2.OperatorAddress, unbondingVals[0])
|
||||
|
||||
@ -283,13 +289,14 @@ func TestValidatorUnbondingOnHold2(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Try again to unbond validators
|
||||
f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx)
|
||||
assert.NilError(t, f.stakingKeeper.UnbondAllMatureValidators(f.sdkCtx))
|
||||
|
||||
// Check that unbonding is complete for validator2
|
||||
validator2, found = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[1])
|
||||
assert.Assert(t, found)
|
||||
assert.Equal(t, types.Unbonded, validator2.Status)
|
||||
unbondingVals = f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
|
||||
unbondingVals, err = f.stakingKeeper.GetUnbondingValidators(f.sdkCtx, completionTime, completionHeight)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 0, len(unbondingVals))
|
||||
}
|
||||
|
||||
@ -311,7 +318,8 @@ func TestRedelegationOnHold1(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Redelegation is not complete - still exists
|
||||
redelegations := f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
|
||||
redelegations, err := f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 1, len(redelegations))
|
||||
|
||||
// PROVIDER CHAIN'S UNBONDING PERIOD ENDS - STOPPED UNBONDING CAN NOW COMPLETE
|
||||
@ -320,7 +328,8 @@ func TestRedelegationOnHold1(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Redelegation is complete and record is gone
|
||||
redelegations = f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
|
||||
redelegations, err = f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 0, len(redelegations))
|
||||
}
|
||||
|
||||
@ -343,7 +352,8 @@ func TestRedelegationOnHold2(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Redelegation is not complete - still exists
|
||||
redelegations := f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
|
||||
redelegations, err := f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 1, len(redelegations))
|
||||
|
||||
// CONSUMER CHAIN'S UNBONDING PERIOD ENDS - STOPPED UNBONDING CAN NOW COMPLETE
|
||||
@ -351,7 +361,8 @@ func TestRedelegationOnHold2(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Redelegation is complete and record is gone
|
||||
redelegations = f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
|
||||
redelegations, err = f.stakingKeeper.GetRedelegationsFromSrcValidator(f.sdkCtx, addrVals[0])
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 0, len(redelegations))
|
||||
}
|
||||
|
||||
|
||||
@ -28,8 +28,11 @@ func bootstrapValidatorTest(t testing.TB, power int64, numAddrs int) (*fixture,
|
||||
|
||||
addrDels, addrVals := generateAddresses(f, numAddrs)
|
||||
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
amt := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, power)
|
||||
totalSupply := sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), amt.MulRaw(int64(len(addrDels)))))
|
||||
totalSupply := sdk.NewCoins(sdk.NewCoin(bondDenom, amt.MulRaw(int64(len(addrDels)))))
|
||||
|
||||
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
|
||||
|
||||
@ -65,13 +68,17 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) {
|
||||
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
|
||||
|
||||
// create keeper parameters
|
||||
params := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
params, err := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
params.MaxValidators = uint32(maxVals)
|
||||
f.stakingKeeper.SetParams(f.sdkCtx, params)
|
||||
assert.NilError(t, f.stakingKeeper.SetParams(f.sdkCtx, params))
|
||||
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// create a random pool
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 1234)))))
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10000)))))
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 1234)))))
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 10000)))))
|
||||
|
||||
f.accountKeeper.SetModuleAccount(f.sdkCtx, bondedPool)
|
||||
f.accountKeeper.SetModuleAccount(f.sdkCtx, notBondedPool)
|
||||
@ -124,8 +131,9 @@ func TestSlashToZeroPowerRemoved(t *testing.T) {
|
||||
valTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 100)
|
||||
|
||||
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
|
||||
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), valTokens))))
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, valTokens))))
|
||||
|
||||
f.accountKeeper.SetModuleAccount(f.sdkCtx, bondedPool)
|
||||
|
||||
@ -168,7 +176,8 @@ func TestGetValidatorSortingUnmixed(t *testing.T) {
|
||||
}
|
||||
|
||||
// first make sure everything made it in to the gotValidator group
|
||||
resValidators := f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err := f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, n, len(resValidators))
|
||||
assert.DeepEqual(t, sdk.NewInt(400).Mul(f.stakingKeeper.PowerReduction(f.sdkCtx)), resValidators[0].BondedTokens())
|
||||
assert.DeepEqual(t, sdk.NewInt(200).Mul(f.stakingKeeper.PowerReduction(f.sdkCtx)), resValidators[1].BondedTokens())
|
||||
@ -184,14 +193,16 @@ func TestGetValidatorSortingUnmixed(t *testing.T) {
|
||||
// test a basic increase in voting power
|
||||
validators[3].Tokens = sdk.NewInt(500).Mul(f.stakingKeeper.PowerReduction(f.sdkCtx))
|
||||
keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[3], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(resValidators), n)
|
||||
assert.Assert(ValEq(t, validators[3], resValidators[0]))
|
||||
|
||||
// test a decrease in voting power
|
||||
validators[3].Tokens = sdk.NewInt(300).Mul(f.stakingKeeper.PowerReduction(f.sdkCtx))
|
||||
keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[3], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(resValidators), n)
|
||||
assert.Assert(ValEq(t, validators[3], resValidators[0]))
|
||||
assert.Assert(ValEq(t, validators[4], resValidators[1]))
|
||||
@ -200,7 +211,8 @@ func TestGetValidatorSortingUnmixed(t *testing.T) {
|
||||
validators[3].Tokens = sdk.NewInt(200).Mul(f.stakingKeeper.PowerReduction(f.sdkCtx))
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(10)
|
||||
keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[3], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(resValidators), n)
|
||||
assert.Assert(ValEq(t, validators[3], resValidators[0]))
|
||||
assert.Assert(ValEq(t, validators[4], resValidators[1]))
|
||||
@ -208,7 +220,8 @@ func TestGetValidatorSortingUnmixed(t *testing.T) {
|
||||
// no change in voting power - no change in sort
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(20)
|
||||
keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[4], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(resValidators), n)
|
||||
assert.Assert(ValEq(t, validators[3], resValidators[0]))
|
||||
assert.Assert(ValEq(t, validators[4], resValidators[1]))
|
||||
@ -217,11 +230,13 @@ func TestGetValidatorSortingUnmixed(t *testing.T) {
|
||||
validators[3].Tokens = sdk.NewInt(300).Mul(f.stakingKeeper.PowerReduction(f.sdkCtx))
|
||||
validators[4].Tokens = sdk.NewInt(300).Mul(f.stakingKeeper.PowerReduction(f.sdkCtx))
|
||||
keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[3], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(resValidators), n)
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(30)
|
||||
keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[4], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(resValidators), n, "%v", resValidators)
|
||||
assert.Assert(ValEq(t, validators[3], resValidators[0]))
|
||||
assert.Assert(ValEq(t, validators[4], resValidators[1]))
|
||||
@ -232,16 +247,20 @@ func TestGetValidatorSortingMixed(t *testing.T) {
|
||||
bondedPool := f.stakingKeeper.GetBondedPool(f.sdkCtx)
|
||||
notBondedPool := f.stakingKeeper.GetNotBondedPool(f.sdkCtx)
|
||||
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 501)))))
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.BondDenom(f.sdkCtx), f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 0)))))
|
||||
bondDenom, err := f.stakingKeeper.BondDenom(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 501)))))
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(f.sdkCtx, f.bankKeeper, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 0)))))
|
||||
|
||||
f.accountKeeper.SetModuleAccount(f.sdkCtx, notBondedPool)
|
||||
f.accountKeeper.SetModuleAccount(f.sdkCtx, bondedPool)
|
||||
|
||||
// now 2 max resValidators
|
||||
params := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
params, err := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
params.MaxValidators = 2
|
||||
f.stakingKeeper.SetParams(f.sdkCtx, params)
|
||||
assert.NilError(t, f.stakingKeeper.SetParams(f.sdkCtx, params))
|
||||
|
||||
// initialize some validators into the state
|
||||
amts := []math.Int{
|
||||
@ -278,7 +297,8 @@ func TestGetValidatorSortingMixed(t *testing.T) {
|
||||
assert.Equal(t, types.Bonded, val4.Status)
|
||||
|
||||
// first make sure everything made it in to the gotValidator group
|
||||
resValidators := f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err := f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
// The validators returned should match the max validators
|
||||
assert.Equal(t, 2, len(resValidators))
|
||||
assert.DeepEqual(t, sdk.NewInt(400).Mul(f.stakingKeeper.PowerReduction(f.sdkCtx)), resValidators[0].BondedTokens())
|
||||
@ -292,7 +312,8 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||
f, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
|
||||
|
||||
// set max validators to 2
|
||||
params := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
params, err := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
nMax := uint32(2)
|
||||
params.MaxValidators = nMax
|
||||
f.stakingKeeper.SetParams(f.sdkCtx, params)
|
||||
@ -314,7 +335,8 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||
}
|
||||
|
||||
// ensure that the first two bonded validators are the largest validators
|
||||
resValidators := f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err := f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, nMax, uint32(len(resValidators)))
|
||||
assert.Assert(ValEq(t, validators[2], resValidators[0]))
|
||||
assert.Assert(ValEq(t, validators[3], resValidators[1]))
|
||||
@ -334,7 +356,8 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||
// a) validator 0 with 500 tokens
|
||||
// b) validator 2 with 400 tokens (delegated before validator 3)
|
||||
validators[0] = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[0], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, nMax, uint32(len(resValidators)))
|
||||
assert.Assert(ValEq(t, validators[0], resValidators[0]))
|
||||
assert.Assert(ValEq(t, validators[2], resValidators[1]))
|
||||
@ -351,9 +374,8 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||
// validator 3 enters bonded validator set
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(40)
|
||||
|
||||
var found bool
|
||||
validators[3], found = f.stakingKeeper.GetValidator(f.sdkCtx, validators[3].GetOperator())
|
||||
assert.Assert(t, found)
|
||||
validators[3], err = f.stakingKeeper.GetValidator(f.sdkCtx, validators[3].GetOperator())
|
||||
assert.NilError(t, err)
|
||||
f.stakingKeeper.DeleteValidatorByPowerIndex(f.sdkCtx, validators[3])
|
||||
validators[3], _ = validators[3].AddTokensFromDel(f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 1))
|
||||
|
||||
@ -363,7 +385,8 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||
f.accountKeeper.SetModuleAccount(f.sdkCtx, notBondedPool)
|
||||
|
||||
validators[3] = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[3], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, nMax, uint32(len(resValidators)))
|
||||
assert.Assert(ValEq(t, validators[0], resValidators[0]))
|
||||
assert.Assert(ValEq(t, validators[3], resValidators[1]))
|
||||
@ -378,7 +401,8 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||
f.accountKeeper.SetModuleAccount(f.sdkCtx, bondedPool)
|
||||
|
||||
validators[3] = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[3], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, nMax, uint32(len(resValidators)))
|
||||
assert.Assert(ValEq(t, validators[0], resValidators[0]))
|
||||
assert.Assert(ValEq(t, validators[2], resValidators[1]))
|
||||
@ -392,7 +416,8 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||
f.accountKeeper.SetModuleAccount(f.sdkCtx, notBondedPool)
|
||||
|
||||
validators[3] = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[3], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, nMax, uint32(len(resValidators)))
|
||||
assert.Assert(ValEq(t, validators[0], resValidators[0]))
|
||||
assert.Assert(ValEq(t, validators[2], resValidators[1]))
|
||||
@ -404,7 +429,8 @@ func TestValidatorBondHeight(t *testing.T) {
|
||||
f, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
|
||||
|
||||
// now 2 max resValidators
|
||||
params := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
params, err := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
params.MaxValidators = 2
|
||||
f.stakingKeeper.SetParams(f.sdkCtx, params)
|
||||
|
||||
@ -429,7 +455,8 @@ func TestValidatorBondHeight(t *testing.T) {
|
||||
validators[1] = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[1], true)
|
||||
validators[2] = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[2], true)
|
||||
|
||||
resValidators := f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err := f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, uint32(len(resValidators)), params.MaxValidators)
|
||||
|
||||
assert.Assert(ValEq(t, validators[0], resValidators[0]))
|
||||
@ -440,7 +467,8 @@ func TestValidatorBondHeight(t *testing.T) {
|
||||
validators[1], _ = validators[1].AddTokensFromDel(delTokens)
|
||||
validators[2], _ = validators[2].AddTokensFromDel(delTokens)
|
||||
validators[2] = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[2], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, params.MaxValidators, uint32(len(resValidators)))
|
||||
validators[1] = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[1], true)
|
||||
assert.Assert(ValEq(t, validators[0], resValidators[0]))
|
||||
@ -449,10 +477,11 @@ func TestValidatorBondHeight(t *testing.T) {
|
||||
|
||||
func TestFullValidatorSetPowerChange(t *testing.T) {
|
||||
f, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
|
||||
params := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
params, err := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
max := 2
|
||||
params.MaxValidators = uint32(2)
|
||||
f.stakingKeeper.SetParams(f.sdkCtx, params)
|
||||
assert.NilError(t, f.stakingKeeper.SetParams(f.sdkCtx, params))
|
||||
|
||||
// initialize some validators into the state
|
||||
powers := []int64{0, 100, 400, 400, 200}
|
||||
@ -464,16 +493,16 @@ func TestFullValidatorSetPowerChange(t *testing.T) {
|
||||
keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[i], true)
|
||||
}
|
||||
for i := range powers {
|
||||
var found bool
|
||||
validators[i], found = f.stakingKeeper.GetValidator(f.sdkCtx, validators[i].GetOperator())
|
||||
assert.Assert(t, found)
|
||||
validators[i], err = f.stakingKeeper.GetValidator(f.sdkCtx, validators[i].GetOperator())
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
assert.Equal(t, types.Unbonded, validators[0].Status)
|
||||
assert.Equal(t, types.Unbonding, validators[1].Status)
|
||||
assert.Equal(t, types.Bonded, validators[2].Status)
|
||||
assert.Equal(t, types.Bonded, validators[3].Status)
|
||||
assert.Equal(t, types.Unbonded, validators[4].Status)
|
||||
resValidators := f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err := f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, max, len(resValidators))
|
||||
assert.Assert(ValEq(t, validators[2], resValidators[0])) // in the order of txs
|
||||
assert.Assert(ValEq(t, validators[3], resValidators[1]))
|
||||
@ -483,7 +512,8 @@ func TestFullValidatorSetPowerChange(t *testing.T) {
|
||||
tokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 600)
|
||||
validators[0], _ = validators[0].AddTokensFromDel(tokens)
|
||||
validators[0] = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, validators[0], true)
|
||||
resValidators = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
resValidators, err = f.stakingKeeper.GetBondedValidatorsByPower(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, max, len(resValidators))
|
||||
assert.Assert(ValEq(t, validators[0], resValidators[0]))
|
||||
assert.Assert(ValEq(t, validators[2], resValidators[1]))
|
||||
@ -661,10 +691,11 @@ func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) {
|
||||
|
||||
func TestApplyAndReturnValidatorSetUpdatesNewValidator(t *testing.T) {
|
||||
f, _, _ := bootstrapValidatorTest(t, 1000, 20)
|
||||
params := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
params, err := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
params.MaxValidators = uint32(3)
|
||||
|
||||
f.stakingKeeper.SetParams(f.sdkCtx, params)
|
||||
assert.NilError(t, f.stakingKeeper.SetParams(f.sdkCtx, params))
|
||||
|
||||
powers := []int64{100, 100}
|
||||
var validators [2]types.Validator
|
||||
@ -739,10 +770,11 @@ func TestApplyAndReturnValidatorSetUpdatesNewValidator(t *testing.T) {
|
||||
|
||||
func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) {
|
||||
f, _, _ := bootstrapValidatorTest(t, 1000, 20)
|
||||
params := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
params, err := f.stakingKeeper.GetParams(f.sdkCtx)
|
||||
assert.NilError(t, err)
|
||||
params.MaxValidators = uint32(2)
|
||||
|
||||
f.stakingKeeper.SetParams(f.sdkCtx, params)
|
||||
assert.NilError(t, f.stakingKeeper.SetParams(f.sdkCtx, params))
|
||||
|
||||
powers := []int64{100, 200, 300}
|
||||
var validators [3]types.Validator
|
||||
@ -772,9 +804,8 @@ func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) {
|
||||
// delegate to validator with lowest power but not enough to bond
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(1)
|
||||
|
||||
var found bool
|
||||
validators[0], found = f.stakingKeeper.GetValidator(f.sdkCtx, validators[0].GetOperator())
|
||||
assert.Assert(t, found)
|
||||
validators[0], err = f.stakingKeeper.GetValidator(f.sdkCtx, validators[0].GetOperator())
|
||||
assert.NilError(t, err)
|
||||
|
||||
f.stakingKeeper.DeleteValidatorByPowerIndex(f.sdkCtx, validators[0])
|
||||
tokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, 1)
|
||||
@ -789,8 +820,8 @@ func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) {
|
||||
// lowest power in a single block context (height)
|
||||
f.sdkCtx = f.sdkCtx.WithBlockHeight(2)
|
||||
|
||||
validators[1], found = f.stakingKeeper.GetValidator(f.sdkCtx, validators[1].GetOperator())
|
||||
assert.Assert(t, found)
|
||||
validators[1], err = f.stakingKeeper.GetValidator(f.sdkCtx, validators[1].GetOperator())
|
||||
assert.NilError(t, err)
|
||||
|
||||
f.stakingKeeper.DeleteValidatorByPowerIndex(f.sdkCtx, validators[0])
|
||||
validators[0], _ = validators[0].RemoveDelShares(validators[0].DelegatorShares)
|
||||
|
||||
@ -167,7 +167,8 @@ func (s *SimTestSuite) TestWeightedOperations() {
|
||||
// Abonormal scenarios, where the message are created by an errors are not tested here.
|
||||
func (s *SimTestSuite) TestSimulateMsgCreateValidator() {
|
||||
require := s.Require()
|
||||
s.app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: s.app.LastBlockHeight() + 1, Hash: s.app.LastCommitID().Hash})
|
||||
_, err := s.app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: s.app.LastBlockHeight() + 1, Hash: s.app.LastCommitID().Hash})
|
||||
require.NoError(err)
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgCreateValidator(s.txConfig, s.accountKeeper, s.bankKeeper, s.stakingKeeper)
|
||||
@ -201,17 +202,18 @@ func (s *SimTestSuite) TestSimulateMsgCancelUnbondingDelegation() {
|
||||
validator0, issuedShares := validator0.AddTokensFromDel(delTokens)
|
||||
delegator := s.accounts[2]
|
||||
delegation := types.NewDelegation(delegator.Address, validator0.GetOperator(), issuedShares)
|
||||
s.stakingKeeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(s.stakingKeeper.SetDelegation(ctx, delegation))
|
||||
s.Require().NoError(s.distrKeeper.DelegatorStartingInfo.Set(ctx, collections.Join(validator0.GetOperator(), delegator.Address), distrtypes.NewDelegatorStartingInfo(2, math.LegacyOneDec(), 200)))
|
||||
|
||||
s.setupValidatorRewards(ctx, validator0.GetOperator())
|
||||
|
||||
// unbonding delegation
|
||||
udb := types.NewUnbondingDelegation(delegator.Address, validator0.GetOperator(), s.app.LastBlockHeight()+1, blockTime.Add(2*time.Minute), delTokens, 0)
|
||||
s.stakingKeeper.SetUnbondingDelegation(ctx, udb)
|
||||
require.NoError(s.stakingKeeper.SetUnbondingDelegation(ctx, udb))
|
||||
s.setupValidatorRewards(ctx, validator0.GetOperator())
|
||||
|
||||
s.app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: s.app.LastBlockHeight() + 1, Hash: s.app.LastCommitID().Hash, Time: blockTime})
|
||||
_, err := s.app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: s.app.LastBlockHeight() + 1, Hash: s.app.LastCommitID().Hash, Time: blockTime})
|
||||
require.NoError(err)
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgCancelUnbondingDelegate(s.txConfig, s.accountKeeper, s.bankKeeper, s.stakingKeeper)
|
||||
@ -239,7 +241,8 @@ func (s *SimTestSuite) TestSimulateMsgEditValidator() {
|
||||
// setup accounts[0] as validator
|
||||
_ = s.getTestingValidator0(ctx)
|
||||
|
||||
s.app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: s.app.LastBlockHeight() + 1, Hash: s.app.LastCommitID().Hash, Time: blockTime})
|
||||
_, err := s.app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: s.app.LastBlockHeight() + 1, Hash: s.app.LastCommitID().Hash, Time: blockTime})
|
||||
require.NoError(err)
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgEditValidator(s.txConfig, s.accountKeeper, s.bankKeeper, s.stakingKeeper)
|
||||
@ -293,12 +296,13 @@ func (s *SimTestSuite) TestSimulateMsgUndelegate() {
|
||||
validator0, issuedShares := validator0.AddTokensFromDel(delTokens)
|
||||
delegator := s.accounts[2]
|
||||
delegation := types.NewDelegation(delegator.Address, validator0.GetOperator(), issuedShares)
|
||||
s.stakingKeeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(s.stakingKeeper.SetDelegation(ctx, delegation))
|
||||
s.Require().NoError(s.distrKeeper.DelegatorStartingInfo.Set(ctx, collections.Join(validator0.GetOperator(), delegator.Address), distrtypes.NewDelegatorStartingInfo(2, math.LegacyOneDec(), 200)))
|
||||
|
||||
s.setupValidatorRewards(ctx, validator0.GetOperator())
|
||||
|
||||
s.app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: s.app.LastBlockHeight() + 1, Hash: s.app.LastCommitID().Hash, Time: blockTime})
|
||||
_, err := s.app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: s.app.LastBlockHeight() + 1, Hash: s.app.LastCommitID().Hash, Time: blockTime})
|
||||
require.NoError(err)
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgUndelegate(s.txConfig, s.accountKeeper, s.bankKeeper, s.stakingKeeper)
|
||||
@ -334,14 +338,14 @@ func (s *SimTestSuite) TestSimulateMsgBeginRedelegate() {
|
||||
// setup accounts[3] as delegator
|
||||
delegator := s.accounts[3]
|
||||
delegation := types.NewDelegation(delegator.Address, validator0.GetOperator(), issuedShares)
|
||||
s.stakingKeeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(s.stakingKeeper.SetDelegation(ctx, delegation))
|
||||
s.Require().NoError(s.distrKeeper.DelegatorStartingInfo.Set(ctx, collections.Join(validator0.GetOperator(), delegator.Address), distrtypes.NewDelegatorStartingInfo(2, math.LegacyOneDec(), 200)))
|
||||
|
||||
s.setupValidatorRewards(ctx, validator0.GetOperator())
|
||||
s.setupValidatorRewards(ctx, validator1.GetOperator())
|
||||
|
||||
_, err := s.app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: s.app.LastBlockHeight() + 1, Hash: s.app.LastCommitID().Hash, Time: blockTime})
|
||||
s.Require().NoError(err)
|
||||
require.NoError(err)
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgBeginRedelegate(s.txConfig, s.accountKeeper, s.bankKeeper, s.stakingKeeper)
|
||||
@ -382,7 +386,7 @@ func (s *SimTestSuite) getTestingValidator(ctx sdk.Context, commission types.Com
|
||||
validator.DelegatorShares = math.LegacyNewDec(100)
|
||||
validator.Tokens = s.stakingKeeper.TokensFromConsensusPower(ctx, 100)
|
||||
|
||||
s.stakingKeeper.SetValidator(ctx, validator)
|
||||
s.Require().NoError(s.stakingKeeper.SetValidator(ctx, validator))
|
||||
|
||||
return validator
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package sims
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strconv"
|
||||
@ -23,12 +24,16 @@ type GenerateAccountStrategy func(int) []sdk.AccAddress
|
||||
// provides the staking bond denom. It is used in arguments in this package's
|
||||
// functions so that a mock staking keeper can be passed instead of the real one.
|
||||
type BondDenomProvider interface {
|
||||
BondDenom(ctx sdk.Context) string
|
||||
BondDenom(ctx context.Context) (string, error)
|
||||
}
|
||||
|
||||
// AddTestAddrsFromPubKeys adds the addresses into the SimApp providing only the public keys.
|
||||
func AddTestAddrsFromPubKeys(bankKeeper bankkeeper.Keeper, stakingKeeper BondDenomProvider, ctx sdk.Context, pubKeys []cryptotypes.PubKey, accAmt math.Int) {
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), accAmt))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, accAmt))
|
||||
|
||||
for _, pk := range pubKeys {
|
||||
initAccountWithCoins(bankKeeper, ctx, sdk.AccAddress(pk.Address()), initCoins)
|
||||
@ -48,7 +53,11 @@ func AddTestAddrsIncremental(bankKeeper bankkeeper.Keeper, stakingKeeper BondDen
|
||||
|
||||
func addTestAddrs(bankKeeper bankkeeper.Keeper, stakingKeeper BondDenomProvider, ctx sdk.Context, accNum int, accAmt math.Int, strategy GenerateAccountStrategy) []sdk.AccAddress {
|
||||
testAddrs := strategy(accNum)
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), accAmt))
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, accAmt))
|
||||
|
||||
for _, addr := range testAddrs {
|
||||
initAccountWithCoins(bankKeeper, ctx, addr, initCoins)
|
||||
|
||||
@ -19,13 +19,12 @@ func (k Keeper) AllocateTokens(ctx context.Context, totalPreviousPower int64, bo
|
||||
// fetch and clear the collected fees for distribution, since this is
|
||||
// called in BeginBlock, collected fees will be from the previous block
|
||||
// (and distributed to the previous proposer)
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
feeCollector := k.authKeeper.GetModuleAccount(ctx, k.feeCollectorName)
|
||||
feesCollectedInt := k.bankKeeper.GetAllBalances(sdkCtx, feeCollector.GetAddress())
|
||||
feesCollectedInt := k.bankKeeper.GetAllBalances(ctx, feeCollector.GetAddress())
|
||||
feesCollected := sdk.NewDecCoinsFromCoins(feesCollectedInt...)
|
||||
|
||||
// transfer collected fees to the distribution module account
|
||||
err := k.bankKeeper.SendCoinsFromModuleToModule(sdkCtx, k.feeCollectorName, types.ModuleName, feesCollectedInt)
|
||||
err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, k.feeCollectorName, types.ModuleName, feesCollectedInt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -58,7 +57,10 @@ func (k Keeper) AllocateTokens(ctx context.Context, totalPreviousPower int64, bo
|
||||
//
|
||||
// Ref: https://github.com/cosmos/cosmos-sdk/pull/3099#discussion_r246276376
|
||||
for _, vote := range bondedVotes {
|
||||
validator := k.stakingKeeper.ValidatorByConsAddr(sdkCtx, vote.Validator.Address)
|
||||
validator, err := k.stakingKeeper.ValidatorByConsAddr(ctx, vote.Validator.Address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: Consider micro-slashing for missing votes.
|
||||
//
|
||||
@ -66,7 +68,7 @@ func (k Keeper) AllocateTokens(ctx context.Context, totalPreviousPower int64, bo
|
||||
powerFraction := math.LegacyNewDec(vote.Validator.Power).QuoTruncate(math.LegacyNewDec(totalPreviousPower))
|
||||
reward := feeMultiplier.MulDecTruncate(powerFraction)
|
||||
|
||||
err := k.AllocateTokensToValidator(ctx, validator, reward)
|
||||
err = k.AllocateTokensToValidator(ctx, validator, reward)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ func TestAllocateTokensToValidatorWithCommission(t *testing.T) {
|
||||
val, err := distrtestutil.CreateValidator(valConsPk0, math.NewInt(100))
|
||||
require.NoError(t, err)
|
||||
val.Commission = stakingtypes.NewCommission(math.LegacyNewDecWithPrec(5, 1), math.LegacyNewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk0)).Return(val).AnyTimes()
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk0)).Return(val, nil).AnyTimes()
|
||||
|
||||
// allocate tokens
|
||||
tokens := sdk.DecCoins{
|
||||
@ -111,14 +111,14 @@ func TestAllocateTokensToManyValidators(t *testing.T) {
|
||||
val0, err := distrtestutil.CreateValidator(valConsPk0, math.NewInt(100))
|
||||
require.NoError(t, err)
|
||||
val0.Commission = stakingtypes.NewCommission(math.LegacyNewDecWithPrec(5, 1), math.LegacyNewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk0)).Return(val0).AnyTimes()
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk0)).Return(val0, nil).AnyTimes()
|
||||
|
||||
// create second validator with 0% commission
|
||||
valAddr1 := sdk.ValAddress(valConsAddr1)
|
||||
val1, err := distrtestutil.CreateValidator(valConsPk1, math.NewInt(100))
|
||||
require.NoError(t, err)
|
||||
val1.Commission = stakingtypes.NewCommission(math.LegacyNewDec(0), math.LegacyNewDec(0), math.LegacyNewDec(0))
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk1)).Return(val1).AnyTimes()
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk1)).Return(val1, nil).AnyTimes()
|
||||
|
||||
abciValA := abci.Validator{
|
||||
Address: valConsPk0.Address(),
|
||||
@ -237,21 +237,21 @@ func TestAllocateTokensTruncation(t *testing.T) {
|
||||
val0, err := distrtestutil.CreateValidator(valConsPk0, math.NewInt(100))
|
||||
require.NoError(t, err)
|
||||
val0.Commission = stakingtypes.NewCommission(math.LegacyNewDecWithPrec(1, 1), math.LegacyNewDecWithPrec(1, 1), math.LegacyNewDec(0))
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk0)).Return(val0).AnyTimes()
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk0)).Return(val0, nil).AnyTimes()
|
||||
|
||||
// create second validator with 10% commission
|
||||
valAddr1 := sdk.ValAddress(valConsAddr1)
|
||||
val1, err := distrtestutil.CreateValidator(valConsPk1, math.NewInt(100))
|
||||
require.NoError(t, err)
|
||||
val1.Commission = stakingtypes.NewCommission(math.LegacyNewDecWithPrec(1, 1), math.LegacyNewDecWithPrec(1, 1), math.LegacyNewDec(0))
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk1)).Return(val1).AnyTimes()
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk1)).Return(val1, nil).AnyTimes()
|
||||
|
||||
// create third validator with 10% commission
|
||||
valAddr2 := sdk.ValAddress(valConsAddr2)
|
||||
val2, err := stakingtypes.NewValidator(sdk.ValAddress(valConsAddr2), valConsPk1, stakingtypes.Description{})
|
||||
require.NoError(t, err)
|
||||
val2.Commission = stakingtypes.NewCommission(math.LegacyNewDecWithPrec(1, 1), math.LegacyNewDecWithPrec(1, 1), math.LegacyNewDec(0))
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk2)).Return(val2).AnyTimes()
|
||||
stakingKeeper.EXPECT().ValidatorByConsAddr(gomock.Any(), sdk.GetConsAddress(valConsPk2)).Return(val2, nil).AnyTimes()
|
||||
|
||||
abciValA := abci.Validator{
|
||||
Address: valConsPk0.Address(),
|
||||
|
||||
@ -23,16 +23,26 @@ func (k Keeper) initializeDelegation(ctx context.Context, val sdk.ValAddress, de
|
||||
previousPeriod := valCurrentRewards.Period - 1
|
||||
|
||||
// increment reference count for the period we're going to track
|
||||
k.incrementReferenceCount(ctx, val, previousPeriod)
|
||||
err = k.incrementReferenceCount(ctx, val, previousPeriod)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
validator := k.stakingKeeper.Validator(sdkCtx, val)
|
||||
delegation := k.stakingKeeper.Delegation(sdkCtx, del, val)
|
||||
validator, err := k.stakingKeeper.Validator(ctx, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
delegation, err := k.stakingKeeper.Delegation(ctx, del, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// calculate delegation stake in tokens
|
||||
// we don't store directly, so multiply delegation shares * (tokens per share)
|
||||
// note: necessary to truncate so we don't allow withdrawing more rewards than owed
|
||||
stake := validator.TokensFromSharesTruncated(delegation.GetShares())
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
return k.DelegatorStartingInfo.Set(ctx, collections.Join(val, del), types.NewDelegatorStartingInfo(previousPeriod, stake, uint64(sdkCtx.BlockHeight())))
|
||||
}
|
||||
|
||||
|
||||
@ -59,8 +59,8 @@ func TestCalculateRewardsBasic(t *testing.T) {
|
||||
|
||||
// delegation mock
|
||||
del := stakingtypes.NewDelegation(addr, valAddr, val.DelegatorShares)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(3)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(3)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del, nil)
|
||||
|
||||
// run the necessary hooks manually (given that we are not running an actual staking module)
|
||||
err = distrtestutil.CallCreateValidatorHooks(ctx, distrKeeper, addr, valAddr)
|
||||
@ -145,8 +145,8 @@ func TestCalculateRewardsAfterSlash(t *testing.T) {
|
||||
del := stakingtypes.NewDelegation(addr, valAddr, val.DelegatorShares)
|
||||
|
||||
// set mock calls
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(4)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(4)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del, nil)
|
||||
|
||||
// run the necessary hooks manually (given that we are not running an actual staking module)
|
||||
err = distrtestutil.CallCreateValidatorHooks(ctx, distrKeeper, addr, valAddr)
|
||||
@ -244,8 +244,8 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) {
|
||||
|
||||
// delegation mocks
|
||||
del := stakingtypes.NewDelegation(addr, valAddr, val.DelegatorShares)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(4)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(4)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del, nil)
|
||||
|
||||
// run the necessary hooks manually (given that we are not running an actual staking module)
|
||||
err = distrtestutil.CallCreateValidatorHooks(ctx, distrKeeper, addr, valAddr)
|
||||
@ -280,7 +280,7 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) {
|
||||
require.True(t, slashedTokens.IsPositive(), "expected positive slashed tokens, got: %s", slashedTokens)
|
||||
|
||||
// expect a call for the next slash with the updated validator
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(1)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(1)
|
||||
|
||||
// increase block height
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
@ -364,8 +364,8 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) {
|
||||
del0 := stakingtypes.NewDelegation(addr0, valAddr, val.DelegatorShares)
|
||||
|
||||
// set mock calls
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(4)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr0, valAddr).Return(del0).Times(1)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(4)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr0, valAddr).Return(del0, nil).Times(1)
|
||||
|
||||
// run the necessary hooks manually (given that we are not running an actual staking module)
|
||||
err = distrtestutil.CallCreateValidatorHooks(ctx, distrKeeper, addr0, valAddr)
|
||||
@ -384,8 +384,8 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) {
|
||||
_, del1, err := distrtestutil.Delegate(ctx, distrKeeper, addr1, &val, math.NewInt(100), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr1, valAddr).Return(del1)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(1)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr1, valAddr).Return(del1, nil)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(1)
|
||||
|
||||
// call necessary hooks to update a delegation
|
||||
err = distrKeeper.Hooks().AfterDelegationModified(ctx, addr1, valAddr)
|
||||
@ -458,8 +458,8 @@ func TestWithdrawDelegationRewardsBasic(t *testing.T) {
|
||||
|
||||
// delegation mock
|
||||
del := stakingtypes.NewDelegation(addr, valAddr, val.DelegatorShares)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(5)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del).Times(3)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(5)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del, nil).Times(3)
|
||||
|
||||
// run the necessary hooks manually (given that we are not running an actual staking module)
|
||||
err = distrtestutil.CallCreateValidatorHooks(ctx, distrKeeper, addr, valAddr)
|
||||
@ -531,8 +531,8 @@ func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) {
|
||||
|
||||
// delegation mock
|
||||
del := stakingtypes.NewDelegation(addr, valAddr, val.DelegatorShares)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(5)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(5)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del, nil)
|
||||
|
||||
// run the necessary hooks manually (given that we are not running an actual staking module)
|
||||
err = distrtestutil.CallCreateValidatorHooks(ctx, distrKeeper, addr, valAddr)
|
||||
@ -644,13 +644,13 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) {
|
||||
|
||||
// validator and delegation mocks
|
||||
del := stakingtypes.NewDelegation(addr, valAddr, val.DelegatorShares)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(3)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(3)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del, nil)
|
||||
|
||||
// run the necessary hooks manually (given that we are not running an actual staking module)
|
||||
err = distrtestutil.CallCreateValidatorHooks(ctx, distrKeeper, addr, valAddr)
|
||||
require.NoError(t, err)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(2)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(2)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
@ -674,7 +674,7 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) {
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
|
||||
// update validator mock
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(1)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(1)
|
||||
|
||||
// second delegation
|
||||
_, del2, err := distrtestutil.Delegate(
|
||||
@ -688,8 +688,8 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// new delegation mock and update validator mock
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), sdk.AccAddress(valConsAddr1), valAddr).Return(del2)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(1)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), sdk.AccAddress(valConsAddr1), valAddr).Return(del2, nil)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(1)
|
||||
|
||||
// call necessary hooks to update a delegation
|
||||
err = distrKeeper.Hooks().AfterDelegationModified(ctx, sdk.AccAddress(valConsAddr1), valAddr)
|
||||
@ -774,13 +774,13 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) {
|
||||
|
||||
// validator and delegation mocks
|
||||
del := stakingtypes.NewDelegation(addr, valAddr, val.DelegatorShares)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(3)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del).Times(5)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(3)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del, nil).Times(5)
|
||||
|
||||
// run the necessary hooks manually (given that we are not running an actual staking module)
|
||||
err = distrtestutil.CallCreateValidatorHooks(ctx, distrKeeper, addr, valAddr)
|
||||
require.NoError(t, err)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(2)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(2)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
@ -805,8 +805,8 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// new delegation mock and update validator mock
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), sdk.AccAddress(valConsAddr1), valAddr).Return(del2).Times(3)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(6)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), sdk.AccAddress(valConsAddr1), valAddr).Return(del2, nil).Times(3)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(6)
|
||||
|
||||
// call necessary hooks to update a delegation
|
||||
err = distrKeeper.Hooks().AfterDelegationModified(ctx, sdk.AccAddress(valConsAddr1), valAddr)
|
||||
@ -970,13 +970,13 @@ func Test100PercentCommissionReward(t *testing.T) {
|
||||
|
||||
// validator and delegation mocks
|
||||
del := stakingtypes.NewDelegation(addr, valAddr, val.DelegatorShares)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(3)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del).Times(3)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(3)
|
||||
stakingKeeper.EXPECT().Delegation(gomock.Any(), addr, valAddr).Return(del, nil).Times(3)
|
||||
|
||||
// run the necessary hooks manually (given that we are not running an actual staking module)
|
||||
err = distrtestutil.CallCreateValidatorHooks(ctx, distrKeeper, addr, valAddr)
|
||||
require.NoError(t, err)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val).Times(2)
|
||||
stakingKeeper.EXPECT().Validator(gomock.Any(), valAddr).Return(val, nil).Times(2)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
@ -28,8 +28,8 @@ func NewQuerier(keeper Keeper) Querier {
|
||||
}
|
||||
|
||||
// Params queries params of distribution module
|
||||
func (k Querier) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
|
||||
params, err := k.Keeper.Params.Get(c)
|
||||
func (k Querier) Params(ctx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
|
||||
params, err := k.Keeper.Params.Get(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -38,7 +38,7 @@ func (k Querier) Params(c context.Context, req *types.QueryParamsRequest) (*type
|
||||
}
|
||||
|
||||
// ValidatorDistributionInfo query validator's commission and self-delegation rewards
|
||||
func (k Querier) ValidatorDistributionInfo(c context.Context, req *types.QueryValidatorDistributionInfoRequest) (*types.QueryValidatorDistributionInfoResponse, error) {
|
||||
func (k Querier) ValidatorDistributionInfo(ctx context.Context, req *types.QueryValidatorDistributionInfoRequest) (*types.QueryValidatorDistributionInfoResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid request")
|
||||
}
|
||||
@ -47,22 +47,28 @@ func (k Querier) ValidatorDistributionInfo(c context.Context, req *types.QueryVa
|
||||
return nil, status.Error(codes.InvalidArgument, "empty validator address")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
valAdr, err := sdk.ValAddressFromBech32(req.ValidatorAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// self-delegation rewards
|
||||
val := k.stakingKeeper.Validator(ctx, valAdr)
|
||||
val, err := k.stakingKeeper.Validator(ctx, valAdr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if val == nil {
|
||||
return nil, errors.Wrap(types.ErrNoValidatorExists, req.ValidatorAddress)
|
||||
}
|
||||
|
||||
delAdr := sdk.AccAddress(valAdr)
|
||||
|
||||
del := k.stakingKeeper.Delegation(ctx, delAdr, valAdr)
|
||||
del, err := k.stakingKeeper.Delegation(ctx, delAdr, valAdr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if del == nil {
|
||||
return nil, types.ErrNoDelegationExists
|
||||
}
|
||||
@ -91,7 +97,7 @@ func (k Querier) ValidatorDistributionInfo(c context.Context, req *types.QueryVa
|
||||
}
|
||||
|
||||
// ValidatorOutstandingRewards queries rewards of a validator address
|
||||
func (k Querier) ValidatorOutstandingRewards(c context.Context, req *types.QueryValidatorOutstandingRewardsRequest) (*types.QueryValidatorOutstandingRewardsResponse, error) {
|
||||
func (k Querier) ValidatorOutstandingRewards(ctx context.Context, req *types.QueryValidatorOutstandingRewardsRequest) (*types.QueryValidatorOutstandingRewardsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid request")
|
||||
}
|
||||
@ -100,14 +106,16 @@ func (k Querier) ValidatorOutstandingRewards(c context.Context, req *types.Query
|
||||
return nil, status.Error(codes.InvalidArgument, "empty validator address")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
valAdr, err := sdk.ValAddressFromBech32(req.ValidatorAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validator := k.stakingKeeper.Validator(ctx, valAdr)
|
||||
validator, err := k.stakingKeeper.Validator(ctx, valAdr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if validator == nil {
|
||||
return nil, errors.Wrapf(types.ErrNoValidatorExists, valAdr.String())
|
||||
}
|
||||
@ -121,7 +129,7 @@ func (k Querier) ValidatorOutstandingRewards(c context.Context, req *types.Query
|
||||
}
|
||||
|
||||
// ValidatorCommission queries accumulated commission for a validator
|
||||
func (k Querier) ValidatorCommission(c context.Context, req *types.QueryValidatorCommissionRequest) (*types.QueryValidatorCommissionResponse, error) {
|
||||
func (k Querier) ValidatorCommission(ctx context.Context, req *types.QueryValidatorCommissionRequest) (*types.QueryValidatorCommissionResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid request")
|
||||
}
|
||||
@ -130,14 +138,16 @@ func (k Querier) ValidatorCommission(c context.Context, req *types.QueryValidato
|
||||
return nil, status.Error(codes.InvalidArgument, "empty validator address")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
valAdr, err := sdk.ValAddressFromBech32(req.ValidatorAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validator := k.stakingKeeper.Validator(ctx, valAdr)
|
||||
validator, err := k.stakingKeeper.Validator(ctx, valAdr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if validator == nil {
|
||||
return nil, errors.Wrapf(types.ErrNoValidatorExists, valAdr.String())
|
||||
}
|
||||
@ -150,7 +160,7 @@ func (k Querier) ValidatorCommission(c context.Context, req *types.QueryValidato
|
||||
}
|
||||
|
||||
// ValidatorSlashes queries slash events of a validator
|
||||
func (k Querier) ValidatorSlashes(c context.Context, req *types.QueryValidatorSlashesRequest) (*types.QueryValidatorSlashesResponse, error) {
|
||||
func (k Querier) ValidatorSlashes(ctx context.Context, req *types.QueryValidatorSlashesRequest) (*types.QueryValidatorSlashesResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid request")
|
||||
}
|
||||
@ -168,7 +178,7 @@ func (k Querier) ValidatorSlashes(c context.Context, req *types.QueryValidatorSl
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid validator address")
|
||||
}
|
||||
|
||||
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(c))
|
||||
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
||||
slashesStore := prefix.NewStore(store, types.GetValidatorSlashEventPrefix(valAddr))
|
||||
|
||||
events, pageRes, err := query.GenericFilteredPaginate(k.cdc, slashesStore, req.Pagination, func(key []byte, result *types.ValidatorSlashEvent) (*types.ValidatorSlashEvent, error) {
|
||||
@ -193,7 +203,7 @@ func (k Querier) ValidatorSlashes(c context.Context, req *types.QueryValidatorSl
|
||||
}
|
||||
|
||||
// DelegationRewards the total rewards accrued by a delegation
|
||||
func (k Querier) DelegationRewards(c context.Context, req *types.QueryDelegationRewardsRequest) (*types.QueryDelegationRewardsResponse, error) {
|
||||
func (k Querier) DelegationRewards(ctx context.Context, req *types.QueryDelegationRewardsRequest) (*types.QueryDelegationRewardsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid request")
|
||||
}
|
||||
@ -206,14 +216,16 @@ func (k Querier) DelegationRewards(c context.Context, req *types.QueryDelegation
|
||||
return nil, status.Error(codes.InvalidArgument, "empty validator address")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
valAdr, err := sdk.ValAddressFromBech32(req.ValidatorAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
val := k.stakingKeeper.Validator(ctx, valAdr)
|
||||
val, err := k.stakingKeeper.Validator(ctx, valAdr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if val == nil {
|
||||
return nil, errors.Wrap(types.ErrNoValidatorExists, req.ValidatorAddress)
|
||||
}
|
||||
@ -222,7 +234,11 @@ func (k Querier) DelegationRewards(c context.Context, req *types.QueryDelegation
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
del := k.stakingKeeper.Delegation(ctx, delAdr, valAdr)
|
||||
del, err := k.stakingKeeper.Delegation(ctx, delAdr, valAdr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if del == nil {
|
||||
return nil, types.ErrNoDelegationExists
|
||||
}
|
||||
@ -241,7 +257,7 @@ func (k Querier) DelegationRewards(c context.Context, req *types.QueryDelegation
|
||||
}
|
||||
|
||||
// DelegationTotalRewards the total rewards accrued by a each validator
|
||||
func (k Querier) DelegationTotalRewards(c context.Context, req *types.QueryDelegationTotalRewardsRequest) (*types.QueryDelegationTotalRewardsResponse, error) {
|
||||
func (k Querier) DelegationTotalRewards(ctx context.Context, req *types.QueryDelegationTotalRewardsRequest) (*types.QueryDelegationTotalRewardsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid request")
|
||||
}
|
||||
@ -250,8 +266,6 @@ func (k Querier) DelegationTotalRewards(c context.Context, req *types.QueryDeleg
|
||||
return nil, status.Error(codes.InvalidArgument, "empty delegator address")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
total := sdk.DecCoins{}
|
||||
var delRewards []types.DelegationDelegatorReward
|
||||
|
||||
@ -260,11 +274,15 @@ func (k Querier) DelegationTotalRewards(c context.Context, req *types.QueryDeleg
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.stakingKeeper.IterateDelegations(
|
||||
err = k.stakingKeeper.IterateDelegations(
|
||||
ctx, delAdr,
|
||||
func(_ int64, del stakingtypes.DelegationI) (stop bool) {
|
||||
valAddr := del.GetValidatorAddr()
|
||||
val := k.stakingKeeper.Validator(ctx, valAddr)
|
||||
val, err := k.stakingKeeper.Validator(ctx, valAddr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
endingPeriod, err := k.IncrementValidatorPeriod(ctx, val)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -280,12 +298,15 @@ func (k Querier) DelegationTotalRewards(c context.Context, req *types.QueryDeleg
|
||||
return false
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.QueryDelegationTotalRewardsResponse{Rewards: delRewards, Total: total}, nil
|
||||
}
|
||||
|
||||
// DelegatorValidators queries the validators list of a delegator
|
||||
func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) {
|
||||
func (k Querier) DelegatorValidators(ctx context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid request")
|
||||
}
|
||||
@ -294,14 +315,13 @@ func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegato
|
||||
return nil, status.Error(codes.InvalidArgument, "empty delegator address")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
delAdr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var validators []string
|
||||
|
||||
k.stakingKeeper.IterateDelegations(
|
||||
err = k.stakingKeeper.IterateDelegations(
|
||||
ctx, delAdr,
|
||||
func(_ int64, del stakingtypes.DelegationI) (stop bool) {
|
||||
validators = append(validators, del.GetValidatorAddr().String())
|
||||
@ -309,11 +329,15 @@ func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegato
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.QueryDelegatorValidatorsResponse{Validators: validators}, nil
|
||||
}
|
||||
|
||||
// DelegatorWithdrawAddress queries Query/delegatorWithdrawAddress
|
||||
func (k Querier) DelegatorWithdrawAddress(c context.Context, req *types.QueryDelegatorWithdrawAddressRequest) (*types.QueryDelegatorWithdrawAddressResponse, error) {
|
||||
func (k Querier) DelegatorWithdrawAddress(ctx context.Context, req *types.QueryDelegatorWithdrawAddressRequest) (*types.QueryDelegatorWithdrawAddressResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid request")
|
||||
}
|
||||
@ -326,7 +350,7 @@ func (k Querier) DelegatorWithdrawAddress(c context.Context, req *types.QueryDel
|
||||
return nil, err
|
||||
}
|
||||
|
||||
withdrawAddr, err := k.GetDelegatorWithdrawAddr(c, delAdr)
|
||||
withdrawAddr, err := k.GetDelegatorWithdrawAddr(ctx, delAdr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -335,8 +359,8 @@ func (k Querier) DelegatorWithdrawAddress(c context.Context, req *types.QueryDel
|
||||
}
|
||||
|
||||
// CommunityPool queries the community pool coins
|
||||
func (k Querier) CommunityPool(c context.Context, req *types.QueryCommunityPoolRequest) (*types.QueryCommunityPoolResponse, error) {
|
||||
pool, err := k.FeePool.Get(c)
|
||||
func (k Querier) CommunityPool(ctx context.Context, req *types.QueryCommunityPoolRequest) (*types.QueryCommunityPoolResponse, error) {
|
||||
pool, err := k.FeePool.Get(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"cosmossdk.io/collections"
|
||||
@ -24,13 +25,16 @@ func (k Keeper) Hooks() Hooks {
|
||||
}
|
||||
|
||||
// initialize validator distribution record
|
||||
func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error {
|
||||
val := h.k.stakingKeeper.Validator(ctx, valAddr)
|
||||
func (h Hooks) AfterValidatorCreated(ctx context.Context, valAddr sdk.ValAddress) error {
|
||||
val, err := h.k.stakingKeeper.Validator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return h.k.initializeValidator(ctx, val)
|
||||
}
|
||||
|
||||
// AfterValidatorRemoved performs clean up after a validator is removed
|
||||
func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) error {
|
||||
func (h Hooks) AfterValidatorRemoved(ctx context.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) error {
|
||||
// fetch outstanding
|
||||
outstanding, err := h.k.GetValidatorOutstandingRewardsCoins(ctx, valAddr)
|
||||
if err != nil {
|
||||
@ -120,16 +124,27 @@ func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr
|
||||
}
|
||||
|
||||
// increment period
|
||||
func (h Hooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
|
||||
val := h.k.stakingKeeper.Validator(ctx, valAddr)
|
||||
_, err := h.k.IncrementValidatorPeriod(ctx, val)
|
||||
func (h Hooks) BeforeDelegationCreated(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
|
||||
val, err := h.k.stakingKeeper.Validator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = h.k.IncrementValidatorPeriod(ctx, val)
|
||||
return err
|
||||
}
|
||||
|
||||
// withdraw delegation rewards (which also increments period)
|
||||
func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
|
||||
val := h.k.stakingKeeper.Validator(ctx, valAddr)
|
||||
del := h.k.stakingKeeper.Delegation(ctx, delAddr, valAddr)
|
||||
func (h Hooks) BeforeDelegationSharesModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
|
||||
val, err := h.k.stakingKeeper.Validator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
del, err := h.k.stakingKeeper.Delegation(ctx, delAddr, valAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := h.k.withdrawDelegationRewards(ctx, val, del); err != nil {
|
||||
return err
|
||||
@ -139,32 +154,32 @@ func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAd
|
||||
}
|
||||
|
||||
// create new delegation period record
|
||||
func (h Hooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
|
||||
func (h Hooks) AfterDelegationModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
|
||||
return h.k.initializeDelegation(ctx, valAddr, delAddr)
|
||||
}
|
||||
|
||||
// record the slash event
|
||||
func (h Hooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdkmath.LegacyDec) error {
|
||||
func (h Hooks) BeforeValidatorSlashed(ctx context.Context, valAddr sdk.ValAddress, fraction sdkmath.LegacyDec) error {
|
||||
h.k.updateValidatorSlashFraction(ctx, valAddr, fraction)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) error {
|
||||
func (h Hooks) BeforeValidatorModified(_ context.Context, _ sdk.ValAddress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) AfterValidatorBonded(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error {
|
||||
func (h Hooks) AfterValidatorBonded(_ context.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) AfterValidatorBeginUnbonding(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error {
|
||||
func (h Hooks) AfterValidatorBeginUnbonding(_ context.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
|
||||
func (h Hooks) BeforeDelegationRemoved(_ context.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) AfterUnbondingInitiated(_ sdk.Context, _ uint64) error {
|
||||
func (h Hooks) AfterUnbondingInitiated(_ context.Context, _ uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -75,13 +75,18 @@ func CanWithdrawInvariant(k Keeper) sdk.Invariant {
|
||||
var remaining sdk.DecCoins
|
||||
|
||||
valDelegationAddrs := make(map[string][]sdk.AccAddress)
|
||||
for _, del := range k.stakingKeeper.GetAllSDKDelegations(ctx) {
|
||||
allDelegations, err := k.stakingKeeper.GetAllSDKDelegations(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, del := range allDelegations {
|
||||
valAddr := del.GetValidatorAddr().String()
|
||||
valDelegationAddrs[valAddr] = append(valDelegationAddrs[valAddr], del.GetDelegatorAddr())
|
||||
}
|
||||
|
||||
// iterate over all validators
|
||||
k.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
err = k.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
_, _ = k.WithdrawValidatorCommission(ctx, val.GetOperator())
|
||||
|
||||
delegationAddrs, ok := valDelegationAddrs[val.GetOperator().String()]
|
||||
@ -105,6 +110,9 @@ func CanWithdrawInvariant(k Keeper) sdk.Invariant {
|
||||
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
broken := len(remaining) > 0 && remaining[0].Amount.IsNegative()
|
||||
return sdk.FormatInvariant(types.ModuleName, "can withdraw",
|
||||
@ -116,11 +124,19 @@ func CanWithdrawInvariant(k Keeper) sdk.Invariant {
|
||||
func ReferenceCountInvariant(k Keeper) sdk.Invariant {
|
||||
return func(ctx sdk.Context) (string, bool) {
|
||||
valCount := uint64(0)
|
||||
k.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
err := k.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
valCount++
|
||||
return false
|
||||
})
|
||||
dels := k.stakingKeeper.GetAllSDKDelegations(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
dels, err := k.stakingKeeper.GetAllSDKDelegations(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
slashCount := uint64(0)
|
||||
k.IterateValidatorSlashEvents(ctx,
|
||||
func(_ sdk.ValAddress, _ uint64, _ types.ValidatorSlashEvent) (stop bool) {
|
||||
|
||||
@ -146,25 +146,32 @@ func (k Keeper) SetWithdrawAddr(ctx context.Context, delegatorAddr, withdrawAddr
|
||||
|
||||
// withdraw rewards from a delegation
|
||||
func (k Keeper) WithdrawDelegationRewards(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (sdk.Coins, error) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
val := k.stakingKeeper.Validator(sdkCtx, valAddr)
|
||||
val, err := k.stakingKeeper.Validator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if val == nil {
|
||||
return nil, types.ErrNoValidatorDistInfo
|
||||
}
|
||||
|
||||
del := k.stakingKeeper.Delegation(sdkCtx, delAddr, valAddr)
|
||||
del, err := k.stakingKeeper.Delegation(ctx, delAddr, valAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if del == nil {
|
||||
return nil, types.ErrEmptyDelegationDistInfo
|
||||
}
|
||||
|
||||
// withdraw rewards
|
||||
rewards, err := k.withdrawDelegationRewards(sdkCtx, val, del)
|
||||
rewards, err := k.withdrawDelegationRewards(ctx, val, del)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// reinitialize the delegation
|
||||
err = k.initializeDelegation(sdkCtx, valAddr, delAddr)
|
||||
err = k.initializeDelegation(ctx, valAddr, delAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -183,8 +183,11 @@ func (k msgServer) DepositValidatorRewardsPool(ctx context.Context, msg *types.M
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
validator := k.stakingKeeper.Validator(sdkCtx, valAddr)
|
||||
validator, err := k.stakingKeeper.Validator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if validator == nil {
|
||||
return nil, errors.Wrapf(types.ErrNoValidatorExists, valAddr.String())
|
||||
}
|
||||
|
||||
@ -147,7 +147,10 @@ func (k Keeper) updateValidatorSlashFraction(ctx context.Context, valAddr sdk.Va
|
||||
}
|
||||
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
val := k.stakingKeeper.Validator(sdkCtx, valAddr)
|
||||
val, err := k.stakingKeeper.Validator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// increment current period
|
||||
newPeriod, err := k.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
@ -126,14 +126,20 @@ func SimulateMsgWithdrawDelegatorReward(txConfig client.TxConfig, ak types.Accou
|
||||
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
simAccount, _ := simtypes.RandomAcc(r, accs)
|
||||
delegations := sk.GetAllDelegatorDelegations(ctx, simAccount.Address)
|
||||
delegations, err := sk.GetAllDelegatorDelegations(ctx, simAccount.Address)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(&types.MsgWithdrawDelegatorReward{}), "error getting delegations"), nil, err
|
||||
}
|
||||
if len(delegations) == 0 {
|
||||
return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(&types.MsgWithdrawDelegatorReward{}), "number of delegators equal 0"), nil, nil
|
||||
}
|
||||
|
||||
delegation := delegations[r.Intn(len(delegations))]
|
||||
|
||||
validator := sk.Validator(ctx, delegation.GetValidatorAddr())
|
||||
validator, err := sk.Validator(ctx, delegation.GetValidatorAddr())
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(&types.MsgWithdrawDelegatorReward{}), "error getting validator"), nil, err
|
||||
}
|
||||
if validator == nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(&types.MsgWithdrawDelegatorReward{}), "validator is nil"), nil, fmt.Errorf("validator %s not found", delegation.GetValidatorAddr())
|
||||
}
|
||||
@ -168,7 +174,12 @@ func SimulateMsgWithdrawValidatorCommission(txConfig client.TxConfig, ak types.A
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
msgType := sdk.MsgTypeURL(&types.MsgWithdrawValidatorCommission{})
|
||||
|
||||
validator, ok := testutil.RandSliceElem(r, sk.GetAllValidators(ctx))
|
||||
allVals, err := sk.GetAllValidators(ctx)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, msgType, "error getting all validators"), nil, err
|
||||
}
|
||||
|
||||
validator, ok := testutil.RandSliceElem(r, allVals)
|
||||
if !ok {
|
||||
return simtypes.NoOpMsg(types.ModuleName, msgType, "random validator is not ok"), nil, nil
|
||||
}
|
||||
|
||||
@ -267,7 +267,8 @@ func (suite *SimTestSuite) SetupTest() {
|
||||
|
||||
suite.ctx = suite.app.BaseApp.NewContext(false)
|
||||
|
||||
genesisVals := suite.stakingKeeper.GetAllValidators(suite.ctx)
|
||||
genesisVals, err := suite.stakingKeeper.GetAllValidators(suite.ctx)
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Len(genesisVals, 1)
|
||||
suite.genesisVals = genesisVals
|
||||
}
|
||||
|
||||
@ -236,11 +236,12 @@ func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder {
|
||||
}
|
||||
|
||||
// Delegation mocks base method.
|
||||
func (m *MockStakingKeeper) Delegation(arg0 types.Context, arg1 types.AccAddress, arg2 types.ValAddress) types0.DelegationI {
|
||||
func (m *MockStakingKeeper) Delegation(arg0 context.Context, arg1 types.AccAddress, arg2 types.ValAddress) (types0.DelegationI, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delegation", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(types0.DelegationI)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Delegation indicates an expected call of Delegation.
|
||||
@ -250,11 +251,12 @@ func (mr *MockStakingKeeperMockRecorder) Delegation(arg0, arg1, arg2 interface{}
|
||||
}
|
||||
|
||||
// GetAllDelegatorDelegations mocks base method.
|
||||
func (m *MockStakingKeeper) GetAllDelegatorDelegations(ctx types.Context, delegator types.AccAddress) []types0.Delegation {
|
||||
func (m *MockStakingKeeper) GetAllDelegatorDelegations(ctx context.Context, delegator types.AccAddress) ([]types0.Delegation, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAllDelegatorDelegations", ctx, delegator)
|
||||
ret0, _ := ret[0].([]types0.Delegation)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAllDelegatorDelegations indicates an expected call of GetAllDelegatorDelegations.
|
||||
@ -264,11 +266,12 @@ func (mr *MockStakingKeeperMockRecorder) GetAllDelegatorDelegations(ctx, delegat
|
||||
}
|
||||
|
||||
// GetAllSDKDelegations mocks base method.
|
||||
func (m *MockStakingKeeper) GetAllSDKDelegations(ctx types.Context) []types0.Delegation {
|
||||
func (m *MockStakingKeeper) GetAllSDKDelegations(ctx context.Context) ([]types0.Delegation, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAllSDKDelegations", ctx)
|
||||
ret0, _ := ret[0].([]types0.Delegation)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAllSDKDelegations indicates an expected call of GetAllSDKDelegations.
|
||||
@ -278,11 +281,12 @@ func (mr *MockStakingKeeperMockRecorder) GetAllSDKDelegations(ctx interface{}) *
|
||||
}
|
||||
|
||||
// GetAllValidators mocks base method.
|
||||
func (m *MockStakingKeeper) GetAllValidators(ctx types.Context) []types0.Validator {
|
||||
func (m *MockStakingKeeper) GetAllValidators(ctx context.Context) ([]types0.Validator, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAllValidators", ctx)
|
||||
ret0, _ := ret[0].([]types0.Validator)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAllValidators indicates an expected call of GetAllValidators.
|
||||
@ -292,9 +296,11 @@ func (mr *MockStakingKeeperMockRecorder) GetAllValidators(ctx interface{}) *gomo
|
||||
}
|
||||
|
||||
// IterateDelegations mocks base method.
|
||||
func (m *MockStakingKeeper) IterateDelegations(ctx types.Context, delegator types.AccAddress, fn func(int64, types0.DelegationI) bool) {
|
||||
func (m *MockStakingKeeper) IterateDelegations(ctx context.Context, delegator types.AccAddress, fn func(int64, types0.DelegationI) bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "IterateDelegations", ctx, delegator, fn)
|
||||
ret := m.ctrl.Call(m, "IterateDelegations", ctx, delegator, fn)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IterateDelegations indicates an expected call of IterateDelegations.
|
||||
@ -304,9 +310,11 @@ func (mr *MockStakingKeeperMockRecorder) IterateDelegations(ctx, delegator, fn i
|
||||
}
|
||||
|
||||
// IterateValidators mocks base method.
|
||||
func (m *MockStakingKeeper) IterateValidators(arg0 types.Context, arg1 func(int64, types0.ValidatorI) bool) {
|
||||
func (m *MockStakingKeeper) IterateValidators(arg0 context.Context, arg1 func(int64, types0.ValidatorI) bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "IterateValidators", arg0, arg1)
|
||||
ret := m.ctrl.Call(m, "IterateValidators", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IterateValidators indicates an expected call of IterateValidators.
|
||||
@ -316,11 +324,12 @@ func (mr *MockStakingKeeperMockRecorder) IterateValidators(arg0, arg1 interface{
|
||||
}
|
||||
|
||||
// Validator mocks base method.
|
||||
func (m *MockStakingKeeper) Validator(arg0 types.Context, arg1 types.ValAddress) types0.ValidatorI {
|
||||
func (m *MockStakingKeeper) Validator(arg0 context.Context, arg1 types.ValAddress) (types0.ValidatorI, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Validator", arg0, arg1)
|
||||
ret0, _ := ret[0].(types0.ValidatorI)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Validator indicates an expected call of Validator.
|
||||
@ -330,11 +339,12 @@ func (mr *MockStakingKeeperMockRecorder) Validator(arg0, arg1 interface{}) *gomo
|
||||
}
|
||||
|
||||
// ValidatorByConsAddr mocks base method.
|
||||
func (m *MockStakingKeeper) ValidatorByConsAddr(arg0 types.Context, arg1 types.ConsAddress) types0.ValidatorI {
|
||||
func (m *MockStakingKeeper) ValidatorByConsAddr(arg0 context.Context, arg1 types.ConsAddress) (types0.ValidatorI, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatorByConsAddr", arg0, arg1)
|
||||
ret0, _ := ret[0].(types0.ValidatorI)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ValidatorByConsAddr indicates an expected call of ValidatorByConsAddr.
|
||||
@ -367,9 +377,11 @@ func (m *MockStakingHooks) EXPECT() *MockStakingHooksMockRecorder {
|
||||
}
|
||||
|
||||
// AfterDelegationModified mocks base method.
|
||||
func (m *MockStakingHooks) AfterDelegationModified(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) {
|
||||
func (m *MockStakingHooks) AfterDelegationModified(ctx context.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "AfterDelegationModified", ctx, delAddr, valAddr)
|
||||
ret := m.ctrl.Call(m, "AfterDelegationModified", ctx, delAddr, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// AfterDelegationModified indicates an expected call of AfterDelegationModified.
|
||||
@ -379,9 +391,11 @@ func (mr *MockStakingHooksMockRecorder) AfterDelegationModified(ctx, delAddr, va
|
||||
}
|
||||
|
||||
// AfterValidatorCreated mocks base method.
|
||||
func (m *MockStakingHooks) AfterValidatorCreated(ctx types.Context, valAddr types.ValAddress) {
|
||||
func (m *MockStakingHooks) AfterValidatorCreated(ctx context.Context, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "AfterValidatorCreated", ctx, valAddr)
|
||||
ret := m.ctrl.Call(m, "AfterValidatorCreated", ctx, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// AfterValidatorCreated indicates an expected call of AfterValidatorCreated.
|
||||
|
||||
@ -35,26 +35,26 @@ type BankKeeper interface {
|
||||
// StakingKeeper expected staking keeper (noalias)
|
||||
type StakingKeeper interface {
|
||||
// iterate through validators by operator address, execute func for each validator
|
||||
IterateValidators(sdk.Context,
|
||||
func(index int64, validator stakingtypes.ValidatorI) (stop bool))
|
||||
IterateValidators(context.Context,
|
||||
func(index int64, validator stakingtypes.ValidatorI) (stop bool)) error
|
||||
|
||||
Validator(sdk.Context, sdk.ValAddress) stakingtypes.ValidatorI // get a particular validator by operator address
|
||||
ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.ValidatorI // get a particular validator by consensus address
|
||||
Validator(context.Context, sdk.ValAddress) (stakingtypes.ValidatorI, error) // get a particular validator by operator address
|
||||
ValidatorByConsAddr(context.Context, sdk.ConsAddress) (stakingtypes.ValidatorI, error) // get a particular validator by consensus address
|
||||
|
||||
// Delegation allows for getting a particular delegation for a given validator
|
||||
// and delegator outside the scope of the staking module.
|
||||
Delegation(sdk.Context, sdk.AccAddress, sdk.ValAddress) stakingtypes.DelegationI
|
||||
Delegation(context.Context, sdk.AccAddress, sdk.ValAddress) (stakingtypes.DelegationI, error)
|
||||
|
||||
IterateDelegations(ctx sdk.Context, delegator sdk.AccAddress,
|
||||
fn func(index int64, delegation stakingtypes.DelegationI) (stop bool))
|
||||
IterateDelegations(ctx context.Context, delegator sdk.AccAddress,
|
||||
fn func(index int64, delegation stakingtypes.DelegationI) (stop bool)) error
|
||||
|
||||
GetAllSDKDelegations(ctx sdk.Context) []stakingtypes.Delegation
|
||||
GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator)
|
||||
GetAllDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress) []stakingtypes.Delegation
|
||||
GetAllSDKDelegations(ctx context.Context) ([]stakingtypes.Delegation, error)
|
||||
GetAllValidators(ctx context.Context) ([]stakingtypes.Validator, error)
|
||||
GetAllDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress) ([]stakingtypes.Delegation, error)
|
||||
}
|
||||
|
||||
// StakingHooks event hooks for staking validator object (noalias)
|
||||
type StakingHooks interface {
|
||||
AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) // Must be called when a validator is created
|
||||
AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress)
|
||||
AfterValidatorCreated(ctx context.Context, valAddr sdk.ValAddress) error // Must be called when a validator is created
|
||||
AfterDelegationModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ require (
|
||||
cosmossdk.io/store v0.1.0-alpha.1.0.20230606190835-3e18f4088b2c
|
||||
github.com/cometbft/cometbft v0.38.0-rc1
|
||||
github.com/cosmos/cosmos-proto v1.0.0-beta.3
|
||||
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230614103911-b3da8bb4e801
|
||||
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230616095813-1111e0b51118
|
||||
github.com/cosmos/gogoproto v1.4.10
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/golang/protobuf v1.5.3
|
||||
|
||||
@ -177,6 +177,8 @@ github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQ
|
||||
github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I=
|
||||
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230614103911-b3da8bb4e801 h1:Qg0EgcEYtN0RWmxaFWTTCeMDfnbHB6UEzHucafy14i8=
|
||||
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230614103911-b3da8bb4e801/go.mod h1:VwFzgpv4z/Mrx+0sQpWwURCHx4h/iAalMdKIe3VEyBw=
|
||||
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230616095813-1111e0b51118 h1:XIBDrJ25Sv4nnO6LspwXQkiMYnlo7j52XCl2KzBMjoQ=
|
||||
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230616095813-1111e0b51118/go.mod h1:dtE3e607fUxLeDcDwSzKycM0lat8U5BbK/wsAmFk7HI=
|
||||
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
|
||||
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
|
||||
github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE=
|
||||
|
||||
@ -26,10 +26,13 @@ import (
|
||||
// in the case of a lunatic attack.
|
||||
func (k Keeper) handleEquivocationEvidence(ctx context.Context, evidence *types.Equivocation) error {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
logger := k.Logger(sdkCtx)
|
||||
logger := k.Logger(ctx)
|
||||
consAddr := evidence.GetConsensusAddress()
|
||||
|
||||
validator := k.stakingKeeper.ValidatorByConsAddr(sdkCtx, consAddr)
|
||||
validator, err := k.stakingKeeper.ValidatorByConsAddr(ctx, consAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if validator == nil || validator.IsUnbonded() {
|
||||
// Defensive: Simulation doesn't take unbonding periods into account, and
|
||||
// CometBFT might break this assumption at some point.
|
||||
|
||||
@ -41,11 +41,12 @@ func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder {
|
||||
}
|
||||
|
||||
// GetParams mocks base method.
|
||||
func (m *MockStakingKeeper) GetParams(ctx types0.Context) types1.Params {
|
||||
func (m *MockStakingKeeper) GetParams(ctx context.Context) (types1.Params, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetParams", ctx)
|
||||
ret0, _ := ret[0].(types1.Params)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetParams indicates an expected call of GetParams.
|
||||
@ -55,11 +56,12 @@ func (mr *MockStakingKeeperMockRecorder) GetParams(ctx interface{}) *gomock.Call
|
||||
}
|
||||
|
||||
// ValidatorByConsAddr mocks base method.
|
||||
func (m *MockStakingKeeper) ValidatorByConsAddr(arg0 types0.Context, arg1 types0.ConsAddress) types1.ValidatorI {
|
||||
func (m *MockStakingKeeper) ValidatorByConsAddr(arg0 context.Context, arg1 types0.ConsAddress) (types1.ValidatorI, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatorByConsAddr", arg0, arg1)
|
||||
ret0, _ := ret[0].(types1.ValidatorI)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ValidatorByConsAddr indicates an expected call of ValidatorByConsAddr.
|
||||
|
||||
@ -16,8 +16,8 @@ type (
|
||||
// StakingKeeper defines the staking module interface contract needed by the
|
||||
// evidence module.
|
||||
StakingKeeper interface {
|
||||
ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.ValidatorI
|
||||
GetParams(ctx sdk.Context) (params stakingtypes.Params)
|
||||
ValidatorByConsAddr(context.Context, sdk.ConsAddress) (stakingtypes.ValidatorI, error)
|
||||
GetParams(ctx context.Context) (params stakingtypes.Params, err error)
|
||||
}
|
||||
|
||||
// SlashingKeeper defines the slashing module interface contract needed by the
|
||||
|
||||
@ -40,7 +40,7 @@ func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder {
|
||||
}
|
||||
|
||||
// ApplyAndReturnValidatorSetUpdates mocks base method.
|
||||
func (m *MockStakingKeeper) ApplyAndReturnValidatorSetUpdates(arg0 types0.Context) ([]types.ValidatorUpdate, error) {
|
||||
func (m *MockStakingKeeper) ApplyAndReturnValidatorSetUpdates(arg0 context.Context) ([]types.ValidatorUpdate, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ApplyAndReturnValidatorSetUpdates", arg0)
|
||||
ret0, _ := ret[0].([]types.ValidatorUpdate)
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
|
||||
// StakingKeeper defines the expected staking keeper (noalias)
|
||||
type StakingKeeper interface {
|
||||
ApplyAndReturnValidatorSetUpdates(sdk.Context) (updates []abci.ValidatorUpdate, err error)
|
||||
ApplyAndReturnValidatorSetUpdates(context.Context) (updates []abci.ValidatorUpdate, err error)
|
||||
}
|
||||
|
||||
// AccountKeeper defines the expected account keeper (noalias)
|
||||
|
||||
@ -95,10 +95,10 @@ func setupGovKeeper(t *testing.T) (
|
||||
return sdk.TokensFromConsensusPower(power, math.NewIntFromUint64(1000000))
|
||||
}).AnyTimes()
|
||||
|
||||
stakingKeeper.EXPECT().BondDenom(ctx).Return("stake").AnyTimes()
|
||||
stakingKeeper.EXPECT().BondDenom(ctx).Return("stake", nil).AnyTimes()
|
||||
stakingKeeper.EXPECT().IterateBondedValidatorsByPower(gomock.Any(), gomock.Any()).AnyTimes()
|
||||
stakingKeeper.EXPECT().IterateDelegations(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
stakingKeeper.EXPECT().TotalBondedTokens(gomock.Any()).Return(math.NewInt(10000000)).AnyTimes()
|
||||
stakingKeeper.EXPECT().TotalBondedTokens(gomock.Any()).Return(math.NewInt(10000000), nil).AnyTimes()
|
||||
distributionKeeper.EXPECT().FundCommunityPool(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
|
||||
|
||||
// Gov keeper initializations
|
||||
|
||||
@ -28,8 +28,7 @@ func (keeper Keeper) Tally(ctx context.Context, proposal v1.Proposal) (passes, b
|
||||
currValidators := make(map[string]v1.ValidatorGovInfo)
|
||||
|
||||
// fetch all the bonded validators, insert them into currValidators
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
keeper.sk.IterateBondedValidatorsByPower(sdkCtx, func(index int64, validator stakingtypes.ValidatorI) (stop bool) {
|
||||
err = keeper.sk.IterateBondedValidatorsByPower(ctx, func(index int64, validator stakingtypes.ValidatorI) (stop bool) {
|
||||
currValidators[validator.GetOperator().String()] = v1.NewValidatorGovInfo(
|
||||
validator.GetOperator(),
|
||||
validator.GetBondedTokens(),
|
||||
@ -40,6 +39,10 @@ func (keeper Keeper) Tally(ctx context.Context, proposal v1.Proposal) (passes, b
|
||||
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
return false, false, tallyResults, err
|
||||
}
|
||||
|
||||
rng := collections.NewPrefixedPairRange[uint64, sdk.AccAddress](proposal.Id)
|
||||
err = keeper.Votes.Walk(ctx, rng, func(key collections.Pair[uint64, sdk.AccAddress], vote v1.Vote) (bool, error) {
|
||||
// if validator, just record it in the map
|
||||
@ -55,7 +58,7 @@ func (keeper Keeper) Tally(ctx context.Context, proposal v1.Proposal) (passes, b
|
||||
}
|
||||
|
||||
// iterate over all delegations from voter, deduct from any delegated-to validators
|
||||
keeper.sk.IterateDelegations(sdkCtx, voter, func(index int64, delegation stakingtypes.DelegationI) (stop bool) {
|
||||
err = keeper.sk.IterateDelegations(ctx, voter, func(index int64, delegation stakingtypes.DelegationI) (stop bool) {
|
||||
valAddrStr := delegation.GetValidatorAddr().String()
|
||||
|
||||
if val, ok := currValidators[valAddrStr]; ok {
|
||||
@ -77,6 +80,9 @@ func (keeper Keeper) Tally(ctx context.Context, proposal v1.Proposal) (passes, b
|
||||
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return false, keeper.Votes.Remove(ctx, collections.Join(vote.ProposalId, sdk.AccAddress(voter)))
|
||||
})
|
||||
@ -110,12 +116,17 @@ func (keeper Keeper) Tally(ctx context.Context, proposal v1.Proposal) (passes, b
|
||||
|
||||
// TODO: Upgrade the spec to cover all of these cases & remove pseudocode.
|
||||
// If there is no staked coins, the proposal fails
|
||||
if keeper.sk.TotalBondedTokens(sdkCtx).IsZero() {
|
||||
totalBonded, err := keeper.sk.TotalBondedTokens(ctx)
|
||||
if err != nil {
|
||||
return false, false, tallyResults, err
|
||||
}
|
||||
|
||||
if totalBonded.IsZero() {
|
||||
return false, false, tallyResults, nil
|
||||
}
|
||||
|
||||
// If there is not enough quorum of votes, the proposal fails
|
||||
percentVoting := totalVotingPower.Quo(math.LegacyNewDecFromInt(keeper.sk.TotalBondedTokens(sdkCtx)))
|
||||
percentVoting := totalVotingPower.Quo(math.LegacyNewDecFromInt(totalBonded))
|
||||
quorum, _ := math.LegacyNewDecFromStr(params.Quorum)
|
||||
if percentVoting.LT(quorum) {
|
||||
return false, params.BurnVoteQuorum, tallyResults, nil
|
||||
|
||||
@ -31,8 +31,8 @@ type BankKeeper interface {
|
||||
type StakingKeeper interface {
|
||||
types.StakingKeeper
|
||||
|
||||
BondDenom(ctx sdk.Context) string
|
||||
TokensFromConsensusPower(ctx sdk.Context, power int64) math.Int
|
||||
BondDenom(ctx context.Context) (string, error)
|
||||
TokensFromConsensusPower(ctx context.Context, power int64) math.Int
|
||||
}
|
||||
|
||||
// DistributionKeeper defines the expected distribution keeper
|
||||
|
||||
@ -985,11 +985,12 @@ func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder {
|
||||
}
|
||||
|
||||
// BondDenom mocks base method.
|
||||
func (m *MockStakingKeeper) BondDenom(ctx types.Context) string {
|
||||
func (m *MockStakingKeeper) BondDenom(ctx context.Context) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BondDenom", ctx)
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BondDenom indicates an expected call of BondDenom.
|
||||
@ -999,9 +1000,11 @@ func (mr *MockStakingKeeperMockRecorder) BondDenom(ctx interface{}) *gomock.Call
|
||||
}
|
||||
|
||||
// IterateBondedValidatorsByPower mocks base method.
|
||||
func (m *MockStakingKeeper) IterateBondedValidatorsByPower(arg0 types.Context, arg1 func(int64, types1.ValidatorI) bool) {
|
||||
func (m *MockStakingKeeper) IterateBondedValidatorsByPower(arg0 context.Context, arg1 func(int64, types1.ValidatorI) bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "IterateBondedValidatorsByPower", arg0, arg1)
|
||||
ret := m.ctrl.Call(m, "IterateBondedValidatorsByPower", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IterateBondedValidatorsByPower indicates an expected call of IterateBondedValidatorsByPower.
|
||||
@ -1011,9 +1014,11 @@ func (mr *MockStakingKeeperMockRecorder) IterateBondedValidatorsByPower(arg0, ar
|
||||
}
|
||||
|
||||
// IterateDelegations mocks base method.
|
||||
func (m *MockStakingKeeper) IterateDelegations(ctx types.Context, delegator types.AccAddress, fn func(int64, types1.DelegationI) bool) {
|
||||
func (m *MockStakingKeeper) IterateDelegations(ctx context.Context, delegator types.AccAddress, fn func(int64, types1.DelegationI) bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "IterateDelegations", ctx, delegator, fn)
|
||||
ret := m.ctrl.Call(m, "IterateDelegations", ctx, delegator, fn)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IterateDelegations indicates an expected call of IterateDelegations.
|
||||
@ -1023,7 +1028,7 @@ func (mr *MockStakingKeeperMockRecorder) IterateDelegations(ctx, delegator, fn i
|
||||
}
|
||||
|
||||
// TokensFromConsensusPower mocks base method.
|
||||
func (m *MockStakingKeeper) TokensFromConsensusPower(ctx types.Context, power int64) math.Int {
|
||||
func (m *MockStakingKeeper) TokensFromConsensusPower(ctx context.Context, power int64) math.Int {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "TokensFromConsensusPower", ctx, power)
|
||||
ret0, _ := ret[0].(math.Int)
|
||||
@ -1037,11 +1042,12 @@ func (mr *MockStakingKeeperMockRecorder) TokensFromConsensusPower(ctx, power int
|
||||
}
|
||||
|
||||
// TotalBondedTokens mocks base method.
|
||||
func (m *MockStakingKeeper) TotalBondedTokens(arg0 types.Context) math.Int {
|
||||
func (m *MockStakingKeeper) TotalBondedTokens(arg0 context.Context) (math.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "TotalBondedTokens", arg0)
|
||||
ret0, _ := ret[0].(math.Int)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// TotalBondedTokens indicates an expected call of TotalBondedTokens.
|
||||
|
||||
@ -20,14 +20,14 @@ type ParamSubspace interface {
|
||||
type StakingKeeper interface {
|
||||
// iterate through bonded validators by operator address, execute func for each validator
|
||||
IterateBondedValidatorsByPower(
|
||||
sdk.Context, func(index int64, validator stakingtypes.ValidatorI) (stop bool),
|
||||
)
|
||||
context.Context, func(index int64, validator stakingtypes.ValidatorI) (stop bool),
|
||||
) error
|
||||
|
||||
TotalBondedTokens(sdk.Context) math.Int // total bonded tokens within the validator set
|
||||
TotalBondedTokens(context.Context) (math.Int, error) // total bonded tokens within the validator set
|
||||
IterateDelegations(
|
||||
ctx sdk.Context, delegator sdk.AccAddress,
|
||||
ctx context.Context, delegator sdk.AccAddress,
|
||||
fn func(index int64, delegation stakingtypes.DelegationI) (stop bool),
|
||||
)
|
||||
) error
|
||||
}
|
||||
|
||||
// DistributionKeeper defines the expected distribution keeper (noalias)
|
||||
|
||||
@ -26,12 +26,19 @@ func BeginBlocker(ctx context.Context, k keeper.Keeper, ic types.InflationCalcul
|
||||
}
|
||||
|
||||
// recalculate inflation rate
|
||||
totalStakingSupply := k.StakingTokenSupply(ctx)
|
||||
bondedRatio := k.BondedRatio(ctx)
|
||||
totalStakingSupply, err := k.StakingTokenSupply(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bondedRatio, err := k.BondedRatio(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
minter.Inflation = ic(ctx, minter, params, bondedRatio)
|
||||
minter.AnnualProvisions = minter.NextAnnualProvisions(params, totalStakingSupply)
|
||||
err = k.Minter.Set(ctx, minter)
|
||||
if err != nil {
|
||||
if err = k.Minter.Set(ctx, minter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@ -80,16 +80,14 @@ func (k Keeper) Logger(ctx context.Context) log.Logger {
|
||||
|
||||
// StakingTokenSupply implements an alias call to the underlying staking keeper's
|
||||
// StakingTokenSupply to be used in BeginBlocker.
|
||||
func (k Keeper) StakingTokenSupply(ctx context.Context) math.Int {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
return k.stakingKeeper.StakingTokenSupply(sdkCtx)
|
||||
func (k Keeper) StakingTokenSupply(ctx context.Context) (math.Int, error) {
|
||||
return k.stakingKeeper.StakingTokenSupply(ctx)
|
||||
}
|
||||
|
||||
// BondedRatio implements an alias call to the underlying staking keeper's
|
||||
// BondedRatio to be used in BeginBlocker.
|
||||
func (k Keeper) BondedRatio(ctx context.Context) math.LegacyDec {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
return k.stakingKeeper.BondedRatio(sdkCtx)
|
||||
func (k Keeper) BondedRatio(ctx context.Context) (math.LegacyDec, error) {
|
||||
return k.stakingKeeper.BondedRatio(ctx)
|
||||
}
|
||||
|
||||
// MintCoins implements an alias call to the underlying supply keeper's
|
||||
|
||||
@ -73,12 +73,16 @@ func (s *IntegrationTestSuite) SetupTest() {
|
||||
|
||||
func (s *IntegrationTestSuite) TestAliasFunctions() {
|
||||
stakingTokenSupply := math.NewIntFromUint64(100000000000)
|
||||
s.stakingKeeper.EXPECT().StakingTokenSupply(s.ctx).Return(stakingTokenSupply)
|
||||
s.Require().Equal(s.mintKeeper.StakingTokenSupply(s.ctx), stakingTokenSupply)
|
||||
s.stakingKeeper.EXPECT().StakingTokenSupply(s.ctx).Return(stakingTokenSupply, nil)
|
||||
tokenSupply, err := s.mintKeeper.StakingTokenSupply(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(tokenSupply, stakingTokenSupply)
|
||||
|
||||
bondedRatio := math.LegacyNewDecWithPrec(15, 2)
|
||||
s.stakingKeeper.EXPECT().BondedRatio(s.ctx).Return(bondedRatio)
|
||||
s.Require().Equal(s.mintKeeper.BondedRatio(s.ctx), bondedRatio)
|
||||
s.stakingKeeper.EXPECT().BondedRatio(s.ctx).Return(bondedRatio, nil)
|
||||
ratio, err := s.mintKeeper.BondedRatio(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(ratio, bondedRatio)
|
||||
|
||||
coins := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000000)))
|
||||
s.bankKeeper.EXPECT().MintCoins(s.ctx, types.ModuleName, coins).Return(nil)
|
||||
|
||||
@ -37,11 +37,12 @@ func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder {
|
||||
}
|
||||
|
||||
// BondedRatio mocks base method.
|
||||
func (m *MockStakingKeeper) BondedRatio(ctx types.Context) math.LegacyDec {
|
||||
func (m *MockStakingKeeper) BondedRatio(ctx context.Context) (math.LegacyDec, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BondedRatio", ctx)
|
||||
ret0, _ := ret[0].(math.LegacyDec)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BondedRatio indicates an expected call of BondedRatio.
|
||||
@ -51,11 +52,12 @@ func (mr *MockStakingKeeperMockRecorder) BondedRatio(ctx interface{}) *gomock.Ca
|
||||
}
|
||||
|
||||
// StakingTokenSupply mocks base method.
|
||||
func (m *MockStakingKeeper) StakingTokenSupply(ctx types.Context) math.Int {
|
||||
func (m *MockStakingKeeper) StakingTokenSupply(ctx context.Context) (math.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "StakingTokenSupply", ctx)
|
||||
ret0, _ := ret[0].(math.Int)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// StakingTokenSupply indicates an expected call of StakingTokenSupply.
|
||||
|
||||
@ -10,8 +10,8 @@ import (
|
||||
|
||||
// StakingKeeper defines the expected staking keeper
|
||||
type StakingKeeper interface {
|
||||
StakingTokenSupply(ctx sdk.Context) math.Int
|
||||
BondedRatio(ctx sdk.Context) math.LegacyDec
|
||||
StakingTokenSupply(ctx context.Context) (math.Int, error)
|
||||
BondedRatio(ctx context.Context) (math.LegacyDec, error)
|
||||
}
|
||||
|
||||
// AccountKeeper defines the contract required for account APIs.
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package params_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
@ -22,7 +23,7 @@ import (
|
||||
|
||||
// StakingKeeper defines the expected staking keeper
|
||||
type StakingKeeper interface {
|
||||
MaxValidators(ctx sdk.Context) (res uint32)
|
||||
MaxValidators(ctx context.Context) (res uint32, err error)
|
||||
}
|
||||
|
||||
type HandlerTestSuite struct {
|
||||
@ -43,7 +44,7 @@ func (suite *HandlerTestSuite) SetupTest() {
|
||||
paramsKeeper.Subspace("staking").WithKeyTable(stakingtypes.ParamKeyTable()) //nolint:staticcheck // TODO: depreacte this test case
|
||||
ctrl := gomock.NewController(suite.T())
|
||||
stakingKeeper := paramstestutil.NewMockStakingKeeper(ctrl)
|
||||
stakingKeeper.EXPECT().MaxValidators(ctx).Return(uint32(1))
|
||||
stakingKeeper.EXPECT().MaxValidators(ctx).Return(uint32(1), nil)
|
||||
|
||||
suite.govHandler = params.NewParamChangeProposalHandler(paramsKeeper)
|
||||
suite.stakingKeeper = stakingKeeper
|
||||
@ -69,7 +70,8 @@ func (suite *HandlerTestSuite) TestProposalHandler() {
|
||||
"all fields",
|
||||
testProposal(proposal.NewParamChange(stakingtypes.ModuleName, string(stakingtypes.KeyMaxValidators), "1")),
|
||||
func() {
|
||||
maxVals := suite.stakingKeeper.MaxValidators(suite.ctx)
|
||||
maxVals, err := suite.stakingKeeper.MaxValidators(suite.ctx)
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Equal(uint32(1), maxVals)
|
||||
},
|
||||
false,
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
types "github.com/cosmos/cosmos-sdk/types"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
@ -35,11 +35,12 @@ func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder {
|
||||
}
|
||||
|
||||
// MaxValidators mocks base method.
|
||||
func (m *MockStakingKeeper) MaxValidators(ctx types.Context) uint32 {
|
||||
func (m *MockStakingKeeper) MaxValidators(ctx context.Context) (uint32, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MaxValidators", ctx)
|
||||
ret0, _ := ret[0].(uint32)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// MaxValidators indicates an expected call of MaxValidators.
|
||||
|
||||
@ -51,19 +51,23 @@ func TestBeginBlocker(t *testing.T) {
|
||||
power := int64(100)
|
||||
amt := tstaking.CreateValidatorWithValPower(addr, pk, power, true)
|
||||
stakingKeeper.EndBlocker(ctx)
|
||||
bondDenom, err := stakingKeeper.BondDenom(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(
|
||||
t, bankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)),
|
||||
sdk.NewCoins(sdk.NewCoin(stakingKeeper.GetParams(ctx).BondDenom, testutil.InitTokens.Sub(amt))),
|
||||
sdk.NewCoins(sdk.NewCoin(bondDenom, testutil.InitTokens.Sub(amt))),
|
||||
)
|
||||
require.Equal(t, amt, stakingKeeper.Validator(ctx, addr).GetBondedTokens())
|
||||
val, err := stakingKeeper.Validator(ctx, addr)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, amt, val.GetBondedTokens())
|
||||
|
||||
val := abci.Validator{
|
||||
abciVal := abci.Validator{
|
||||
Address: pk.Address(),
|
||||
Power: power,
|
||||
}
|
||||
|
||||
ctx = ctx.WithVoteInfos([]abci.VoteInfo{{
|
||||
Validator: val,
|
||||
Validator: abciVal,
|
||||
BlockIdFlag: cmtproto.BlockIDFlagCommit,
|
||||
}})
|
||||
|
||||
@ -85,7 +89,7 @@ func TestBeginBlocker(t *testing.T) {
|
||||
for ; height < signedBlocksWindow; height++ {
|
||||
ctx = ctx.WithBlockHeight(height).
|
||||
WithVoteInfos([]abci.VoteInfo{{
|
||||
Validator: val,
|
||||
Validator: abciVal,
|
||||
BlockIdFlag: cmtproto.BlockIDFlagCommit,
|
||||
}})
|
||||
|
||||
@ -99,7 +103,7 @@ func TestBeginBlocker(t *testing.T) {
|
||||
for ; height < ((signedBlocksWindow * 2) - minSignedPerWindow + 1); height++ {
|
||||
ctx = ctx.WithBlockHeight(height).
|
||||
WithVoteInfos([]abci.VoteInfo{{
|
||||
Validator: val,
|
||||
Validator: abciVal,
|
||||
BlockIdFlag: cmtproto.BlockIDFlagAbsent,
|
||||
}})
|
||||
|
||||
@ -112,7 +116,7 @@ func TestBeginBlocker(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// validator should be jailed
|
||||
validator, found := stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(pk))
|
||||
require.True(t, found)
|
||||
validator, err := stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(pk))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, stakingtypes.Unbonding, validator.GetStatus())
|
||||
}
|
||||
|
||||
@ -94,8 +94,9 @@ func TestSlashingMsgs(t *testing.T) {
|
||||
app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: app.LastBlockHeight() + 1})
|
||||
|
||||
ctxCheck = baseApp.NewContext(true)
|
||||
validator, found := stakingKeeper.GetValidator(ctxCheck, sdk.ValAddress(addr1))
|
||||
require.True(t, found)
|
||||
validator, err := stakingKeeper.GetValidator(ctxCheck, sdk.ValAddress(addr1))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, sdk.ValAddress(addr1).String(), validator.OperatorAddress)
|
||||
require.Equal(t, stakingtypes.Bonded, validator.Status)
|
||||
require.True(math.IntEq(t, bondTokens, validator.BondedTokens()))
|
||||
|
||||
@ -45,7 +45,7 @@ func (s *KeeperTestSuite) TestExportAndInitGenesis() {
|
||||
require.NotEqual(info1, newInfo1)
|
||||
|
||||
// Initialize genesis with genesis state before tombstone
|
||||
s.stakingKeeper.EXPECT().IterateValidators(ctx, gomock.Any()).Return()
|
||||
s.stakingKeeper.EXPECT().IterateValidators(ctx, gomock.Any()).Return(nil)
|
||||
keeper.InitGenesis(ctx, s.stakingKeeper, genesisState)
|
||||
|
||||
// Validator isTombstoned should return false as GenesisState is initialized
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
@ -23,14 +24,15 @@ func (k Keeper) Hooks() Hooks {
|
||||
}
|
||||
|
||||
// AfterValidatorBonded updates the signing info start height or create a new signing info
|
||||
func (h Hooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error {
|
||||
func (h Hooks) AfterValidatorBonded(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
signingInfo, err := h.k.GetValidatorSigningInfo(ctx, consAddr)
|
||||
if err == nil {
|
||||
signingInfo.StartHeight = ctx.BlockHeight()
|
||||
signingInfo.StartHeight = sdkCtx.BlockHeight()
|
||||
} else {
|
||||
signingInfo = types.NewValidatorSigningInfo(
|
||||
consAddr,
|
||||
ctx.BlockHeight(),
|
||||
sdkCtx.BlockHeight(),
|
||||
0,
|
||||
time.Unix(0, 0),
|
||||
false,
|
||||
@ -42,49 +44,54 @@ func (h Hooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, v
|
||||
}
|
||||
|
||||
// AfterValidatorRemoved deletes the address-pubkey relation when a validator is removed,
|
||||
func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, _ sdk.ValAddress) error {
|
||||
func (h Hooks) AfterValidatorRemoved(ctx context.Context, consAddr sdk.ConsAddress, _ sdk.ValAddress) error {
|
||||
return h.k.deleteAddrPubkeyRelation(ctx, crypto.Address(consAddr))
|
||||
}
|
||||
|
||||
// AfterValidatorCreated adds the address-pubkey relation when a validator is created.
|
||||
func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error {
|
||||
validator := h.k.sk.Validator(ctx, valAddr)
|
||||
func (h Hooks) AfterValidatorCreated(ctx context.Context, valAddr sdk.ValAddress) error {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
validator, err := h.k.sk.Validator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
consPk, err := validator.ConsPubKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return h.k.AddPubkey(ctx, consPk)
|
||||
return h.k.AddPubkey(sdkCtx, consPk)
|
||||
}
|
||||
|
||||
func (h Hooks) AfterValidatorBeginUnbonding(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error {
|
||||
func (h Hooks) AfterValidatorBeginUnbonding(_ context.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) error {
|
||||
func (h Hooks) BeforeValidatorModified(_ context.Context, _ sdk.ValAddress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) BeforeDelegationCreated(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
|
||||
func (h Hooks) BeforeDelegationCreated(_ context.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) BeforeDelegationSharesModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
|
||||
func (h Hooks) BeforeDelegationSharesModified(_ context.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
|
||||
func (h Hooks) BeforeDelegationRemoved(_ context.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) AfterDelegationModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
|
||||
func (h Hooks) AfterDelegationModified(_ context.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) BeforeValidatorSlashed(_ sdk.Context, _ sdk.ValAddress, _ sdkmath.LegacyDec) error {
|
||||
func (h Hooks) BeforeValidatorSlashed(_ context.Context, _ sdk.ValAddress, _ sdkmath.LegacyDec) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hooks) AfterUnbondingInitiated(_ sdk.Context, _ uint64) error {
|
||||
func (h Hooks) AfterUnbondingInitiated(_ context.Context, _ uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ func (s *KeeperTestSuite) TestAfterValidatorCreatedOrRemoved() {
|
||||
validator, err := stakingtypes.NewValidator(sdk.ValAddress(addr), pubKey, stakingtypes.Description{})
|
||||
require.NoError(err)
|
||||
|
||||
s.stakingKeeper.EXPECT().Validator(ctx, valAddr).Return(validator)
|
||||
s.stakingKeeper.EXPECT().Validator(ctx, valAddr).Return(validator, nil)
|
||||
err = keeper.Hooks().AfterValidatorCreated(ctx, valAddr)
|
||||
require.NoError(err)
|
||||
|
||||
|
||||
@ -23,7 +23,12 @@ func (k Keeper) HandleValidatorSignature(ctx context.Context, addr cryptotypes.A
|
||||
consAddr := sdk.ConsAddress(addr)
|
||||
|
||||
// don't update missed blocks when validator's jailed
|
||||
if k.sk.IsValidatorJailed(sdkCtx, consAddr) {
|
||||
isJailed, err := k.sk.IsValidatorJailed(ctx, consAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isJailed {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -105,7 +110,10 @@ func (k Keeper) HandleValidatorSignature(ctx context.Context, addr cryptotypes.A
|
||||
|
||||
// if we are past the minimum height and the validator has missed too many blocks, punish them
|
||||
if height > minHeight && signInfo.MissedBlocksCounter > maxMissed {
|
||||
validator := k.sk.ValidatorByConsAddr(sdkCtx, consAddr)
|
||||
validator, err := k.sk.ValidatorByConsAddr(ctx, consAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if validator != nil && !validator.IsJailed() {
|
||||
// Downtime confirmed: slash and jail the validator
|
||||
// We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height,
|
||||
@ -120,7 +128,11 @@ func (k Keeper) HandleValidatorSignature(ctx context.Context, addr cryptotypes.A
|
||||
return err
|
||||
}
|
||||
|
||||
coinsBurned := k.sk.SlashWithInfractionReason(sdkCtx, consAddr, distributionHeight, power, slashFractionDowntime, stakingtypes.Infraction_INFRACTION_DOWNTIME)
|
||||
coinsBurned, err := k.sk.SlashWithInfractionReason(ctx, consAddr, distributionHeight, power, slashFractionDowntime, stakingtypes.Infraction_INFRACTION_DOWNTIME)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sdkCtx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeSlash,
|
||||
|
||||
@ -84,8 +84,12 @@ func (k Keeper) Slash(ctx context.Context, consAddr sdk.ConsAddress, fraction sd
|
||||
// SlashWithInfractionReason attempts to slash a validator. The slash is delegated to the staking
|
||||
// module to make the necessary validator changes. It specifies an intraction reason.
|
||||
func (k Keeper) SlashWithInfractionReason(ctx context.Context, consAddr sdk.ConsAddress, fraction sdkmath.LegacyDec, power, distributionHeight int64, infraction stakingtypes.Infraction) error {
|
||||
coinsBurned, err := k.sk.SlashWithInfractionReason(ctx, consAddr, distributionHeight, power, fraction, infraction)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
coinsBurned := k.sk.SlashWithInfractionReason(sdkCtx, consAddr, distributionHeight, power, fraction, infraction)
|
||||
sdkCtx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeSlash,
|
||||
|
||||
@ -90,7 +90,7 @@ func (s *KeeperTestSuite) TestJailAndSlash() {
|
||||
sdk.TokensToConsensusPower(sdkmath.NewInt(1), sdk.DefaultPowerReduction),
|
||||
slashFractionDoubleSign,
|
||||
stakingtypes.Infraction_INFRACTION_UNSPECIFIED,
|
||||
).Return(sdkmath.NewInt(0))
|
||||
).Return(sdkmath.NewInt(0), nil)
|
||||
|
||||
s.slashingKeeper.Slash(
|
||||
s.ctx,
|
||||
@ -100,7 +100,7 @@ func (s *KeeperTestSuite) TestJailAndSlash() {
|
||||
s.ctx.BlockHeight(),
|
||||
)
|
||||
|
||||
s.stakingKeeper.EXPECT().Jail(s.ctx, consAddr).Return()
|
||||
s.stakingKeeper.EXPECT().Jail(s.ctx, consAddr).Return(nil)
|
||||
s.slashingKeeper.Jail(s.ctx, consAddr)
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ func (s *KeeperTestSuite) TestJailAndSlashWithInfractionReason() {
|
||||
sdk.TokensToConsensusPower(sdkmath.NewInt(1), sdk.DefaultPowerReduction),
|
||||
slashFractionDoubleSign,
|
||||
stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN,
|
||||
).Return(sdkmath.NewInt(0))
|
||||
).Return(sdkmath.NewInt(0), nil)
|
||||
|
||||
s.slashingKeeper.SlashWithInfractionReason(
|
||||
s.ctx,
|
||||
@ -125,7 +125,7 @@ func (s *KeeperTestSuite) TestJailAndSlashWithInfractionReason() {
|
||||
stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN,
|
||||
)
|
||||
|
||||
s.stakingKeeper.EXPECT().Jail(s.ctx, consAddr).Return()
|
||||
s.stakingKeeper.EXPECT().Jail(s.ctx, consAddr).Return(nil)
|
||||
s.slashingKeeper.Jail(s.ctx, consAddr)
|
||||
}
|
||||
|
||||
|
||||
@ -170,8 +170,8 @@ func (s *KeeperTestSuite) TestUnjail() {
|
||||
val, err := types.NewValidator(valAddr, pubKey, types.Description{Moniker: "test"})
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val)
|
||||
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(nil)
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val, nil)
|
||||
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(nil, nil)
|
||||
|
||||
return &slashingtypes.MsgUnjail{
|
||||
ValidatorAddr: sdk.ValAddress(addr).String(),
|
||||
@ -186,7 +186,7 @@ func (s *KeeperTestSuite) TestUnjail() {
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
valAddr := sdk.ValAddress(addr)
|
||||
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(nil)
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(nil, nil)
|
||||
|
||||
return &slashingtypes.MsgUnjail{
|
||||
ValidatorAddr: valAddr.String(),
|
||||
@ -213,10 +213,10 @@ func (s *KeeperTestSuite) TestUnjail() {
|
||||
|
||||
s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
|
||||
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val)
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val, nil)
|
||||
del := types.NewDelegation(addr, valAddr, sdkmath.LegacyNewDec(100))
|
||||
|
||||
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del)
|
||||
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del, nil)
|
||||
|
||||
return &slashingtypes.MsgUnjail{
|
||||
ValidatorAddr: sdk.ValAddress(addr).String(),
|
||||
@ -243,10 +243,10 @@ func (s *KeeperTestSuite) TestUnjail() {
|
||||
|
||||
s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
|
||||
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val)
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val, nil)
|
||||
del := types.NewDelegation(addr, valAddr, sdkmath.LegacyNewDec(100))
|
||||
|
||||
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del)
|
||||
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del, nil)
|
||||
|
||||
return &slashingtypes.MsgUnjail{
|
||||
ValidatorAddr: sdk.ValAddress(addr).String(),
|
||||
@ -273,10 +273,10 @@ func (s *KeeperTestSuite) TestUnjail() {
|
||||
|
||||
s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
|
||||
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val)
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val, nil)
|
||||
del := types.NewDelegation(addr, valAddr, sdkmath.LegacyNewDec(10000))
|
||||
|
||||
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del)
|
||||
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del, nil)
|
||||
|
||||
return &slashingtypes.MsgUnjail{
|
||||
ValidatorAddr: sdk.ValAddress(addr).String(),
|
||||
@ -303,11 +303,11 @@ func (s *KeeperTestSuite) TestUnjail() {
|
||||
|
||||
s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
|
||||
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val)
|
||||
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val, nil)
|
||||
del := types.NewDelegation(addr, valAddr, sdkmath.LegacyNewDec(100))
|
||||
|
||||
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del)
|
||||
s.stakingKeeper.EXPECT().Unjail(s.ctx, sdk.ConsAddress(addr)).Return()
|
||||
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del, nil)
|
||||
s.stakingKeeper.EXPECT().Unjail(s.ctx, sdk.ConsAddress(addr)).Return(nil)
|
||||
|
||||
return &slashingtypes.MsgUnjail{
|
||||
ValidatorAddr: sdk.ValAddress(addr).String(),
|
||||
|
||||
@ -12,14 +12,20 @@ import (
|
||||
// Unjail calls the staking Unjail function to unjail a validator if the
|
||||
// jailed period has concluded
|
||||
func (k Keeper) Unjail(ctx context.Context, validatorAddr sdk.ValAddress) error {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
validator := k.sk.Validator(sdkCtx, validatorAddr)
|
||||
validator, err := k.sk.Validator(ctx, validatorAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if validator == nil {
|
||||
return types.ErrNoValidatorForAddress
|
||||
}
|
||||
|
||||
// cannot be unjailed if no self-delegation exists
|
||||
selfDel := k.sk.Delegation(sdkCtx, sdk.AccAddress(validatorAddr), validatorAddr)
|
||||
selfDel, err := k.sk.Delegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if selfDel == nil {
|
||||
return types.ErrMissingSelfDelegation
|
||||
}
|
||||
@ -57,11 +63,11 @@ func (k Keeper) Unjail(ctx context.Context, validatorAddr sdk.ValAddress) error
|
||||
}
|
||||
|
||||
// cannot be unjailed until out of jail
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
if sdkCtx.BlockHeader().Time.Before(info.JailedUntil) {
|
||||
return types.ErrValidatorJailed
|
||||
}
|
||||
}
|
||||
|
||||
k.sk.Unjail(sdkCtx, consAddr)
|
||||
return nil
|
||||
return k.sk.Unjail(ctx, consAddr)
|
||||
}
|
||||
|
||||
@ -63,7 +63,12 @@ func SimulateMsgUnjail(
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
msgType := sdk.MsgTypeURL(&types.MsgUnjail{})
|
||||
|
||||
validator, ok := testutil.RandSliceElem(r, sk.GetAllValidators(ctx))
|
||||
allVals, err := sk.GetAllValidators(ctx)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to get all validators"), nil, err
|
||||
}
|
||||
|
||||
validator, ok := testutil.RandSliceElem(r, allVals)
|
||||
if !ok {
|
||||
return simtypes.NoOpMsg(types.ModuleName, msgType, "validator is not ok"), nil, nil // skip
|
||||
}
|
||||
@ -87,7 +92,11 @@ func SimulateMsgUnjail(
|
||||
return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to find validator signing info"), nil, err // skip
|
||||
}
|
||||
|
||||
selfDel := sk.Delegation(ctx, simAccount.Address, validator.GetOperator())
|
||||
selfDel, err := sk.Delegation(ctx, simAccount.Address, validator.GetOperator())
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to get self delegation"), nil, err
|
||||
}
|
||||
|
||||
if selfDel == nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, msgType, "self delegation is nil"), nil, nil // skip
|
||||
}
|
||||
|
||||
@ -254,11 +254,12 @@ func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder {
|
||||
}
|
||||
|
||||
// Delegation mocks base method.
|
||||
func (m *MockStakingKeeper) Delegation(arg0 types.Context, arg1 types.AccAddress, arg2 types.ValAddress) types1.DelegationI {
|
||||
func (m *MockStakingKeeper) Delegation(arg0 context.Context, arg1 types.AccAddress, arg2 types.ValAddress) (types1.DelegationI, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delegation", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(types1.DelegationI)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Delegation indicates an expected call of Delegation.
|
||||
@ -268,11 +269,12 @@ func (mr *MockStakingKeeperMockRecorder) Delegation(arg0, arg1, arg2 interface{}
|
||||
}
|
||||
|
||||
// GetAllValidators mocks base method.
|
||||
func (m *MockStakingKeeper) GetAllValidators(ctx types.Context) []types1.Validator {
|
||||
func (m *MockStakingKeeper) GetAllValidators(ctx context.Context) ([]types1.Validator, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAllValidators", ctx)
|
||||
ret0, _ := ret[0].([]types1.Validator)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAllValidators indicates an expected call of GetAllValidators.
|
||||
@ -282,11 +284,12 @@ func (mr *MockStakingKeeperMockRecorder) GetAllValidators(ctx interface{}) *gomo
|
||||
}
|
||||
|
||||
// IsValidatorJailed mocks base method.
|
||||
func (m *MockStakingKeeper) IsValidatorJailed(ctx types.Context, addr types.ConsAddress) bool {
|
||||
func (m *MockStakingKeeper) IsValidatorJailed(ctx context.Context, addr types.ConsAddress) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "IsValidatorJailed", ctx, addr)
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// IsValidatorJailed indicates an expected call of IsValidatorJailed.
|
||||
@ -296,9 +299,11 @@ func (mr *MockStakingKeeperMockRecorder) IsValidatorJailed(ctx, addr interface{}
|
||||
}
|
||||
|
||||
// IterateValidators mocks base method.
|
||||
func (m *MockStakingKeeper) IterateValidators(arg0 types.Context, arg1 func(int64, types1.ValidatorI) bool) {
|
||||
func (m *MockStakingKeeper) IterateValidators(arg0 context.Context, arg1 func(int64, types1.ValidatorI) bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "IterateValidators", arg0, arg1)
|
||||
ret := m.ctrl.Call(m, "IterateValidators", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IterateValidators indicates an expected call of IterateValidators.
|
||||
@ -308,9 +313,11 @@ func (mr *MockStakingKeeperMockRecorder) IterateValidators(arg0, arg1 interface{
|
||||
}
|
||||
|
||||
// Jail mocks base method.
|
||||
func (m *MockStakingKeeper) Jail(arg0 types.Context, arg1 types.ConsAddress) {
|
||||
func (m *MockStakingKeeper) Jail(arg0 context.Context, arg1 types.ConsAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Jail", arg0, arg1)
|
||||
ret := m.ctrl.Call(m, "Jail", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Jail indicates an expected call of Jail.
|
||||
@ -320,11 +327,12 @@ func (mr *MockStakingKeeperMockRecorder) Jail(arg0, arg1 interface{}) *gomock.Ca
|
||||
}
|
||||
|
||||
// MaxValidators mocks base method.
|
||||
func (m *MockStakingKeeper) MaxValidators(arg0 types.Context) uint32 {
|
||||
func (m *MockStakingKeeper) MaxValidators(arg0 context.Context) (uint32, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MaxValidators", arg0)
|
||||
ret0, _ := ret[0].(uint32)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// MaxValidators indicates an expected call of MaxValidators.
|
||||
@ -334,11 +342,12 @@ func (mr *MockStakingKeeperMockRecorder) MaxValidators(arg0 interface{}) *gomock
|
||||
}
|
||||
|
||||
// Slash mocks base method.
|
||||
func (m *MockStakingKeeper) Slash(arg0 types.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec) math.Int {
|
||||
func (m *MockStakingKeeper) Slash(arg0 context.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec) (math.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Slash", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(math.Int)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Slash indicates an expected call of Slash.
|
||||
@ -348,11 +357,12 @@ func (mr *MockStakingKeeperMockRecorder) Slash(arg0, arg1, arg2, arg3, arg4 inte
|
||||
}
|
||||
|
||||
// SlashWithInfractionReason mocks base method.
|
||||
func (m *MockStakingKeeper) SlashWithInfractionReason(arg0 types.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec, arg5 types1.Infraction) math.Int {
|
||||
func (m *MockStakingKeeper) SlashWithInfractionReason(arg0 context.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec, arg5 types1.Infraction) (math.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SlashWithInfractionReason", arg0, arg1, arg2, arg3, arg4, arg5)
|
||||
ret0, _ := ret[0].(math.Int)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SlashWithInfractionReason indicates an expected call of SlashWithInfractionReason.
|
||||
@ -362,9 +372,11 @@ func (mr *MockStakingKeeperMockRecorder) SlashWithInfractionReason(arg0, arg1, a
|
||||
}
|
||||
|
||||
// Unjail mocks base method.
|
||||
func (m *MockStakingKeeper) Unjail(arg0 types.Context, arg1 types.ConsAddress) {
|
||||
func (m *MockStakingKeeper) Unjail(arg0 context.Context, arg1 types.ConsAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Unjail", arg0, arg1)
|
||||
ret := m.ctrl.Call(m, "Unjail", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Unjail indicates an expected call of Unjail.
|
||||
@ -374,11 +386,12 @@ func (mr *MockStakingKeeperMockRecorder) Unjail(arg0, arg1 interface{}) *gomock.
|
||||
}
|
||||
|
||||
// Validator mocks base method.
|
||||
func (m *MockStakingKeeper) Validator(arg0 types.Context, arg1 types.ValAddress) types1.ValidatorI {
|
||||
func (m *MockStakingKeeper) Validator(arg0 context.Context, arg1 types.ValAddress) (types1.ValidatorI, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Validator", arg0, arg1)
|
||||
ret0, _ := ret[0].(types1.ValidatorI)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Validator indicates an expected call of Validator.
|
||||
@ -388,11 +401,12 @@ func (mr *MockStakingKeeperMockRecorder) Validator(arg0, arg1 interface{}) *gomo
|
||||
}
|
||||
|
||||
// ValidatorByConsAddr mocks base method.
|
||||
func (m *MockStakingKeeper) ValidatorByConsAddr(arg0 types.Context, arg1 types.ConsAddress) types1.ValidatorI {
|
||||
func (m *MockStakingKeeper) ValidatorByConsAddr(arg0 context.Context, arg1 types.ConsAddress) (types1.ValidatorI, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatorByConsAddr", arg0, arg1)
|
||||
ret0, _ := ret[0].(types1.ValidatorI)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ValidatorByConsAddr indicates an expected call of ValidatorByConsAddr.
|
||||
@ -425,7 +439,7 @@ func (m *MockStakingHooks) EXPECT() *MockStakingHooksMockRecorder {
|
||||
}
|
||||
|
||||
// AfterDelegationModified mocks base method.
|
||||
func (m *MockStakingHooks) AfterDelegationModified(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
|
||||
func (m *MockStakingHooks) AfterDelegationModified(ctx context.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AfterDelegationModified", ctx, delAddr, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
@ -439,7 +453,7 @@ func (mr *MockStakingHooksMockRecorder) AfterDelegationModified(ctx, delAddr, va
|
||||
}
|
||||
|
||||
// AfterValidatorBeginUnbonding mocks base method.
|
||||
func (m *MockStakingHooks) AfterValidatorBeginUnbonding(ctx types.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
|
||||
func (m *MockStakingHooks) AfterValidatorBeginUnbonding(ctx context.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AfterValidatorBeginUnbonding", ctx, consAddr, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
@ -453,7 +467,7 @@ func (mr *MockStakingHooksMockRecorder) AfterValidatorBeginUnbonding(ctx, consAd
|
||||
}
|
||||
|
||||
// AfterValidatorBonded mocks base method.
|
||||
func (m *MockStakingHooks) AfterValidatorBonded(ctx types.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
|
||||
func (m *MockStakingHooks) AfterValidatorBonded(ctx context.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AfterValidatorBonded", ctx, consAddr, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
@ -467,7 +481,7 @@ func (mr *MockStakingHooksMockRecorder) AfterValidatorBonded(ctx, consAddr, valA
|
||||
}
|
||||
|
||||
// AfterValidatorCreated mocks base method.
|
||||
func (m *MockStakingHooks) AfterValidatorCreated(ctx types.Context, valAddr types.ValAddress) error {
|
||||
func (m *MockStakingHooks) AfterValidatorCreated(ctx context.Context, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AfterValidatorCreated", ctx, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
@ -481,7 +495,7 @@ func (mr *MockStakingHooksMockRecorder) AfterValidatorCreated(ctx, valAddr inter
|
||||
}
|
||||
|
||||
// AfterValidatorRemoved mocks base method.
|
||||
func (m *MockStakingHooks) AfterValidatorRemoved(ctx types.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
|
||||
func (m *MockStakingHooks) AfterValidatorRemoved(ctx context.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AfterValidatorRemoved", ctx, consAddr, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
@ -495,7 +509,7 @@ func (mr *MockStakingHooksMockRecorder) AfterValidatorRemoved(ctx, consAddr, val
|
||||
}
|
||||
|
||||
// BeforeDelegationCreated mocks base method.
|
||||
func (m *MockStakingHooks) BeforeDelegationCreated(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
|
||||
func (m *MockStakingHooks) BeforeDelegationCreated(ctx context.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BeforeDelegationCreated", ctx, delAddr, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
@ -509,7 +523,7 @@ func (mr *MockStakingHooksMockRecorder) BeforeDelegationCreated(ctx, delAddr, va
|
||||
}
|
||||
|
||||
// BeforeDelegationRemoved mocks base method.
|
||||
func (m *MockStakingHooks) BeforeDelegationRemoved(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
|
||||
func (m *MockStakingHooks) BeforeDelegationRemoved(ctx context.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BeforeDelegationRemoved", ctx, delAddr, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
@ -523,7 +537,7 @@ func (mr *MockStakingHooksMockRecorder) BeforeDelegationRemoved(ctx, delAddr, va
|
||||
}
|
||||
|
||||
// BeforeDelegationSharesModified mocks base method.
|
||||
func (m *MockStakingHooks) BeforeDelegationSharesModified(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
|
||||
func (m *MockStakingHooks) BeforeDelegationSharesModified(ctx context.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BeforeDelegationSharesModified", ctx, delAddr, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
@ -537,7 +551,7 @@ func (mr *MockStakingHooksMockRecorder) BeforeDelegationSharesModified(ctx, delA
|
||||
}
|
||||
|
||||
// BeforeValidatorModified mocks base method.
|
||||
func (m *MockStakingHooks) BeforeValidatorModified(ctx types.Context, valAddr types.ValAddress) error {
|
||||
func (m *MockStakingHooks) BeforeValidatorModified(ctx context.Context, valAddr types.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BeforeValidatorModified", ctx, valAddr)
|
||||
ret0, _ := ret[0].(error)
|
||||
@ -551,7 +565,7 @@ func (mr *MockStakingHooksMockRecorder) BeforeValidatorModified(ctx, valAddr int
|
||||
}
|
||||
|
||||
// BeforeValidatorSlashed mocks base method.
|
||||
func (m *MockStakingHooks) BeforeValidatorSlashed(ctx types.Context, valAddr types.ValAddress, fraction math.LegacyDec) error {
|
||||
func (m *MockStakingHooks) BeforeValidatorSlashed(ctx context.Context, valAddr types.ValAddress, fraction math.LegacyDec) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BeforeValidatorSlashed", ctx, valAddr, fraction)
|
||||
ret0, _ := ret[0].(error)
|
||||
|
||||
@ -36,42 +36,42 @@ type ParamSubspace interface {
|
||||
// StakingKeeper expected staking keeper
|
||||
type StakingKeeper interface {
|
||||
// iterate through validators by operator address, execute func for each validator
|
||||
IterateValidators(sdk.Context,
|
||||
func(index int64, validator stakingtypes.ValidatorI) (stop bool))
|
||||
IterateValidators(context.Context,
|
||||
func(index int64, validator stakingtypes.ValidatorI) (stop bool)) error
|
||||
|
||||
Validator(sdk.Context, sdk.ValAddress) stakingtypes.ValidatorI // get a particular validator by operator address
|
||||
ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.ValidatorI // get a particular validator by consensus address
|
||||
Validator(context.Context, sdk.ValAddress) (stakingtypes.ValidatorI, error) // get a particular validator by operator address
|
||||
ValidatorByConsAddr(context.Context, sdk.ConsAddress) (stakingtypes.ValidatorI, error) // get a particular validator by consensus address
|
||||
|
||||
// slash the validator and delegators of the validator, specifying offense height, offense power, and slash fraction
|
||||
Slash(sdk.Context, sdk.ConsAddress, int64, int64, math.LegacyDec) math.Int
|
||||
SlashWithInfractionReason(sdk.Context, sdk.ConsAddress, int64, int64, math.LegacyDec, stakingtypes.Infraction) math.Int
|
||||
Jail(sdk.Context, sdk.ConsAddress) // jail a validator
|
||||
Unjail(sdk.Context, sdk.ConsAddress) // unjail a validator
|
||||
Slash(context.Context, sdk.ConsAddress, int64, int64, math.LegacyDec) (math.Int, error)
|
||||
SlashWithInfractionReason(context.Context, sdk.ConsAddress, int64, int64, math.LegacyDec, stakingtypes.Infraction) (math.Int, error)
|
||||
Jail(context.Context, sdk.ConsAddress) error // jail a validator
|
||||
Unjail(context.Context, sdk.ConsAddress) error // unjail a validator
|
||||
|
||||
// Delegation allows for getting a particular delegation for a given validator
|
||||
// and delegator outside the scope of the staking module.
|
||||
Delegation(sdk.Context, sdk.AccAddress, sdk.ValAddress) stakingtypes.DelegationI
|
||||
GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator)
|
||||
Delegation(context.Context, sdk.AccAddress, sdk.ValAddress) (stakingtypes.DelegationI, error)
|
||||
GetAllValidators(ctx context.Context) ([]stakingtypes.Validator, error)
|
||||
|
||||
// MaxValidators returns the maximum amount of bonded validators
|
||||
MaxValidators(sdk.Context) uint32
|
||||
MaxValidators(context.Context) (uint32, error)
|
||||
|
||||
// IsValidatorJailed returns if the validator is jailed.
|
||||
IsValidatorJailed(ctx sdk.Context, addr sdk.ConsAddress) bool
|
||||
IsValidatorJailed(ctx context.Context, addr sdk.ConsAddress) (bool, error)
|
||||
}
|
||||
|
||||
// StakingHooks event hooks for staking validator object (noalias)
|
||||
type StakingHooks interface {
|
||||
AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error // Must be called when a validator is created
|
||||
BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) error // Must be called when a validator's state changes
|
||||
AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is deleted
|
||||
AfterValidatorCreated(ctx context.Context, valAddr sdk.ValAddress) error // Must be called when a validator is created
|
||||
BeforeValidatorModified(ctx context.Context, valAddr sdk.ValAddress) error // Must be called when a validator's state changes
|
||||
AfterValidatorRemoved(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is deleted
|
||||
|
||||
AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is bonded
|
||||
AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator begins unbonding
|
||||
AfterValidatorBonded(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is bonded
|
||||
AfterValidatorBeginUnbonding(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator begins unbonding
|
||||
|
||||
BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is created
|
||||
BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation's shares are modified
|
||||
BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is removed
|
||||
AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error
|
||||
BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction math.LegacyDec) error
|
||||
BeforeDelegationCreated(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is created
|
||||
BeforeDelegationSharesModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation's shares are modified
|
||||
BeforeDelegationRemoved(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is removed
|
||||
AfterDelegationModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error
|
||||
BeforeValidatorSlashed(ctx context.Context, valAddr sdk.ValAddress, fraction math.LegacyDec) error
|
||||
}
|
||||
|
||||
@ -82,15 +82,18 @@ func TestStakingMsgs(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.True(t, sdk.Coins{genCoin.Sub(bondCoin)}.Equal(bankKeeper.GetAllBalances(ctxCheck, addr1)))
|
||||
|
||||
app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: app.LastBlockHeight() + 1})
|
||||
_, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: app.LastBlockHeight() + 1})
|
||||
require.NoError(t, err)
|
||||
ctxCheck = app.BaseApp.NewContext(true)
|
||||
validator, found := stakingKeeper.GetValidator(ctxCheck, sdk.ValAddress(addr1))
|
||||
require.True(t, found)
|
||||
validator, err := stakingKeeper.GetValidator(ctxCheck, sdk.ValAddress(addr1))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, sdk.ValAddress(addr1).String(), validator.OperatorAddress)
|
||||
require.Equal(t, types.Bonded, validator.Status)
|
||||
require.True(math.IntEq(t, bondTokens, validator.BondedTokens()))
|
||||
|
||||
app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: app.LastBlockHeight() + 1})
|
||||
_, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: app.LastBlockHeight() + 1})
|
||||
require.NoError(t, err)
|
||||
|
||||
// edit the validator
|
||||
description = types.NewDescription("bar_moniker", "", "", "", "")
|
||||
@ -101,8 +104,8 @@ func TestStakingMsgs(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
ctxCheck = app.BaseApp.NewContext(true)
|
||||
validator, found = stakingKeeper.GetValidator(ctxCheck, sdk.ValAddress(addr1))
|
||||
require.True(t, found)
|
||||
validator, err = stakingKeeper.GetValidator(ctxCheck, sdk.ValAddress(addr1))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, description, validator.Description)
|
||||
|
||||
// delegate
|
||||
@ -115,8 +118,8 @@ func TestStakingMsgs(t *testing.T) {
|
||||
|
||||
ctxCheck = app.BaseApp.NewContext(true)
|
||||
require.True(t, sdk.Coins{genCoin.Sub(bondCoin)}.Equal(bankKeeper.GetAllBalances(ctxCheck, addr2)))
|
||||
_, found = stakingKeeper.GetDelegation(ctxCheck, addr2, sdk.ValAddress(addr1))
|
||||
require.True(t, found)
|
||||
_, err = stakingKeeper.GetDelegation(ctxCheck, addr2, sdk.ValAddress(addr1))
|
||||
require.NoError(t, err)
|
||||
|
||||
// begin unbonding
|
||||
beginUnbondingMsg := types.NewMsgUndelegate(addr2, sdk.ValAddress(addr1), bondCoin)
|
||||
@ -126,8 +129,8 @@ func TestStakingMsgs(t *testing.T) {
|
||||
|
||||
// delegation should exist anymore
|
||||
ctxCheck = app.BaseApp.NewContext(true)
|
||||
_, found = stakingKeeper.GetDelegation(ctxCheck, addr2, sdk.ValAddress(addr1))
|
||||
require.False(t, found)
|
||||
_, err = stakingKeeper.GetDelegation(ctxCheck, addr2, sdk.ValAddress(addr1))
|
||||
require.ErrorIs(t, err, types.ErrNoDelegation)
|
||||
|
||||
// balance should be the same because bonding not yet complete
|
||||
require.True(t, sdk.Coins{genCoin.Sub(bondCoin)}.Equal(bankKeeper.GetAllBalances(ctxCheck, addr2)))
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
@ -78,6 +77,7 @@ func (s *CLITestSuite) TestPrepareConfigForTxCreateValidator() {
|
||||
privKey := ed25519.GenPrivKey()
|
||||
valPubKey := privKey.PubKey()
|
||||
moniker := "DefaultMoniker"
|
||||
require := s.Require()
|
||||
mkTxValCfg := func(amount, commission, commissionMax, commissionMaxChange, minSelfDelegation string) cli.TxCreateValidatorConfig {
|
||||
return cli.TxCreateValidatorConfig{
|
||||
IP: ip,
|
||||
@ -107,35 +107,35 @@ func (s *CLITestSuite) TestPrepareConfigForTxCreateValidator() {
|
||||
{
|
||||
name: "Custom amount",
|
||||
fsModify: func(fs *pflag.FlagSet) {
|
||||
fs.Set(cli.FlagAmount, "2000stake")
|
||||
require.NoError(fs.Set(cli.FlagAmount, "2000stake"))
|
||||
},
|
||||
expectedCfg: mkTxValCfg("2000stake", "0.1", "0.2", "0.01", "1"),
|
||||
},
|
||||
{
|
||||
name: "Custom commission rate",
|
||||
fsModify: func(fs *pflag.FlagSet) {
|
||||
fs.Set(cli.FlagCommissionRate, "0.54")
|
||||
require.NoError(fs.Set(cli.FlagCommissionRate, "0.54"))
|
||||
},
|
||||
expectedCfg: mkTxValCfg(cli.DefaultTokens.String()+sdk.DefaultBondDenom, "0.54", "0.2", "0.01", "1"),
|
||||
},
|
||||
{
|
||||
name: "Custom commission max rate",
|
||||
fsModify: func(fs *pflag.FlagSet) {
|
||||
fs.Set(cli.FlagCommissionMaxRate, "0.89")
|
||||
require.NoError(fs.Set(cli.FlagCommissionMaxRate, "0.89"))
|
||||
},
|
||||
expectedCfg: mkTxValCfg(cli.DefaultTokens.String()+sdk.DefaultBondDenom, "0.1", "0.89", "0.01", "1"),
|
||||
},
|
||||
{
|
||||
name: "Custom commission max change rate",
|
||||
fsModify: func(fs *pflag.FlagSet) {
|
||||
fs.Set(cli.FlagCommissionMaxChangeRate, "0.55")
|
||||
require.NoError(fs.Set(cli.FlagCommissionMaxChangeRate, "0.55"))
|
||||
},
|
||||
expectedCfg: mkTxValCfg(cli.DefaultTokens.String()+sdk.DefaultBondDenom, "0.1", "0.2", "0.55", "1"),
|
||||
},
|
||||
{
|
||||
name: "Custom min self delegations",
|
||||
fsModify: func(fs *pflag.FlagSet) {
|
||||
fs.Set(cli.FlagMinSelfDelegation, "0.33")
|
||||
require.NoError(fs.Set(cli.FlagMinSelfDelegation, "0.33"))
|
||||
},
|
||||
expectedCfg: mkTxValCfg(cli.DefaultTokens.String()+sdk.DefaultBondDenom, "0.1", "0.2", "0.01", "0.33"),
|
||||
},
|
||||
@ -150,9 +150,9 @@ func (s *CLITestSuite) TestPrepareConfigForTxCreateValidator() {
|
||||
tc.fsModify(fs)
|
||||
|
||||
cvCfg, err := cli.PrepareConfigForTxCreateValidator(fs, moniker, nodeID, chainID, valPubKey)
|
||||
require.NoError(s.T(), err)
|
||||
require.NoError(err)
|
||||
|
||||
require.Equal(s.T(), tc.expectedCfg, cvCfg)
|
||||
require.Equal(tc.expectedCfg, cvCfg)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
|
||||
// WriteValidators returns a slice of bonded genesis validators.
|
||||
func WriteValidators(ctx sdk.Context, keeper *keeper.Keeper) (vals []cmttypes.GenesisValidator, returnErr error) {
|
||||
keeper.IterateLastValidators(ctx, func(_ int64, validator types.ValidatorI) (stop bool) {
|
||||
err := keeper.IterateLastValidators(ctx, func(_ int64, validator types.ValidatorI) (stop bool) {
|
||||
pk, err := validator.ConsPubKey()
|
||||
if err != nil {
|
||||
returnErr = err
|
||||
@ -34,6 +34,9 @@ func WriteValidators(ctx sdk.Context, keeper *keeper.Keeper) (vals []cmttypes.Ge
|
||||
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -7,21 +7,18 @@ import (
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// BeginBlocker will persist the current header and validator set as a historical entry
|
||||
// and prune the oldest entry based on the HistoricalEntries parameter
|
||||
func (k *Keeper) BeginBlocker(ctx sdk.Context) {
|
||||
func (k *Keeper) BeginBlocker(ctx context.Context) error {
|
||||
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)
|
||||
|
||||
k.TrackHistoricalInfo(ctx)
|
||||
return k.TrackHistoricalInfo(ctx)
|
||||
}
|
||||
|
||||
// Called every block, update validator set
|
||||
func (k *Keeper) EndBlocker(ctx context.Context) ([]abci.ValidatorUpdate, error) {
|
||||
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker)
|
||||
|
||||
return k.BlockValidatorUpdates(sdk.UnwrapSDKContext(ctx)), nil
|
||||
return k.BlockValidatorUpdates(ctx)
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"context"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
@ -12,16 +12,21 @@ import (
|
||||
// Validator Set
|
||||
|
||||
// iterate through the validator set and perform the provided function
|
||||
func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validator types.ValidatorI) (stop bool)) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, types.ValidatorsKey)
|
||||
func (k Keeper) IterateValidators(ctx context.Context, fn func(index int64, validator types.ValidatorI) (stop bool)) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
iterator, err := store.Iterator(types.ValidatorsKey, storetypes.PrefixEndBytes(types.ValidatorsKey))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
i := int64(0)
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
validator := types.MustUnmarshalValidator(k.cdc, iterator.Value())
|
||||
validator, err := types.UnmarshalValidator(k.cdc, iterator.Value())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stop := fn(i, validator) // XXX is this safe will the validator unexposed fields be able to get written to?
|
||||
|
||||
if stop {
|
||||
@ -29,14 +34,22 @@ func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validato
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// iterate through the bonded validator set and perform the provided function
|
||||
func (k Keeper) IterateBondedValidatorsByPower(ctx sdk.Context, fn func(index int64, validator types.ValidatorI) (stop bool)) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
maxValidators := k.MaxValidators(ctx)
|
||||
func (k Keeper) IterateBondedValidatorsByPower(ctx context.Context, fn func(index int64, validator types.ValidatorI) (stop bool)) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
maxValidators, err := k.MaxValidators(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
iterator := storetypes.KVStoreReversePrefixIterator(store, types.ValidatorsByPowerIndexKey)
|
||||
iterator, err := store.ReverseIterator(types.ValidatorsByPowerIndexKey, storetypes.PrefixEndBytes(types.ValidatorsByPowerIndexKey))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
i := int64(0)
|
||||
@ -52,11 +65,16 @@ func (k Keeper) IterateBondedValidatorsByPower(ctx sdk.Context, fn func(index in
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// iterate through the active validator set and perform the provided function
|
||||
func (k Keeper) IterateLastValidators(ctx sdk.Context, fn func(index int64, validator types.ValidatorI) (stop bool)) {
|
||||
iterator := k.LastValidatorsIterator(ctx)
|
||||
func (k Keeper) IterateLastValidators(ctx context.Context, fn func(index int64, validator types.ValidatorI) (stop bool)) error {
|
||||
iterator, err := k.LastValidatorsIterator(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
i := int64(0)
|
||||
@ -64,9 +82,9 @@ func (k Keeper) IterateLastValidators(ctx sdk.Context, fn func(index int64, vali
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
address := types.AddressFromLastValidatorPowerKey(iterator.Key())
|
||||
|
||||
validator, found := k.GetValidator(ctx, address)
|
||||
if !found {
|
||||
panic(fmt.Sprintf("validator record not found for address: %v\n", address))
|
||||
validator, err := k.GetValidator(ctx, address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stop := fn(i, validator) // XXX is this safe will the validator unexposed fields be able to get written to?
|
||||
@ -75,26 +93,17 @@ func (k Keeper) IterateLastValidators(ctx sdk.Context, fn func(index int64, vali
|
||||
}
|
||||
i++
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validator gets the Validator interface for a particular address
|
||||
func (k Keeper) Validator(ctx sdk.Context, address sdk.ValAddress) types.ValidatorI {
|
||||
val, found := k.GetValidator(ctx, address)
|
||||
if !found {
|
||||
return nil
|
||||
}
|
||||
|
||||
return val
|
||||
func (k Keeper) Validator(ctx context.Context, address sdk.ValAddress) (types.ValidatorI, error) {
|
||||
return k.GetValidator(ctx, address)
|
||||
}
|
||||
|
||||
// ValidatorByConsAddr gets the validator interface for a particular pubkey
|
||||
func (k Keeper) ValidatorByConsAddr(ctx sdk.Context, addr sdk.ConsAddress) types.ValidatorI {
|
||||
val, found := k.GetValidatorByConsAddr(ctx, addr)
|
||||
if !found {
|
||||
return nil
|
||||
}
|
||||
|
||||
return val
|
||||
func (k Keeper) ValidatorByConsAddr(ctx context.Context, addr sdk.ConsAddress) (types.ValidatorI, error) {
|
||||
return k.GetValidatorByConsAddr(ctx, addr)
|
||||
}
|
||||
|
||||
// Delegation Set
|
||||
@ -105,27 +114,32 @@ func (k Keeper) GetValidatorSet() types.ValidatorSet {
|
||||
}
|
||||
|
||||
// Delegation get the delegation interface for a particular set of delegator and validator addresses
|
||||
func (k Keeper) Delegation(ctx sdk.Context, addrDel sdk.AccAddress, addrVal sdk.ValAddress) types.DelegationI {
|
||||
bond, ok := k.GetDelegation(ctx, addrDel, addrVal)
|
||||
if !ok {
|
||||
return nil
|
||||
func (k Keeper) Delegation(ctx context.Context, addrDel sdk.AccAddress, addrVal sdk.ValAddress) (types.DelegationI, error) {
|
||||
bond, err := k.GetDelegation(ctx, addrDel, addrVal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bond
|
||||
return bond, nil
|
||||
}
|
||||
|
||||
// iterate through all of the delegations from a delegator
|
||||
func (k Keeper) IterateDelegations(ctx sdk.Context, delAddr sdk.AccAddress,
|
||||
func (k Keeper) IterateDelegations(ctx context.Context, delAddr sdk.AccAddress,
|
||||
fn func(index int64, del types.DelegationI) (stop bool),
|
||||
) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
delegatorPrefixKey := types.GetDelegationsKey(delAddr)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, delegatorPrefixKey) // smallest to largest
|
||||
iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
for i := int64(0); iterator.Valid(); iterator.Next() {
|
||||
del := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
|
||||
del, err := types.UnmarshalDelegation(k.cdc, iterator.Value())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stop := fn(i, del)
|
||||
if stop {
|
||||
@ -133,18 +147,25 @@ func (k Keeper) IterateDelegations(ctx sdk.Context, delAddr sdk.AccAddress,
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// return all delegations used during genesis dump
|
||||
// TODO: remove this func, change all usage for iterate functionality
|
||||
func (k Keeper) GetAllSDKDelegations(ctx sdk.Context) (delegations []types.Delegation) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, types.DelegationKey)
|
||||
func (k Keeper) GetAllSDKDelegations(ctx context.Context) (delegations []types.Delegation, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
iterator, err := store.Iterator(types.DelegationKey, storetypes.PrefixEndBytes(types.DelegationKey))
|
||||
if err != nil {
|
||||
return delegations, err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
|
||||
delegation, err := types.UnmarshalDelegation(k.cdc, iterator.Value())
|
||||
if err != nil {
|
||||
return delegations, err
|
||||
}
|
||||
delegations = append(delegations, delegation)
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -44,20 +44,20 @@ func (s *KeeperTestSuite) TestDelegation() {
|
||||
bond1to1 := stakingtypes.NewDelegation(addrDels[0], valAddrs[0], math.LegacyNewDec(9))
|
||||
|
||||
// check the empty keeper first
|
||||
_, found := keeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
|
||||
require.False(found)
|
||||
_, err := keeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
|
||||
require.ErrorIs(err, stakingtypes.ErrNoDelegation)
|
||||
|
||||
// set and retrieve a record
|
||||
keeper.SetDelegation(ctx, bond1to1)
|
||||
resBond, found := keeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetDelegation(ctx, bond1to1))
|
||||
resBond, err := keeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(bond1to1, resBond)
|
||||
|
||||
// modify a records, save, and retrieve
|
||||
bond1to1.Shares = math.LegacyNewDec(99)
|
||||
keeper.SetDelegation(ctx, bond1to1)
|
||||
resBond, found = keeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetDelegation(ctx, bond1to1))
|
||||
resBond, err = keeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(bond1to1, resBond)
|
||||
|
||||
// add some more records
|
||||
@ -66,28 +66,33 @@ func (s *KeeperTestSuite) TestDelegation() {
|
||||
bond2to1 := stakingtypes.NewDelegation(addrDels[1], valAddrs[0], math.LegacyNewDec(9))
|
||||
bond2to2 := stakingtypes.NewDelegation(addrDels[1], valAddrs[1], math.LegacyNewDec(9))
|
||||
bond2to3 := stakingtypes.NewDelegation(addrDels[1], valAddrs[2], math.LegacyNewDec(9))
|
||||
keeper.SetDelegation(ctx, bond1to2)
|
||||
keeper.SetDelegation(ctx, bond1to3)
|
||||
keeper.SetDelegation(ctx, bond2to1)
|
||||
keeper.SetDelegation(ctx, bond2to2)
|
||||
keeper.SetDelegation(ctx, bond2to3)
|
||||
require.NoError(keeper.SetDelegation(ctx, bond1to2))
|
||||
require.NoError(keeper.SetDelegation(ctx, bond1to3))
|
||||
require.NoError(keeper.SetDelegation(ctx, bond2to1))
|
||||
require.NoError(keeper.SetDelegation(ctx, bond2to2))
|
||||
require.NoError(keeper.SetDelegation(ctx, bond2to3))
|
||||
|
||||
// test all bond retrieve capabilities
|
||||
resBonds := keeper.GetDelegatorDelegations(ctx, addrDels[0], 5)
|
||||
resBonds, err := keeper.GetDelegatorDelegations(ctx, addrDels[0], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(3, len(resBonds))
|
||||
require.Equal(bond1to1, resBonds[0])
|
||||
require.Equal(bond1to2, resBonds[1])
|
||||
require.Equal(bond1to3, resBonds[2])
|
||||
resBonds = keeper.GetAllDelegatorDelegations(ctx, addrDels[0])
|
||||
resBonds, err = keeper.GetAllDelegatorDelegations(ctx, addrDels[0])
|
||||
require.NoError(err)
|
||||
require.Equal(3, len(resBonds))
|
||||
resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[0], 2)
|
||||
resBonds, err = keeper.GetDelegatorDelegations(ctx, addrDels[0], 2)
|
||||
require.NoError(err)
|
||||
require.Equal(2, len(resBonds))
|
||||
resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
|
||||
resBonds, err = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(3, len(resBonds))
|
||||
require.Equal(bond2to1, resBonds[0])
|
||||
require.Equal(bond2to2, resBonds[1])
|
||||
require.Equal(bond2to3, resBonds[2])
|
||||
allBonds := keeper.GetAllDelegations(ctx)
|
||||
allBonds, err := keeper.GetAllDelegations(ctx)
|
||||
require.NoError(err)
|
||||
require.Equal(6, len(allBonds))
|
||||
require.Equal(bond1to1, allBonds[0])
|
||||
require.Equal(bond1to2, allBonds[1])
|
||||
@ -96,9 +101,11 @@ func (s *KeeperTestSuite) TestDelegation() {
|
||||
require.Equal(bond2to2, allBonds[4])
|
||||
require.Equal(bond2to3, allBonds[5])
|
||||
|
||||
resVals := keeper.GetDelegatorValidators(ctx, addrDels[0], 3)
|
||||
resVals, err := keeper.GetDelegatorValidators(ctx, addrDels[0], 3)
|
||||
require.NoError(err)
|
||||
require.Equal(3, len(resVals))
|
||||
resVals = keeper.GetDelegatorValidators(ctx, addrDels[1], 4)
|
||||
resVals, err = keeper.GetDelegatorValidators(ctx, addrDels[1], 4)
|
||||
require.NoError(err)
|
||||
require.Equal(3, len(resVals))
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
@ -110,35 +117,40 @@ func (s *KeeperTestSuite) TestDelegation() {
|
||||
require.Nil(err)
|
||||
require.Equal(valAddrs[i], resVal.GetOperator())
|
||||
|
||||
resDels := keeper.GetValidatorDelegations(ctx, valAddrs[i])
|
||||
resDels, err := keeper.GetValidatorDelegations(ctx, valAddrs[i])
|
||||
require.NoError(err)
|
||||
require.Len(resDels, 2)
|
||||
}
|
||||
|
||||
// test total bonded for single delegator
|
||||
expBonded := bond1to1.Shares.Add(bond2to1.Shares).Add(bond1to3.Shares)
|
||||
resDelBond := keeper.GetDelegatorBonded(ctx, addrDels[0])
|
||||
resDelBond, err := keeper.GetDelegatorBonded(ctx, addrDels[0])
|
||||
require.NoError(err)
|
||||
require.Equal(expBonded, math.LegacyNewDecFromInt(resDelBond))
|
||||
|
||||
// delete a record
|
||||
keeper.RemoveDelegation(ctx, bond2to3)
|
||||
_, found = keeper.GetDelegation(ctx, addrDels[1], valAddrs[2])
|
||||
require.False(found)
|
||||
resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
|
||||
require.NoError(keeper.RemoveDelegation(ctx, bond2to3))
|
||||
_, err = keeper.GetDelegation(ctx, addrDels[1], valAddrs[2])
|
||||
require.ErrorIs(err, stakingtypes.ErrNoDelegation)
|
||||
resBonds, err = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(2, len(resBonds))
|
||||
require.Equal(bond2to1, resBonds[0])
|
||||
require.Equal(bond2to2, resBonds[1])
|
||||
|
||||
resBonds = keeper.GetAllDelegatorDelegations(ctx, addrDels[1])
|
||||
resBonds, err = keeper.GetAllDelegatorDelegations(ctx, addrDels[1])
|
||||
require.NoError(err)
|
||||
require.Equal(2, len(resBonds))
|
||||
|
||||
// delete all the records from delegator 2
|
||||
keeper.RemoveDelegation(ctx, bond2to1)
|
||||
keeper.RemoveDelegation(ctx, bond2to2)
|
||||
_, found = keeper.GetDelegation(ctx, addrDels[1], valAddrs[0])
|
||||
require.False(found)
|
||||
_, found = keeper.GetDelegation(ctx, addrDels[1], valAddrs[1])
|
||||
require.False(found)
|
||||
resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
|
||||
require.NoError(keeper.RemoveDelegation(ctx, bond2to1))
|
||||
require.NoError(keeper.RemoveDelegation(ctx, bond2to2))
|
||||
_, err = keeper.GetDelegation(ctx, addrDels[1], valAddrs[0])
|
||||
require.ErrorIs(err, stakingtypes.ErrNoDelegation)
|
||||
_, err = keeper.GetDelegation(ctx, addrDels[1], valAddrs[1])
|
||||
require.ErrorIs(err, stakingtypes.ErrNoDelegation)
|
||||
resBonds, err = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(0, len(resBonds))
|
||||
}
|
||||
|
||||
@ -169,7 +181,8 @@ func (s *KeeperTestSuite) TestDelegationsByValIndex() {
|
||||
_, err := s.msgServer.Delegate(ctx, stakingtypes.NewMsgDelegate(addrDels[0], valAddrs[0], sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))))
|
||||
require.NoError(err)
|
||||
|
||||
dels := s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
dels, err := s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Len(dels, 1)
|
||||
|
||||
// delegate 4 tokens
|
||||
@ -178,7 +191,8 @@ func (s *KeeperTestSuite) TestDelegationsByValIndex() {
|
||||
_, err = s.msgServer.Delegate(ctx, stakingtypes.NewMsgDelegate(addrDels[1], valAddrs[0], sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(4))))
|
||||
require.NoError(err)
|
||||
|
||||
dels = s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
dels, err = s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Len(dels, 2)
|
||||
|
||||
// undelegate 1 token from del1
|
||||
@ -187,7 +201,8 @@ func (s *KeeperTestSuite) TestDelegationsByValIndex() {
|
||||
_, err = s.msgServer.Undelegate(ctx, stakingtypes.NewMsgUndelegate(addrDels[0], valAddrs[0], sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))))
|
||||
require.NoError(err)
|
||||
|
||||
dels = s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
dels, err = s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Len(dels, 2)
|
||||
|
||||
// undelegate 1 token from del1
|
||||
@ -196,7 +211,8 @@ func (s *KeeperTestSuite) TestDelegationsByValIndex() {
|
||||
_, err = s.msgServer.Undelegate(ctx, stakingtypes.NewMsgUndelegate(addrDels[0], valAddrs[0], sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))))
|
||||
require.NoError(err)
|
||||
|
||||
dels = s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
dels, err = s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Len(dels, 1)
|
||||
|
||||
// undelegate 2 tokens from del2
|
||||
@ -205,7 +221,8 @@ func (s *KeeperTestSuite) TestDelegationsByValIndex() {
|
||||
_, err = s.msgServer.Undelegate(ctx, stakingtypes.NewMsgUndelegate(addrDels[1], valAddrs[0], sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))))
|
||||
require.NoError(err)
|
||||
|
||||
dels = s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
dels, err = s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Len(dels, 1)
|
||||
|
||||
// undelegate 2 tokens from del2
|
||||
@ -214,7 +231,8 @@ func (s *KeeperTestSuite) TestDelegationsByValIndex() {
|
||||
_, err = s.msgServer.Undelegate(ctx, stakingtypes.NewMsgUndelegate(addrDels[1], valAddrs[0], sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))))
|
||||
require.NoError(err)
|
||||
|
||||
dels = s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
dels, err = s.stakingKeeper.GetValidatorDelegations(ctx, valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Len(dels, 0)
|
||||
}
|
||||
|
||||
@ -237,38 +255,43 @@ func (s *KeeperTestSuite) TestUnbondingDelegation() {
|
||||
)
|
||||
|
||||
// set and retrieve a record
|
||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||
resUnbond, found := keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetUnbondingDelegation(ctx, ubd))
|
||||
resUnbond, err := keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(ubd, resUnbond)
|
||||
|
||||
// modify a records, save, and retrieve
|
||||
expUnbond := math.NewInt(21)
|
||||
ubd.Entries[0].Balance = expUnbond
|
||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||
require.NoError(keeper.SetUnbondingDelegation(ctx, ubd))
|
||||
|
||||
resUnbonds := keeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
|
||||
resUnbonds, err := keeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resUnbonds))
|
||||
|
||||
resUnbonds = keeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
|
||||
resUnbonds, err = keeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resUnbonds))
|
||||
|
||||
resUnbond, found = keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.True(found)
|
||||
resUnbond, err = keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(ubd, resUnbond)
|
||||
|
||||
resDelUnbond := keeper.GetDelegatorUnbonding(ctx, delAddrs[0])
|
||||
resDelUnbond, err := keeper.GetDelegatorUnbonding(ctx, delAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(expUnbond, resDelUnbond)
|
||||
|
||||
// delete a record
|
||||
keeper.RemoveUnbondingDelegation(ctx, ubd)
|
||||
_, found = keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.False(found)
|
||||
require.NoError(keeper.RemoveUnbondingDelegation(ctx, ubd))
|
||||
_, err = keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.ErrorIs(err, stakingtypes.ErrNoUnbondingDelegation)
|
||||
|
||||
resUnbonds = keeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
|
||||
resUnbonds, err = keeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(0, len(resUnbonds))
|
||||
|
||||
resUnbonds = keeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
|
||||
resUnbonds, err = keeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(0, len(resUnbonds))
|
||||
}
|
||||
|
||||
@ -288,44 +311,51 @@ func (s *KeeperTestSuite) TestUnbondingDelegationsFromValidator() {
|
||||
)
|
||||
|
||||
// set and retrieve a record
|
||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||
resUnbond, found := keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetUnbondingDelegation(ctx, ubd))
|
||||
resUnbond, err := keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(ubd, resUnbond)
|
||||
|
||||
// modify a records, save, and retrieve
|
||||
expUnbond := sdk.NewInt(21)
|
||||
ubd.Entries[0].Balance = expUnbond
|
||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||
require.NoError(keeper.SetUnbondingDelegation(ctx, ubd))
|
||||
|
||||
resUnbonds := keeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
|
||||
resUnbonds, err := keeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resUnbonds))
|
||||
|
||||
resUnbonds = keeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
|
||||
resUnbonds, err = keeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resUnbonds))
|
||||
|
||||
resUnbonds = keeper.GetUnbondingDelegationsFromValidator(ctx, valAddrs[0])
|
||||
resUnbonds, err = keeper.GetUnbondingDelegationsFromValidator(ctx, valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resUnbonds))
|
||||
|
||||
resUnbond, found = keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.True(found)
|
||||
resUnbond, err = keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(ubd, resUnbond)
|
||||
|
||||
resDelUnbond := keeper.GetDelegatorUnbonding(ctx, delAddrs[0])
|
||||
resDelUnbond, err := keeper.GetDelegatorUnbonding(ctx, delAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(expUnbond, resDelUnbond)
|
||||
|
||||
// delete a record
|
||||
keeper.RemoveUnbondingDelegation(ctx, ubd)
|
||||
_, found = keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.False(found)
|
||||
require.NoError(keeper.RemoveUnbondingDelegation(ctx, ubd))
|
||||
_, err = keeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.ErrorIs(err, stakingtypes.ErrNoUnbondingDelegation)
|
||||
|
||||
resUnbonds = keeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
|
||||
resUnbonds, err = keeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(0, len(resUnbonds))
|
||||
|
||||
resUnbonds = keeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
|
||||
resUnbonds, err = keeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(0, len(resUnbonds))
|
||||
|
||||
resUnbonds = keeper.GetUnbondingDelegationsFromValidator(ctx, valAddrs[0])
|
||||
resUnbonds, err = keeper.GetUnbondingDelegationsFromValidator(ctx, valAddrs[0])
|
||||
require.NoError(err)
|
||||
require.Equal(0, len(resUnbonds))
|
||||
}
|
||||
|
||||
@ -345,17 +375,17 @@ func (s *KeeperTestSuite) TestUnbondDelegation() {
|
||||
_ = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
|
||||
delegation := stakingtypes.NewDelegation(delAddrs[0], valAddrs[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, delegation))
|
||||
|
||||
bondTokens := keeper.TokensFromConsensusPower(ctx, 6)
|
||||
amount, err := keeper.Unbond(ctx, delAddrs[0], valAddrs[0], math.LegacyNewDecFromInt(bondTokens))
|
||||
require.NoError(err)
|
||||
require.Equal(bondTokens, amount) // shares to be added to an unbonding delegation
|
||||
|
||||
delegation, found := keeper.GetDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.True(found)
|
||||
validator, found = keeper.GetValidator(ctx, valAddrs[0])
|
||||
require.True(found)
|
||||
delegation, err = keeper.GetDelegation(ctx, delAddrs[0], valAddrs[0])
|
||||
require.NoError(err)
|
||||
validator, err = keeper.GetValidator(ctx, valAddrs[0])
|
||||
require.NoError(err)
|
||||
|
||||
remainingTokens := startTokens.Sub(bondTokens)
|
||||
|
||||
@ -381,21 +411,21 @@ func (s *KeeperTestSuite) TestUndelegateSelfDelegationBelowMinSelfDelegation() {
|
||||
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
|
||||
validator = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
|
||||
require.True(validator.IsBonded())
|
||||
|
||||
selfDelegation := stakingtypes.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, selfDelegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, selfDelegation))
|
||||
|
||||
// create a second delegation to this validator
|
||||
keeper.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
require.NoError(keeper.DeleteValidatorByPowerIndex(ctx, validator))
|
||||
validator, issuedShares = validator.AddTokensFromDel(delTokens)
|
||||
require.True(validator.IsBonded())
|
||||
require.Equal(delTokens, issuedShares.RoundInt())
|
||||
|
||||
validator = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
delegation := stakingtypes.NewDelegation(addrDels[0], addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, delegation))
|
||||
|
||||
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
|
||||
@ -406,8 +436,8 @@ func (s *KeeperTestSuite) TestUndelegateSelfDelegationBelowMinSelfDelegation() {
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
|
||||
s.applyValidatorSetUpdates(ctx, keeper, 1)
|
||||
|
||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(found)
|
||||
validator, err = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(keeper.TokensFromConsensusPower(ctx, 14), validator.Tokens)
|
||||
require.Equal(stakingtypes.Unbonding, validator.Status)
|
||||
require.True(validator.Jailed)
|
||||
@ -422,7 +452,7 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondingValidator() {
|
||||
|
||||
// create a validator with a self-delegation
|
||||
validator := testutil.NewValidator(s.T(), addrVals[0], PKs[0])
|
||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
|
||||
|
||||
validator, issuedShares := validator.AddTokensFromDel(delTokens)
|
||||
require.Equal(delTokens, issuedShares.RoundInt())
|
||||
@ -432,17 +462,17 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondingValidator() {
|
||||
require.True(validator.IsBonded())
|
||||
|
||||
selfDelegation := stakingtypes.NewDelegation(addrVals[0].Bytes(), addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, selfDelegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, selfDelegation))
|
||||
|
||||
// create a second delegation to this validator
|
||||
keeper.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
require.NoError(keeper.DeleteValidatorByPowerIndex(ctx, validator))
|
||||
|
||||
validator, issuedShares = validator.AddTokensFromDel(delTokens)
|
||||
require.Equal(delTokens, issuedShares.RoundInt())
|
||||
|
||||
stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
delegation := stakingtypes.NewDelegation(addrDels[1], addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, delegation))
|
||||
|
||||
header := ctx.BlockHeader()
|
||||
blockHeight := int64(10)
|
||||
@ -462,10 +492,11 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondingValidator() {
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
|
||||
s.applyValidatorSetUpdates(ctx, keeper, 1)
|
||||
|
||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(found)
|
||||
validator, err = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(blockHeight, validator.UnbondingHeight)
|
||||
params := keeper.GetParams(ctx)
|
||||
params, err := keeper.GetParams(ctx)
|
||||
require.NoError(err)
|
||||
require.True(blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime))
|
||||
|
||||
blockHeight2 := int64(20)
|
||||
@ -480,8 +511,8 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondingValidator() {
|
||||
require.Equal(math.LegacyNewDecFromInt(undelegatedAmount), undelegateAmount)
|
||||
|
||||
// retrieve the unbonding delegation
|
||||
ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[1], addrVals[0])
|
||||
require.True(found)
|
||||
ubd, err := keeper.GetUnbondingDelegation(ctx, addrDels[1], addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Len(ubd.Entries, 1)
|
||||
require.True(ubd.Entries[0].Balance.Equal(math.NewInt(6)))
|
||||
require.Equal(blockHeight2, ubd.Entries[0].CreationHeight)
|
||||
@ -497,7 +528,7 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondedValidator() {
|
||||
|
||||
// create a validator with a self-delegation
|
||||
validator := testutil.NewValidator(s.T(), addrVals[0], PKs[0])
|
||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
|
||||
|
||||
valTokens := keeper.TokensFromConsensusPower(ctx, 10)
|
||||
validator, issuedShares := validator.AddTokensFromDel(valTokens)
|
||||
@ -508,16 +539,16 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondedValidator() {
|
||||
|
||||
val0AccAddr := sdk.AccAddress(addrVals[0])
|
||||
selfDelegation := stakingtypes.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, selfDelegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, selfDelegation))
|
||||
|
||||
// create a second delegation to this validator
|
||||
keeper.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
require.NoError(keeper.DeleteValidatorByPowerIndex(ctx, validator))
|
||||
validator, issuedShares = validator.AddTokensFromDel(delTokens)
|
||||
require.Equal(delTokens, issuedShares.RoundInt())
|
||||
validator = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
require.True(validator.IsBonded())
|
||||
delegation := stakingtypes.NewDelegation(addrDels[1], addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, delegation))
|
||||
|
||||
ctx = ctx.WithBlockHeight(10)
|
||||
ctx = ctx.WithBlockTime(time.Unix(333, 0))
|
||||
@ -532,19 +563,21 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondedValidator() {
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
|
||||
s.applyValidatorSetUpdates(ctx, keeper, 1)
|
||||
|
||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(found)
|
||||
validator, err = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(ctx.BlockHeight(), validator.UnbondingHeight)
|
||||
params := keeper.GetParams(ctx)
|
||||
params, err := keeper.GetParams(ctx)
|
||||
require.NoError(err)
|
||||
require.True(ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime))
|
||||
|
||||
// unbond the validator
|
||||
ctx = ctx.WithBlockTime(validator.UnbondingTime)
|
||||
keeper.UnbondAllMatureValidators(ctx)
|
||||
err = keeper.UnbondAllMatureValidators(ctx)
|
||||
require.NoError(err)
|
||||
|
||||
// Make sure validator is still in state because there is still an outstanding delegation
|
||||
validator, found = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(found)
|
||||
validator, err = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(validator.Status, stakingtypes.Unbonded)
|
||||
|
||||
// unbond some of the other delegation's shares
|
||||
@ -560,8 +593,8 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondedValidator() {
|
||||
require.Equal(amount3, remainingTokens)
|
||||
|
||||
// now validator should be deleted from state
|
||||
validator, found = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.False(found, "%v", validator)
|
||||
validator, err = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.ErrorIs(err, stakingtypes.ErrNoValidatorFound)
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestUnbondingAllDelegationFromValidator() {
|
||||
@ -573,7 +606,7 @@ func (s *KeeperTestSuite) TestUnbondingAllDelegationFromValidator() {
|
||||
|
||||
// create a validator with a self-delegation
|
||||
validator := testutil.NewValidator(s.T(), addrVals[0], PKs[0])
|
||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
|
||||
|
||||
valTokens := keeper.TokensFromConsensusPower(ctx, 10)
|
||||
validator, issuedShares := validator.AddTokensFromDel(valTokens)
|
||||
@ -585,10 +618,10 @@ func (s *KeeperTestSuite) TestUnbondingAllDelegationFromValidator() {
|
||||
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
||||
|
||||
selfDelegation := stakingtypes.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, selfDelegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, selfDelegation))
|
||||
|
||||
// create a second delegation to this validator
|
||||
keeper.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
require.NoError(keeper.DeleteValidatorByPowerIndex(ctx, validator))
|
||||
validator, issuedShares = validator.AddTokensFromDel(delTokens)
|
||||
require.Equal(delTokens, issuedShares.RoundInt())
|
||||
|
||||
@ -596,7 +629,7 @@ func (s *KeeperTestSuite) TestUnbondingAllDelegationFromValidator() {
|
||||
require.True(validator.IsBonded())
|
||||
|
||||
delegation := stakingtypes.NewDelegation(addrDels[1], addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, delegation))
|
||||
|
||||
ctx = ctx.WithBlockHeight(10)
|
||||
ctx = ctx.WithBlockTime(time.Unix(333, 0))
|
||||
@ -617,17 +650,18 @@ func (s *KeeperTestSuite) TestUnbondingAllDelegationFromValidator() {
|
||||
require.Equal(amount2, delTokens)
|
||||
|
||||
// validator should still be in state and still be in unbonding state
|
||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(found)
|
||||
validator, err = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(validator.Status, stakingtypes.Unbonding)
|
||||
|
||||
// unbond the validator
|
||||
ctx = ctx.WithBlockTime(validator.UnbondingTime)
|
||||
keeper.UnbondAllMatureValidators(ctx)
|
||||
err = keeper.UnbondAllMatureValidators(ctx)
|
||||
require.NoError(err)
|
||||
|
||||
// validator should now be deleted from state
|
||||
_, found = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.False(found)
|
||||
_, err = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.ErrorIs(err, stakingtypes.ErrNoValidatorFound)
|
||||
}
|
||||
|
||||
// Make sure that that the retrieving the delegations doesn't affect the state
|
||||
@ -642,17 +676,20 @@ func (s *KeeperTestSuite) TestGetRedelegationsFromSrcValidator() {
|
||||
math.LegacyNewDec(5), 0)
|
||||
|
||||
// set and retrieve a record
|
||||
keeper.SetRedelegation(ctx, rd)
|
||||
resBond, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.True(found)
|
||||
err := keeper.SetRedelegation(ctx, rd)
|
||||
require.NoError(err)
|
||||
resBond, err := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.NoError(err)
|
||||
|
||||
// get the redelegations one time
|
||||
redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
|
||||
redelegations, err := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(redelegations))
|
||||
require.Equal(redelegations[0], resBond)
|
||||
|
||||
// get the redelegations a second time, should be exactly the same
|
||||
redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
|
||||
redelegations, err = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(redelegations))
|
||||
require.Equal(redelegations[0], resBond)
|
||||
}
|
||||
@ -669,55 +706,67 @@ func (s *KeeperTestSuite) TestRedelegation() {
|
||||
math.LegacyNewDec(5), 0)
|
||||
|
||||
// test shouldn't have and redelegations
|
||||
has := keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1])
|
||||
has, err := keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1])
|
||||
require.NoError(err)
|
||||
require.False(has)
|
||||
|
||||
// set and retrieve a record
|
||||
keeper.SetRedelegation(ctx, rd)
|
||||
resRed, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.True(found)
|
||||
err = keeper.SetRedelegation(ctx, rd)
|
||||
require.NoError(err)
|
||||
resRed, err := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.NoError(err)
|
||||
|
||||
redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
|
||||
redelegations, err := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(redelegations))
|
||||
require.Equal(redelegations[0], resRed)
|
||||
|
||||
redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5)
|
||||
redelegations, err = keeper.GetRedelegations(ctx, addrDels[0], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(redelegations))
|
||||
require.Equal(redelegations[0], resRed)
|
||||
|
||||
redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil)
|
||||
redelegations, err = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(redelegations))
|
||||
require.Equal(redelegations[0], resRed)
|
||||
|
||||
// check if has the redelegation
|
||||
has = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1])
|
||||
has, err = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1])
|
||||
require.NoError(err)
|
||||
require.True(has)
|
||||
|
||||
// modify a records, save, and retrieve
|
||||
rd.Entries[0].SharesDst = math.LegacyNewDec(21)
|
||||
keeper.SetRedelegation(ctx, rd)
|
||||
err = keeper.SetRedelegation(ctx, rd)
|
||||
require.NoError(err)
|
||||
|
||||
resRed, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.True(found)
|
||||
resRed, err = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.NoError(err)
|
||||
require.Equal(rd, resRed)
|
||||
|
||||
redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
|
||||
redelegations, err = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(redelegations))
|
||||
require.Equal(redelegations[0], resRed)
|
||||
|
||||
redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5)
|
||||
redelegations, err = keeper.GetRedelegations(ctx, addrDels[0], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(redelegations))
|
||||
require.Equal(redelegations[0], resRed)
|
||||
|
||||
// delete a record
|
||||
keeper.RemoveRedelegation(ctx, rd)
|
||||
_, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.False(found)
|
||||
err = keeper.RemoveRedelegation(ctx, rd)
|
||||
require.NoError(err)
|
||||
_, err = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.ErrorIs(err, stakingtypes.ErrNoRedelegation)
|
||||
|
||||
redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5)
|
||||
redelegations, err = keeper.GetRedelegations(ctx, addrDels[0], 5)
|
||||
require.NoError(err)
|
||||
require.Equal(0, len(redelegations))
|
||||
|
||||
redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil)
|
||||
redelegations, err = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil)
|
||||
require.NoError(err)
|
||||
require.Equal(0, len(redelegations))
|
||||
}
|
||||
|
||||
@ -740,7 +789,7 @@ func (s *KeeperTestSuite) TestRedelegateToSameValidator() {
|
||||
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
||||
|
||||
selfDelegation := stakingtypes.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, selfDelegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, selfDelegation))
|
||||
|
||||
_, err := keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[0], math.LegacyNewDec(5))
|
||||
require.Error(err)
|
||||
@ -762,7 +811,7 @@ func (s *KeeperTestSuite) TestRedelegationMaxEntries() {
|
||||
_ = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
||||
selfDelegation := stakingtypes.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, selfDelegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, selfDelegation))
|
||||
|
||||
// create a second validator
|
||||
validator2 := testutil.NewValidator(s.T(), addrVals[1], PKs[1])
|
||||
@ -773,7 +822,8 @@ func (s *KeeperTestSuite) TestRedelegationMaxEntries() {
|
||||
validator2 = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator2, true)
|
||||
require.Equal(stakingtypes.Bonded, validator2.Status)
|
||||
|
||||
maxEntries := keeper.MaxEntries(ctx)
|
||||
maxEntries, err := keeper.MaxEntries(ctx)
|
||||
require.NoError(err)
|
||||
|
||||
// redelegations should pass
|
||||
var completionTime time.Time
|
||||
@ -784,7 +834,7 @@ func (s *KeeperTestSuite) TestRedelegationMaxEntries() {
|
||||
}
|
||||
|
||||
// an additional redelegation should fail due to max entries
|
||||
_, err := keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], math.LegacyNewDec(1))
|
||||
_, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], math.LegacyNewDec(1))
|
||||
require.Error(err)
|
||||
|
||||
// mature redelegations
|
||||
@ -805,7 +855,7 @@ func (s *KeeperTestSuite) TestRedelegateSelfDelegation() {
|
||||
|
||||
// create a validator with a self-delegation
|
||||
validator := testutil.NewValidator(s.T(), addrVals[0], PKs[0])
|
||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
|
||||
|
||||
valTokens := keeper.TokensFromConsensusPower(ctx, 10)
|
||||
validator, issuedShares := validator.AddTokensFromDel(valTokens)
|
||||
@ -816,7 +866,7 @@ func (s *KeeperTestSuite) TestRedelegateSelfDelegation() {
|
||||
|
||||
val0AccAddr := sdk.AccAddress(addrVals[0])
|
||||
selfDelegation := stakingtypes.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, selfDelegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, selfDelegation))
|
||||
|
||||
// create a second validator
|
||||
validator2 := testutil.NewValidator(s.T(), addrVals[1], PKs[1])
|
||||
@ -833,7 +883,7 @@ func (s *KeeperTestSuite) TestRedelegateSelfDelegation() {
|
||||
stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
|
||||
delegation := stakingtypes.NewDelegation(addrDels[0], addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, delegation))
|
||||
|
||||
_, err := keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], math.LegacyNewDecFromInt(delTokens))
|
||||
require.NoError(err)
|
||||
@ -842,8 +892,8 @@ func (s *KeeperTestSuite) TestRedelegateSelfDelegation() {
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
|
||||
s.applyValidatorSetUpdates(ctx, keeper, 2)
|
||||
|
||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(found)
|
||||
validator, err = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(valTokens, validator.Tokens)
|
||||
require.Equal(stakingtypes.Unbonding, validator.Status)
|
||||
}
|
||||
@ -856,7 +906,7 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondingValidator() {
|
||||
|
||||
// create a validator with a self-delegation
|
||||
validator := testutil.NewValidator(s.T(), addrVals[0], PKs[0])
|
||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
|
||||
|
||||
valTokens := keeper.TokensFromConsensusPower(ctx, 10)
|
||||
validator, issuedShares := validator.AddTokensFromDel(valTokens)
|
||||
@ -865,16 +915,16 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondingValidator() {
|
||||
validator = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
||||
selfDelegation := stakingtypes.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, selfDelegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, selfDelegation))
|
||||
|
||||
// create a second delegation to this validator
|
||||
keeper.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
require.NoError(keeper.DeleteValidatorByPowerIndex(ctx, validator))
|
||||
delTokens := keeper.TokensFromConsensusPower(ctx, 10)
|
||||
validator, issuedShares = validator.AddTokensFromDel(delTokens)
|
||||
require.Equal(delTokens, issuedShares.RoundInt())
|
||||
stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
delegation := stakingtypes.NewDelegation(addrDels[1], addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, delegation))
|
||||
|
||||
// create a second validator
|
||||
validator2 := testutil.NewValidator(s.T(), addrVals[1], PKs[1])
|
||||
@ -900,10 +950,11 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondingValidator() {
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
|
||||
s.applyValidatorSetUpdates(ctx, keeper, 1)
|
||||
|
||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(found)
|
||||
validator, err = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(blockHeight, validator.UnbondingHeight)
|
||||
params := keeper.GetParams(ctx)
|
||||
params, err := keeper.GetParams(ctx)
|
||||
require.NoError(err)
|
||||
require.True(blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime))
|
||||
|
||||
// change the context
|
||||
@ -921,8 +972,8 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondingValidator() {
|
||||
require.NoError(err)
|
||||
|
||||
// retrieve the unbonding delegation
|
||||
ubd, found := keeper.GetRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1])
|
||||
require.True(found)
|
||||
ubd, err := keeper.GetRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1])
|
||||
require.NoError(err)
|
||||
require.Len(ubd.Entries, 1)
|
||||
require.Equal(blockHeight, ubd.Entries[0].CreationHeight)
|
||||
require.True(blockTime.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime))
|
||||
@ -936,7 +987,7 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondedValidator() {
|
||||
|
||||
// create a validator with a self-delegation
|
||||
validator := testutil.NewValidator(s.T(), addrVals[0], PKs[0])
|
||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
|
||||
|
||||
valTokens := keeper.TokensFromConsensusPower(ctx, 10)
|
||||
validator, issuedShares := validator.AddTokensFromDel(valTokens)
|
||||
@ -945,16 +996,16 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondedValidator() {
|
||||
validator = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
||||
selfDelegation := stakingtypes.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, selfDelegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, selfDelegation))
|
||||
|
||||
// create a second delegation to this validator
|
||||
keeper.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
require.NoError(keeper.DeleteValidatorByPowerIndex(ctx, validator))
|
||||
delTokens := keeper.TokensFromConsensusPower(ctx, 10)
|
||||
validator, issuedShares = validator.AddTokensFromDel(delTokens)
|
||||
require.Equal(delTokens, issuedShares.RoundInt())
|
||||
stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
delegation := stakingtypes.NewDelegation(addrDels[1], addrVals[0], issuedShares)
|
||||
keeper.SetDelegation(ctx, delegation)
|
||||
require.NoError(keeper.SetDelegation(ctx, delegation))
|
||||
|
||||
// create a second validator
|
||||
validator2 := testutil.NewValidator(s.T(), addrVals[1], PKs[1])
|
||||
@ -977,14 +1028,16 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondedValidator() {
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
|
||||
s.applyValidatorSetUpdates(ctx, keeper, 1)
|
||||
|
||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(found)
|
||||
validator, err = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.NoError(err)
|
||||
require.Equal(ctx.BlockHeight(), validator.UnbondingHeight)
|
||||
params := keeper.GetParams(ctx)
|
||||
params, err := keeper.GetParams(ctx)
|
||||
require.NoError(err)
|
||||
require.True(ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime))
|
||||
|
||||
// unbond the validator
|
||||
keeper.UnbondingToUnbonded(ctx, validator)
|
||||
_, err = keeper.UnbondingToUnbonded(ctx, validator)
|
||||
require.NoError(err)
|
||||
|
||||
// redelegate some of the delegation's shares
|
||||
redelegationTokens := keeper.TokensFromConsensusPower(ctx, 6)
|
||||
@ -993,8 +1046,8 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondedValidator() {
|
||||
require.NoError(err)
|
||||
|
||||
// no red should have been found
|
||||
red, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.False(found, "%v", red)
|
||||
red, err := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.ErrorIs(err, stakingtypes.ErrNoRedelegation, "%v", red)
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestUnbondingDelegationAddEntry() {
|
||||
@ -1056,9 +1109,9 @@ func (s *KeeperTestSuite) TestSetUnbondingDelegationEntry() {
|
||||
)
|
||||
|
||||
// set and retrieve a record
|
||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||
resUnbond, found := keeper.GetUnbondingDelegation(ctx, delAddr, valAddr)
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetUnbondingDelegation(ctx, ubd))
|
||||
resUnbond, err := keeper.GetUnbondingDelegation(ctx, delAddr, valAddr)
|
||||
require.NoError(err)
|
||||
require.Equal(ubd, resUnbond)
|
||||
|
||||
initialEntries := ubd.Entries
|
||||
@ -1068,7 +1121,7 @@ func (s *KeeperTestSuite) TestSetUnbondingDelegationEntry() {
|
||||
|
||||
// set unbonding delegation entry for existing creationHeight
|
||||
// entries are expected to be merged
|
||||
keeper.SetUnbondingDelegationEntry(
|
||||
_, err = keeper.SetUnbondingDelegationEntry(
|
||||
ctx,
|
||||
delAddr,
|
||||
valAddr,
|
||||
@ -1076,8 +1129,9 @@ func (s *KeeperTestSuite) TestSetUnbondingDelegationEntry() {
|
||||
time.Unix(0, 0).UTC(),
|
||||
math.NewInt(5),
|
||||
)
|
||||
resUnbonding, found := keeper.GetUnbondingDelegation(ctx, delAddr, valAddr)
|
||||
require.True(found)
|
||||
require.NoError(err)
|
||||
resUnbonding, err := keeper.GetUnbondingDelegation(ctx, delAddr, valAddr)
|
||||
require.NoError(err)
|
||||
require.Len(resUnbonding.Entries, 1)
|
||||
require.NotEqual(initialEntries, resUnbonding.Entries)
|
||||
require.Equal(creationHeight, resUnbonding.Entries[0].CreationHeight)
|
||||
@ -1087,7 +1141,7 @@ func (s *KeeperTestSuite) TestSetUnbondingDelegationEntry() {
|
||||
// set unbonding delegation entry for newCreationHeight
|
||||
// new entry is expected to be appended to the existing entries
|
||||
newCreationHeight := int64(1)
|
||||
keeper.SetUnbondingDelegationEntry(
|
||||
_, err = keeper.SetUnbondingDelegationEntry(
|
||||
ctx,
|
||||
delAddr,
|
||||
valAddr,
|
||||
@ -1095,8 +1149,9 @@ func (s *KeeperTestSuite) TestSetUnbondingDelegationEntry() {
|
||||
time.Unix(1, 0).UTC(),
|
||||
math.NewInt(10),
|
||||
)
|
||||
resUnbonding, found = keeper.GetUnbondingDelegation(ctx, delAddr, valAddr)
|
||||
require.True(found)
|
||||
require.NoError(err)
|
||||
resUnbonding, err = keeper.GetUnbondingDelegation(ctx, delAddr, valAddr)
|
||||
require.NoError(err)
|
||||
require.Len(resUnbonding.Entries, 2)
|
||||
require.NotEqual(initialEntries, resUnbonding.Entries)
|
||||
require.NotEqual(resUnbonding.Entries[0], resUnbonding.Entries[1])
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
@ -16,7 +17,7 @@ import (
|
||||
// setting the indexes. In addition, it also sets any delegations found in
|
||||
// data. Finally, it updates the bonded validators.
|
||||
// Returns final validator set after applying all declaration and delegations
|
||||
func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []abci.ValidatorUpdate) {
|
||||
func (k Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) (res []abci.ValidatorUpdate) {
|
||||
bondedTokens := math.ZeroInt()
|
||||
notBondedTokens := math.ZeroInt()
|
||||
|
||||
@ -25,19 +26,31 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []ab
|
||||
// initialized for the validator set e.g. with a one-block offset - the
|
||||
// first TM block is at height 1, so state updates applied from
|
||||
// genesis.json are in block 0.
|
||||
ctx = ctx.WithBlockHeight(1 - sdk.ValidatorUpdateDelay)
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
sdkCtx = sdkCtx.WithBlockHeight(1 - sdk.ValidatorUpdateDelay)
|
||||
ctx = sdkCtx
|
||||
|
||||
if err := k.SetParams(ctx, data.Params); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.SetLastTotalPower(ctx, data.LastTotalPower)
|
||||
|
||||
if err := k.SetLastTotalPower(ctx, data.LastTotalPower); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, validator := range data.Validators {
|
||||
k.SetValidator(ctx, validator)
|
||||
if err := k.SetValidator(ctx, validator); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Manually set indices for the first time
|
||||
k.SetValidatorByConsAddr(ctx, validator)
|
||||
k.SetValidatorByPowerIndex(ctx, validator)
|
||||
if err := k.SetValidatorByConsAddr(ctx, validator); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := k.SetValidatorByPowerIndex(ctx, validator); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Call the creation hook if not exported
|
||||
if !data.Exported {
|
||||
@ -48,7 +61,9 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []ab
|
||||
|
||||
// update timeslice if necessary
|
||||
if validator.IsUnbonding() {
|
||||
k.InsertUnbondingValidatorQueue(ctx, validator)
|
||||
if err := k.InsertUnbondingValidatorQueue(ctx, validator); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
switch validator.GetStatus() {
|
||||
@ -76,7 +91,9 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []ab
|
||||
}
|
||||
}
|
||||
|
||||
k.SetDelegation(ctx, delegation)
|
||||
if err := k.SetDelegation(ctx, delegation); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Call the after-modification hook if not exported
|
||||
if !data.Exported {
|
||||
@ -87,19 +104,27 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []ab
|
||||
}
|
||||
|
||||
for _, ubd := range data.UnbondingDelegations {
|
||||
k.SetUnbondingDelegation(ctx, ubd)
|
||||
if err := k.SetUnbondingDelegation(ctx, ubd); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, entry := range ubd.Entries {
|
||||
k.InsertUBDQueue(ctx, ubd, entry.CompletionTime)
|
||||
if err := k.InsertUBDQueue(ctx, ubd, entry.CompletionTime); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
notBondedTokens = notBondedTokens.Add(entry.Balance)
|
||||
}
|
||||
}
|
||||
|
||||
for _, red := range data.Redelegations {
|
||||
k.SetRedelegation(ctx, red)
|
||||
if err := k.SetRedelegation(ctx, red); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, entry := range red.Entries {
|
||||
k.InsertRedelegationQueue(ctx, red, entry.CompletionTime)
|
||||
if err := k.InsertRedelegationQueue(ctx, red, entry.CompletionTime); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,10 +173,13 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []ab
|
||||
panic(err)
|
||||
}
|
||||
|
||||
k.SetLastValidatorPower(ctx, valAddr, lv.Power)
|
||||
validator, found := k.GetValidator(ctx, valAddr)
|
||||
err = k.SetLastValidatorPower(ctx, valAddr, lv.Power)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if !found {
|
||||
validator, err := k.GetValidator(ctx, valAddr)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("validator %s not found", lv.Address))
|
||||
}
|
||||
|
||||
@ -177,31 +205,60 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []ab
|
||||
func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
|
||||
var unbondingDelegations []types.UnbondingDelegation
|
||||
|
||||
k.IterateUnbondingDelegations(ctx, func(_ int64, ubd types.UnbondingDelegation) (stop bool) {
|
||||
err := k.IterateUnbondingDelegations(ctx, func(_ int64, ubd types.UnbondingDelegation) (stop bool) {
|
||||
unbondingDelegations = append(unbondingDelegations, ubd)
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var redelegations []types.Redelegation
|
||||
|
||||
k.IterateRedelegations(ctx, func(_ int64, red types.Redelegation) (stop bool) {
|
||||
err = k.IterateRedelegations(ctx, func(_ int64, red types.Redelegation) (stop bool) {
|
||||
redelegations = append(redelegations, red)
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var lastValidatorPowers []types.LastValidatorPower
|
||||
|
||||
k.IterateLastValidatorPowers(ctx, func(addr sdk.ValAddress, power int64) (stop bool) {
|
||||
err = k.IterateLastValidatorPowers(ctx, func(addr sdk.ValAddress, power int64) (stop bool) {
|
||||
lastValidatorPowers = append(lastValidatorPowers, types.LastValidatorPower{Address: addr.String(), Power: power})
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
params, err := k.GetParams(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
totalPower, err := k.GetLastTotalPower(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allDelegations, err := k.GetAllDelegations(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allValidators, err := k.GetAllValidators(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &types.GenesisState{
|
||||
Params: k.GetParams(ctx),
|
||||
LastTotalPower: k.GetLastTotalPower(ctx),
|
||||
Params: params,
|
||||
LastTotalPower: totalPower,
|
||||
LastValidatorPowers: lastValidatorPowers,
|
||||
Validators: k.GetAllValidators(ctx),
|
||||
Delegations: k.GetAllDelegations(ctx),
|
||||
Validators: allValidators,
|
||||
Delegations: allDelegations,
|
||||
UnbondingDelegations: unbondingDelegations,
|
||||
Redelegations: redelegations,
|
||||
Exported: true,
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"cosmossdk.io/store/prefix"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
@ -27,7 +28,7 @@ func NewQuerier(keeper *Keeper) Querier {
|
||||
}
|
||||
|
||||
// Validators queries all validators that match the given status
|
||||
func (k Querier) Validators(c context.Context, req *types.QueryValidatorsRequest) (*types.QueryValidatorsResponse, error) {
|
||||
func (k Querier) Validators(ctx context.Context, req *types.QueryValidatorsRequest) (*types.QueryValidatorsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -37,9 +38,7 @@ func (k Querier) Validators(c context.Context, req *types.QueryValidatorsRequest
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid validator status %s", req.Status)
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
||||
valStore := prefix.NewStore(store, types.ValidatorsKey)
|
||||
|
||||
validators, pageRes, err := query.GenericFilteredPaginate(k.cdc, valStore, req.Pagination, func(key []byte, val *types.Validator) (*types.Validator, error) {
|
||||
@ -64,7 +63,7 @@ func (k Querier) Validators(c context.Context, req *types.QueryValidatorsRequest
|
||||
}
|
||||
|
||||
// Validator queries validator info for given validator address
|
||||
func (k Querier) Validator(c context.Context, req *types.QueryValidatorRequest) (*types.QueryValidatorResponse, error) {
|
||||
func (k Querier) Validator(ctx context.Context, req *types.QueryValidatorRequest) (*types.QueryValidatorResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -78,9 +77,8 @@ func (k Querier) Validator(c context.Context, req *types.QueryValidatorRequest)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
validator, found := k.GetValidator(ctx, valAddr)
|
||||
if !found {
|
||||
validator, err := k.GetValidator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.NotFound, "validator %s not found", req.ValidatorAddr)
|
||||
}
|
||||
|
||||
@ -88,7 +86,7 @@ func (k Querier) Validator(c context.Context, req *types.QueryValidatorRequest)
|
||||
}
|
||||
|
||||
// ValidatorDelegations queries delegate info for given validator
|
||||
func (k Querier) ValidatorDelegations(c context.Context, req *types.QueryValidatorDelegationsRequest) (*types.QueryValidatorDelegationsResponse, error) {
|
||||
func (k Querier) ValidatorDelegations(ctx context.Context, req *types.QueryValidatorDelegationsRequest) (*types.QueryValidatorDelegationsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -101,9 +99,8 @@ func (k Querier) ValidatorDelegations(c context.Context, req *types.QueryValidat
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
||||
delStore := prefix.NewStore(store, types.GetDelegationsByValPrefixKey(valAddr))
|
||||
|
||||
var (
|
||||
@ -146,8 +143,8 @@ func (k Querier) ValidatorDelegations(c context.Context, req *types.QueryValidat
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (k Querier) getValidatorDelegationsLegacy(ctx sdk.Context, req *types.QueryValidatorDelegationsRequest) ([]*types.Delegation, *query.PageResponse, error) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Querier) getValidatorDelegationsLegacy(ctx context.Context, req *types.QueryValidatorDelegationsRequest) ([]*types.Delegation, *query.PageResponse, error) {
|
||||
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
||||
|
||||
valStore := prefix.NewStore(store, types.DelegationKey)
|
||||
return query.GenericFilteredPaginate(k.cdc, valStore, req.Pagination, func(key []byte, delegation *types.Delegation) (*types.Delegation, error) {
|
||||
@ -167,7 +164,7 @@ func (k Querier) getValidatorDelegationsLegacy(ctx sdk.Context, req *types.Query
|
||||
}
|
||||
|
||||
// ValidatorUnbondingDelegations queries unbonding delegations of a validator
|
||||
func (k Querier) ValidatorUnbondingDelegations(c context.Context, req *types.QueryValidatorUnbondingDelegationsRequest) (*types.QueryValidatorUnbondingDelegationsResponse, error) {
|
||||
func (k Querier) ValidatorUnbondingDelegations(ctx context.Context, req *types.QueryValidatorUnbondingDelegationsRequest) (*types.QueryValidatorUnbondingDelegationsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -176,15 +173,13 @@ func (k Querier) ValidatorUnbondingDelegations(c context.Context, req *types.Que
|
||||
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
|
||||
}
|
||||
var ubds types.UnbondingDelegations
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
||||
srcValPrefix := types.GetUBDsByValIndexKey(valAddr)
|
||||
ubdStore := prefix.NewStore(store, srcValPrefix)
|
||||
pageRes, err := query.Paginate(ubdStore, req.Pagination, func(key, value []byte) error {
|
||||
@ -209,7 +204,7 @@ func (k Querier) ValidatorUnbondingDelegations(c context.Context, req *types.Que
|
||||
}
|
||||
|
||||
// Delegation queries delegate info for given validator delegator pair
|
||||
func (k Querier) Delegation(c context.Context, req *types.QueryDelegationRequest) (*types.QueryDelegationResponse, error) {
|
||||
func (k Querier) Delegation(ctx context.Context, req *types.QueryDelegationRequest) (*types.QueryDelegationResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -221,7 +216,6 @@ func (k Querier) Delegation(c context.Context, req *types.QueryDelegationRequest
|
||||
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -232,8 +226,8 @@ func (k Querier) Delegation(c context.Context, req *types.QueryDelegationRequest
|
||||
return nil, err
|
||||
}
|
||||
|
||||
delegation, found := k.GetDelegation(ctx, delAddr, valAddr)
|
||||
if !found {
|
||||
delegation, err := k.GetDelegation(ctx, delAddr, valAddr)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(
|
||||
codes.NotFound,
|
||||
"delegation with delegator %s not found for validator %s",
|
||||
@ -249,7 +243,7 @@ func (k Querier) Delegation(c context.Context, req *types.QueryDelegationRequest
|
||||
}
|
||||
|
||||
// UnbondingDelegation queries unbonding info for give validator delegator pair
|
||||
func (k Querier) UnbondingDelegation(c context.Context, req *types.QueryUnbondingDelegationRequest) (*types.QueryUnbondingDelegationResponse, error) {
|
||||
func (k Querier) UnbondingDelegation(ctx context.Context, req *types.QueryUnbondingDelegationRequest) (*types.QueryUnbondingDelegationResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -261,8 +255,6 @@ func (k Querier) UnbondingDelegation(c context.Context, req *types.QueryUnbondin
|
||||
return nil, status.Errorf(codes.InvalidArgument, "validator address cannot be empty")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -273,8 +265,8 @@ func (k Querier) UnbondingDelegation(c context.Context, req *types.QueryUnbondin
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unbond, found := k.GetUnbondingDelegation(ctx, delAddr, valAddr)
|
||||
if !found {
|
||||
unbond, err := k.GetUnbondingDelegation(ctx, delAddr, valAddr)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(
|
||||
codes.NotFound,
|
||||
"unbonding delegation with delegator %s not found for validator %s",
|
||||
@ -285,7 +277,7 @@ func (k Querier) UnbondingDelegation(c context.Context, req *types.QueryUnbondin
|
||||
}
|
||||
|
||||
// DelegatorDelegations queries all delegations of a give delegator address
|
||||
func (k Querier) DelegatorDelegations(c context.Context, req *types.QueryDelegatorDelegationsRequest) (*types.QueryDelegatorDelegationsResponse, error) {
|
||||
func (k Querier) DelegatorDelegations(ctx context.Context, req *types.QueryDelegatorDelegationsRequest) (*types.QueryDelegatorDelegationsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -294,14 +286,13 @@ func (k Querier) DelegatorDelegations(c context.Context, req *types.QueryDelegat
|
||||
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
|
||||
}
|
||||
var delegations types.Delegations
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
||||
delStore := prefix.NewStore(store, types.GetDelegationsKey(delAddr))
|
||||
pageRes, err := query.Paginate(delStore, req.Pagination, func(key, value []byte) error {
|
||||
delegation, err := types.UnmarshalDelegation(k.cdc, value)
|
||||
@ -324,7 +315,7 @@ func (k Querier) DelegatorDelegations(c context.Context, req *types.QueryDelegat
|
||||
}
|
||||
|
||||
// DelegatorValidator queries validator info for given delegator validator pair
|
||||
func (k Querier) DelegatorValidator(c context.Context, req *types.QueryDelegatorValidatorRequest) (*types.QueryDelegatorValidatorResponse, error) {
|
||||
func (k Querier) DelegatorValidator(ctx context.Context, req *types.QueryDelegatorValidatorRequest) (*types.QueryDelegatorValidatorResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -336,7 +327,6 @@ func (k Querier) DelegatorValidator(c context.Context, req *types.QueryDelegator
|
||||
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -356,7 +346,7 @@ func (k Querier) DelegatorValidator(c context.Context, req *types.QueryDelegator
|
||||
}
|
||||
|
||||
// DelegatorUnbondingDelegations queries all unbonding delegations of a given delegator address
|
||||
func (k Querier) DelegatorUnbondingDelegations(c context.Context, req *types.QueryDelegatorUnbondingDelegationsRequest) (*types.QueryDelegatorUnbondingDelegationsResponse, error) {
|
||||
func (k Querier) DelegatorUnbondingDelegations(ctx context.Context, req *types.QueryDelegatorUnbondingDelegationsRequest) (*types.QueryDelegatorUnbondingDelegationsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -365,14 +355,13 @@ func (k Querier) DelegatorUnbondingDelegations(c context.Context, req *types.Que
|
||||
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
|
||||
}
|
||||
var unbondingDelegations types.UnbondingDelegations
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
||||
unbStore := prefix.NewStore(store, types.GetUBDsKey(delAddr))
|
||||
pageRes, err := query.Paginate(unbStore, req.Pagination, func(key, value []byte) error {
|
||||
unbond, err := types.UnmarshalUBD(k.cdc, value)
|
||||
@ -392,7 +381,7 @@ func (k Querier) DelegatorUnbondingDelegations(c context.Context, req *types.Que
|
||||
}
|
||||
|
||||
// HistoricalInfo queries the historical info for given height
|
||||
func (k Querier) HistoricalInfo(c context.Context, req *types.QueryHistoricalInfoRequest) (*types.QueryHistoricalInfoResponse, error) {
|
||||
func (k Querier) HistoricalInfo(ctx context.Context, req *types.QueryHistoricalInfoRequest) (*types.QueryHistoricalInfoResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -400,9 +389,9 @@ func (k Querier) HistoricalInfo(c context.Context, req *types.QueryHistoricalInf
|
||||
if req.Height < 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "height cannot be negative")
|
||||
}
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
hi, found := k.GetHistoricalInfo(ctx, req.Height)
|
||||
if !found {
|
||||
|
||||
hi, err := k.GetHistoricalInfo(ctx, req.Height)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.NotFound, "historical info for height %d not found", req.Height)
|
||||
}
|
||||
|
||||
@ -410,7 +399,7 @@ func (k Querier) HistoricalInfo(c context.Context, req *types.QueryHistoricalInf
|
||||
}
|
||||
|
||||
// Redelegations queries redelegations of given address
|
||||
func (k Querier) Redelegations(c context.Context, req *types.QueryRedelegationsRequest) (*types.QueryRedelegationsResponse, error) {
|
||||
func (k Querier) Redelegations(ctx context.Context, req *types.QueryRedelegationsRequest) (*types.QueryRedelegationsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -419,8 +408,7 @@ func (k Querier) Redelegations(c context.Context, req *types.QueryRedelegationsR
|
||||
var pageRes *query.PageResponse
|
||||
var err error
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
||||
switch {
|
||||
case req.DelegatorAddr != "" && req.SrcValidatorAddr != "" && req.DstValidatorAddr != "":
|
||||
redels, err = queryRedelegation(ctx, k, req)
|
||||
@ -441,7 +429,7 @@ func (k Querier) Redelegations(c context.Context, req *types.QueryRedelegationsR
|
||||
}
|
||||
|
||||
// DelegatorValidators queries all validators info for given delegator address
|
||||
func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) {
|
||||
func (k Querier) DelegatorValidators(ctx context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
@ -450,9 +438,8 @@ func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegato
|
||||
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
|
||||
}
|
||||
var validators types.Validators
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -465,9 +452,9 @@ func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegato
|
||||
return err
|
||||
}
|
||||
|
||||
validator, found := k.GetValidator(ctx, delegation.GetValidatorAddr())
|
||||
if !found {
|
||||
return types.ErrNoValidatorFound
|
||||
validator, err := k.GetValidator(ctx, delegation.GetValidatorAddr())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
validators = append(validators, validator)
|
||||
@ -481,9 +468,11 @@ func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegato
|
||||
}
|
||||
|
||||
// Pool queries the pool info
|
||||
func (k Querier) Pool(c context.Context, _ *types.QueryPoolRequest) (*types.QueryPoolResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
bondDenom := k.BondDenom(ctx)
|
||||
func (k Querier) Pool(ctx context.Context, _ *types.QueryPoolRequest) (*types.QueryPoolResponse, error) {
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bondedPool := k.GetBondedPool(ctx)
|
||||
notBondedPool := k.GetNotBondedPool(ctx)
|
||||
|
||||
@ -496,14 +485,15 @@ func (k Querier) Pool(c context.Context, _ *types.QueryPoolRequest) (*types.Quer
|
||||
}
|
||||
|
||||
// Params queries the staking parameters
|
||||
func (k Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
params := k.GetParams(ctx)
|
||||
|
||||
func (k Querier) Params(ctx context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
|
||||
params, err := k.GetParams(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &types.QueryParamsResponse{Params: params}, nil
|
||||
}
|
||||
|
||||
func queryRedelegation(ctx sdk.Context, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, err error) {
|
||||
func queryRedelegation(ctx context.Context, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, err error) {
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -519,8 +509,8 @@ func queryRedelegation(ctx sdk.Context, k Querier, req *types.QueryRedelegations
|
||||
return nil, err
|
||||
}
|
||||
|
||||
redel, found := k.GetRedelegation(ctx, delAddr, srcValAddr, dstValAddr)
|
||||
if !found {
|
||||
redel, err := k.GetRedelegation(ctx, delAddr, srcValAddr, dstValAddr)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(
|
||||
codes.NotFound,
|
||||
"redelegation not found for delegator address %s from validator address %s",
|
||||
@ -528,7 +518,7 @@ func queryRedelegation(ctx sdk.Context, k Querier, req *types.QueryRedelegations
|
||||
}
|
||||
redels = []types.Redelegation{redel}
|
||||
|
||||
return redels, err
|
||||
return redels, nil
|
||||
}
|
||||
|
||||
func queryRedelegationsFromSrcValidator(store storetypes.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) {
|
||||
@ -574,10 +564,10 @@ func queryAllRedelegations(store storetypes.KVStore, k Querier, req *types.Query
|
||||
|
||||
// util
|
||||
|
||||
func DelegationToDelegationResponse(ctx sdk.Context, k *Keeper, del types.Delegation) (types.DelegationResponse, error) {
|
||||
val, found := k.GetValidator(ctx, del.GetValidatorAddr())
|
||||
if !found {
|
||||
return types.DelegationResponse{}, types.ErrNoValidatorFound
|
||||
func DelegationToDelegationResponse(ctx context.Context, k *Keeper, del types.Delegation) (types.DelegationResponse, error) {
|
||||
val, err := k.GetValidator(ctx, del.GetValidatorAddr())
|
||||
if err != nil {
|
||||
return types.DelegationResponse{}, err
|
||||
}
|
||||
|
||||
delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(del.DelegatorAddress)
|
||||
@ -585,15 +575,20 @@ func DelegationToDelegationResponse(ctx sdk.Context, k *Keeper, del types.Delega
|
||||
return types.DelegationResponse{}, err
|
||||
}
|
||||
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return types.DelegationResponse{}, err
|
||||
}
|
||||
|
||||
return types.NewDelegationResp(
|
||||
delegatorAddress,
|
||||
del.GetValidatorAddr(),
|
||||
del.Shares,
|
||||
sdk.NewCoin(k.BondDenom(ctx), val.TokensFromShares(del.Shares).TruncateInt()),
|
||||
sdk.NewCoin(bondDenom, val.TokensFromShares(del.Shares).TruncateInt()),
|
||||
), nil
|
||||
}
|
||||
|
||||
func DelegationsToDelegationResponses(ctx sdk.Context, k *Keeper, delegations types.Delegations) (types.DelegationResponses, error) {
|
||||
func DelegationsToDelegationResponses(ctx context.Context, k *Keeper, delegations types.Delegations) (types.DelegationResponses, error) {
|
||||
resp := make(types.DelegationResponses, len(delegations))
|
||||
|
||||
for i, del := range delegations {
|
||||
@ -608,7 +603,7 @@ func DelegationsToDelegationResponses(ctx sdk.Context, k *Keeper, delegations ty
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func RedelegationsToRedelegationResponses(ctx sdk.Context, k *Keeper, redels types.Redelegations) (types.RedelegationResponses, error) {
|
||||
func RedelegationsToRedelegationResponses(ctx context.Context, k *Keeper, redels types.Redelegations) (types.RedelegationResponses, error) {
|
||||
resp := make(types.RedelegationResponses, len(redels))
|
||||
|
||||
for i, redel := range redels {
|
||||
@ -626,9 +621,9 @@ func RedelegationsToRedelegationResponses(ctx sdk.Context, k *Keeper, redels typ
|
||||
return nil, err
|
||||
}
|
||||
|
||||
val, found := k.GetValidator(ctx, valDstAddr)
|
||||
if !found {
|
||||
return nil, types.ErrNoValidatorFound
|
||||
val, err := k.GetValidator(ctx, valDstAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entryResponses := make([]types.RedelegationEntryResponse, len(redel.Entries))
|
||||
|
||||
@ -14,7 +14,7 @@ func (s *KeeperTestSuite) TestGRPCQueryValidator() {
|
||||
require := s.Require()
|
||||
|
||||
validator := testutil.NewValidator(s.T(), sdk.ValAddress(PKs[0].Address().Bytes()), PKs[0])
|
||||
keeper.SetValidator(ctx, validator)
|
||||
require.NoError(keeper.SetValidator(ctx, validator))
|
||||
var req *types.QueryValidatorRequest
|
||||
testCases := []struct {
|
||||
msg string
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -8,32 +11,39 @@ import (
|
||||
)
|
||||
|
||||
// GetHistoricalInfo gets the historical info at a given height
|
||||
func (k Keeper) GetHistoricalInfo(ctx sdk.Context, height int64) (types.HistoricalInfo, bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetHistoricalInfo(ctx context.Context, height int64) (types.HistoricalInfo, error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
key := types.GetHistoricalInfoKey(height)
|
||||
|
||||
value := store.Get(key)
|
||||
if value == nil {
|
||||
return types.HistoricalInfo{}, false
|
||||
value, err := store.Get(key)
|
||||
if err != nil {
|
||||
return types.HistoricalInfo{}, err
|
||||
}
|
||||
|
||||
return types.MustUnmarshalHistoricalInfo(k.cdc, value), true
|
||||
if value == nil {
|
||||
return types.HistoricalInfo{}, types.ErrNoHistoricalInfo
|
||||
}
|
||||
|
||||
return types.UnmarshalHistoricalInfo(k.cdc, value)
|
||||
}
|
||||
|
||||
// SetHistoricalInfo sets the historical info at a given height
|
||||
func (k Keeper) SetHistoricalInfo(ctx sdk.Context, height int64, hi *types.HistoricalInfo) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) SetHistoricalInfo(ctx context.Context, height int64, hi *types.HistoricalInfo) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
key := types.GetHistoricalInfoKey(height)
|
||||
value := k.cdc.MustMarshal(hi)
|
||||
store.Set(key, value)
|
||||
value, err := k.cdc.Marshal(hi)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return store.Set(key, value)
|
||||
}
|
||||
|
||||
// DeleteHistoricalInfo deletes the historical info at a given height
|
||||
func (k Keeper) DeleteHistoricalInfo(ctx sdk.Context, height int64) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) DeleteHistoricalInfo(ctx context.Context, height int64) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
key := types.GetHistoricalInfoKey(height)
|
||||
|
||||
store.Delete(key)
|
||||
return store.Delete(key)
|
||||
}
|
||||
|
||||
// IterateHistoricalInfo provides an interator over all stored HistoricalInfo
|
||||
@ -41,36 +51,47 @@ func (k Keeper) DeleteHistoricalInfo(ctx sdk.Context, height int64) {
|
||||
// objects. For each HistoricalInfo object, cb will be called. If the cb returns
|
||||
//
|
||||
// true, the iterator will close and stop.
|
||||
func (k Keeper) IterateHistoricalInfo(ctx sdk.Context, cb func(types.HistoricalInfo) bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, types.HistoricalInfoKey)
|
||||
func (k Keeper) IterateHistoricalInfo(ctx context.Context, cb func(types.HistoricalInfo) bool) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
iterator, err := store.Iterator(types.HistoricalInfoKey, storetypes.PrefixEndBytes(types.HistoricalInfoKey))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
histInfo := types.MustUnmarshalHistoricalInfo(k.cdc, iterator.Value())
|
||||
histInfo, err := types.UnmarshalHistoricalInfo(k.cdc, iterator.Value())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cb(histInfo) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAllHistoricalInfo returns all stored HistoricalInfo objects.
|
||||
func (k Keeper) GetAllHistoricalInfo(ctx sdk.Context) []types.HistoricalInfo {
|
||||
func (k Keeper) GetAllHistoricalInfo(ctx context.Context) ([]types.HistoricalInfo, error) {
|
||||
var infos []types.HistoricalInfo
|
||||
|
||||
k.IterateHistoricalInfo(ctx, func(histInfo types.HistoricalInfo) bool {
|
||||
err := k.IterateHistoricalInfo(ctx, func(histInfo types.HistoricalInfo) bool {
|
||||
infos = append(infos, histInfo)
|
||||
return false
|
||||
})
|
||||
|
||||
return infos
|
||||
return infos, err
|
||||
}
|
||||
|
||||
// TrackHistoricalInfo saves the latest historical-info and deletes the oldest
|
||||
// heights that are below pruning height
|
||||
func (k Keeper) TrackHistoricalInfo(ctx sdk.Context) {
|
||||
entryNum := k.HistoricalEntries(ctx)
|
||||
func (k Keeper) TrackHistoricalInfo(ctx context.Context) error {
|
||||
entryNum, err := k.HistoricalEntries(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
|
||||
// Prune store to ensure we only have parameter-defined historical entries.
|
||||
// In most cases, this will involve removing a single historical entry.
|
||||
@ -79,24 +100,32 @@ func (k Keeper) TrackHistoricalInfo(ctx sdk.Context) {
|
||||
// Since the entries to be deleted are always in a continuous range, we can iterate
|
||||
// over the historical entries starting from the most recent version to be pruned
|
||||
// and then return at the first empty entry.
|
||||
for i := ctx.BlockHeight() - int64(entryNum); i >= 0; i-- {
|
||||
_, found := k.GetHistoricalInfo(ctx, i)
|
||||
if found {
|
||||
k.DeleteHistoricalInfo(ctx, i)
|
||||
} else {
|
||||
break
|
||||
for i := sdkCtx.BlockHeight() - int64(entryNum); i >= 0; i-- {
|
||||
_, err := k.GetHistoricalInfo(ctx, i)
|
||||
if err != nil {
|
||||
if errors.Is(err, types.ErrNoHistoricalInfo) {
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
if err = k.DeleteHistoricalInfo(ctx, i); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// if there is no need to persist historicalInfo, return
|
||||
if entryNum == 0 {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create HistoricalInfo struct
|
||||
lastVals := k.GetLastValidators(ctx)
|
||||
historicalEntry := types.NewHistoricalInfo(ctx.BlockHeader(), lastVals, k.PowerReduction(ctx))
|
||||
lastVals, err := k.GetLastValidators(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
historicalEntry := types.NewHistoricalInfo(sdkCtx.BlockHeader(), lastVals, k.PowerReduction(ctx))
|
||||
|
||||
// Set latest HistoricalInfo at current height
|
||||
k.SetHistoricalInfo(ctx, ctx.BlockHeight(), &historicalEntry)
|
||||
return k.SetHistoricalInfo(ctx, sdkCtx.BlockHeight(), &historicalEntry)
|
||||
}
|
||||
|
||||
@ -33,17 +33,17 @@ func (s *KeeperTestSuite) TestHistoricalInfo() {
|
||||
}
|
||||
|
||||
hi := stakingtypes.NewHistoricalInfo(ctx.BlockHeader(), validators, keeper.PowerReduction(ctx))
|
||||
keeper.SetHistoricalInfo(ctx, 2, &hi)
|
||||
require.NoError(keeper.SetHistoricalInfo(ctx, 2, &hi))
|
||||
|
||||
recv, found := keeper.GetHistoricalInfo(ctx, 2)
|
||||
require.True(found, "HistoricalInfo not found after set")
|
||||
recv, err := keeper.GetHistoricalInfo(ctx, 2)
|
||||
require.NoError(err, "HistoricalInfo not found after set")
|
||||
require.Equal(hi, recv, "HistoricalInfo not equal")
|
||||
require.True(IsValSetSorted(recv.Valset, keeper.PowerReduction(ctx)), "HistoricalInfo validators is not sorted")
|
||||
|
||||
keeper.DeleteHistoricalInfo(ctx, 2)
|
||||
require.NoError(keeper.DeleteHistoricalInfo(ctx, 2))
|
||||
|
||||
recv, found = keeper.GetHistoricalInfo(ctx, 2)
|
||||
require.False(found, "HistoricalInfo found after delete")
|
||||
recv, err = keeper.GetHistoricalInfo(ctx, 2)
|
||||
require.ErrorIs(err, stakingtypes.ErrNoHistoricalInfo, "HistoricalInfo found after delete")
|
||||
require.Equal(stakingtypes.HistoricalInfo{}, recv, "HistoricalInfo is not empty")
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ func (s *KeeperTestSuite) TestTrackHistoricalInfo() {
|
||||
// set historical entries in params to 5
|
||||
params := stakingtypes.DefaultParams()
|
||||
params.HistoricalEntries = 5
|
||||
keeper.SetParams(ctx, params)
|
||||
require.NoError(keeper.SetParams(ctx, params))
|
||||
|
||||
// set historical info at 5, 4 which should be pruned
|
||||
// and check that it has been stored
|
||||
@ -74,26 +74,26 @@ func (s *KeeperTestSuite) TestTrackHistoricalInfo() {
|
||||
}
|
||||
hi4 := stakingtypes.NewHistoricalInfo(h4, valSet, keeper.PowerReduction(ctx))
|
||||
hi5 := stakingtypes.NewHistoricalInfo(h5, valSet, keeper.PowerReduction(ctx))
|
||||
keeper.SetHistoricalInfo(ctx, 4, &hi4)
|
||||
keeper.SetHistoricalInfo(ctx, 5, &hi5)
|
||||
recv, found := keeper.GetHistoricalInfo(ctx, 4)
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetHistoricalInfo(ctx, 4, &hi4))
|
||||
require.NoError(keeper.SetHistoricalInfo(ctx, 5, &hi5))
|
||||
recv, err := keeper.GetHistoricalInfo(ctx, 4)
|
||||
require.NoError(err)
|
||||
require.Equal(hi4, recv)
|
||||
recv, found = keeper.GetHistoricalInfo(ctx, 5)
|
||||
require.True(found)
|
||||
recv, err = keeper.GetHistoricalInfo(ctx, 5)
|
||||
require.NoError(err)
|
||||
require.Equal(hi5, recv)
|
||||
|
||||
// Set bonded validators in keeper
|
||||
val1 := testutil.NewValidator(s.T(), addrVals[2], PKs[2])
|
||||
val1.Status = stakingtypes.Bonded // when not bonded, consensus power is Zero
|
||||
val1.Tokens = keeper.TokensFromConsensusPower(ctx, 10)
|
||||
keeper.SetValidator(ctx, val1)
|
||||
keeper.SetLastValidatorPower(ctx, val1.GetOperator(), 10)
|
||||
require.NoError(keeper.SetValidator(ctx, val1))
|
||||
require.NoError(keeper.SetLastValidatorPower(ctx, val1.GetOperator(), 10))
|
||||
val2 := testutil.NewValidator(s.T(), addrVals[3], PKs[3])
|
||||
val1.Status = stakingtypes.Bonded
|
||||
val2.Tokens = keeper.TokensFromConsensusPower(ctx, 80)
|
||||
keeper.SetValidator(ctx, val2)
|
||||
keeper.SetLastValidatorPower(ctx, val2.GetOperator(), 80)
|
||||
require.NoError(keeper.SetValidator(ctx, val2))
|
||||
require.NoError(keeper.SetLastValidatorPower(ctx, val2.GetOperator(), 80))
|
||||
|
||||
vals := []stakingtypes.Validator{val1, val2}
|
||||
require.True(IsValSetSorted(vals, keeper.PowerReduction(ctx)))
|
||||
@ -105,23 +105,23 @@ func (s *KeeperTestSuite) TestTrackHistoricalInfo() {
|
||||
}
|
||||
ctx = ctx.WithBlockHeader(header)
|
||||
|
||||
keeper.TrackHistoricalInfo(ctx)
|
||||
require.NoError(keeper.TrackHistoricalInfo(ctx))
|
||||
|
||||
// Check HistoricalInfo at height 10 is persisted
|
||||
expected := stakingtypes.HistoricalInfo{
|
||||
Header: header,
|
||||
Valset: vals,
|
||||
}
|
||||
recv, found = keeper.GetHistoricalInfo(ctx, 10)
|
||||
require.True(found, "GetHistoricalInfo failed after BeginBlock")
|
||||
recv, err = keeper.GetHistoricalInfo(ctx, 10)
|
||||
require.NoError(err, "GetHistoricalInfo failed after BeginBlock")
|
||||
require.Equal(expected, recv, "GetHistoricalInfo returned unexpected result")
|
||||
|
||||
// Check HistoricalInfo at height 5, 4 is pruned
|
||||
recv, found = keeper.GetHistoricalInfo(ctx, 4)
|
||||
require.False(found, "GetHistoricalInfo did not prune earlier height")
|
||||
recv, err = keeper.GetHistoricalInfo(ctx, 4)
|
||||
require.ErrorIs(err, stakingtypes.ErrNoHistoricalInfo, "GetHistoricalInfo did not prune earlier height")
|
||||
require.Equal(stakingtypes.HistoricalInfo{}, recv, "GetHistoricalInfo at height 4 is not empty after prune")
|
||||
recv, found = keeper.GetHistoricalInfo(ctx, 5)
|
||||
require.False(found, "GetHistoricalInfo did not prune first prune height")
|
||||
recv, err = keeper.GetHistoricalInfo(ctx, 5)
|
||||
require.ErrorIs(err, stakingtypes.ErrNoHistoricalInfo, "GetHistoricalInfo did not prune first prune height")
|
||||
require.Equal(stakingtypes.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune")
|
||||
}
|
||||
|
||||
@ -147,9 +147,10 @@ func (s *KeeperTestSuite) TestGetAllHistoricalInfo() {
|
||||
expHistInfos := []stakingtypes.HistoricalInfo{hist1, hist2, hist3}
|
||||
|
||||
for i, hi := range expHistInfos {
|
||||
keeper.SetHistoricalInfo(ctx, int64(9+i), &hi) //nolint:gosec // G601: Implicit memory aliasing in for loop.
|
||||
require.NoError(keeper.SetHistoricalInfo(ctx, int64(9+i), &hi)) //nolint:gosec // G601: Implicit memory aliasing in for loop.
|
||||
}
|
||||
|
||||
infos := keeper.GetAllHistoricalInfo(ctx)
|
||||
infos, err := keeper.GetAllHistoricalInfo(ctx)
|
||||
require.NoError(err)
|
||||
require.Equal(expHistInfos, infos)
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
@ -51,9 +52,12 @@ func ModuleAccountInvariants(k *Keeper) sdk.Invariant {
|
||||
notBonded := math.ZeroInt()
|
||||
bondedPool := k.GetBondedPool(ctx)
|
||||
notBondedPool := k.GetNotBondedPool(ctx)
|
||||
bondDenom := k.BondDenom(ctx)
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
k.IterateValidators(ctx, func(_ int64, validator types.ValidatorI) bool {
|
||||
err = k.IterateValidators(ctx, func(_ int64, validator types.ValidatorI) bool {
|
||||
switch validator.GetStatus() {
|
||||
case types.Bonded:
|
||||
bonded = bonded.Add(validator.GetTokens())
|
||||
@ -64,13 +68,19 @@ func ModuleAccountInvariants(k *Keeper) sdk.Invariant {
|
||||
}
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
k.IterateUnbondingDelegations(ctx, func(_ int64, ubd types.UnbondingDelegation) bool {
|
||||
err = k.IterateUnbondingDelegations(ctx, func(_ int64, ubd types.UnbondingDelegation) bool {
|
||||
for _, entry := range ubd.Entries {
|
||||
notBonded = notBonded.Add(entry.Balance)
|
||||
}
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
poolBonded := k.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom)
|
||||
poolNotBonded := k.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom)
|
||||
@ -99,10 +109,13 @@ func NonNegativePowerInvariant(k *Keeper) sdk.Invariant {
|
||||
broken bool
|
||||
)
|
||||
|
||||
iterator := k.ValidatorsPowerStoreIterator(ctx)
|
||||
iterator, err := k.ValidatorsPowerStoreIterator(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
validator, found := k.GetValidator(ctx, iterator.Value())
|
||||
if !found {
|
||||
validator, err := k.GetValidator(ctx, iterator.Value())
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("validator record not found for address: %X\n", iterator.Value()))
|
||||
}
|
||||
|
||||
@ -134,7 +147,10 @@ func PositiveDelegationInvariant(k *Keeper) sdk.Invariant {
|
||||
count int
|
||||
)
|
||||
|
||||
delegations := k.GetAllDelegations(ctx)
|
||||
delegations, err := k.GetAllDelegations(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, delegation := range delegations {
|
||||
if delegation.Shares.IsNegative() {
|
||||
count++
|
||||
@ -164,7 +180,11 @@ func DelegatorSharesInvariant(k *Keeper) sdk.Invariant {
|
||||
broken bool
|
||||
)
|
||||
|
||||
validators := k.GetAllValidators(ctx)
|
||||
validators, err := k.GetAllValidators(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
validatorsDelegationShares := map[string]math.LegacyDec{}
|
||||
|
||||
// initialize a map: validator -> its delegation shares
|
||||
@ -173,7 +193,11 @@ func DelegatorSharesInvariant(k *Keeper) sdk.Invariant {
|
||||
}
|
||||
|
||||
// iterate through all the delegations to calculate the total delegation shares for each validator
|
||||
delegations := k.GetAllDelegations(ctx)
|
||||
delegations, err := k.GetAllDelegations(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, delegation := range delegations {
|
||||
delegationValidatorAddr := delegation.GetValidatorAddr().String()
|
||||
validatorDelegationShares := validatorsDelegationShares[delegationValidatorAddr]
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
"cosmossdk.io/math"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
storetypes "cosmossdk.io/core/store"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
@ -21,18 +23,18 @@ var _ types.DelegationSet = Keeper{}
|
||||
|
||||
// Keeper of the x/staking store
|
||||
type Keeper struct {
|
||||
storeKey storetypes.StoreKey
|
||||
cdc codec.BinaryCodec
|
||||
authKeeper types.AccountKeeper
|
||||
bankKeeper types.BankKeeper
|
||||
hooks types.StakingHooks
|
||||
authority string
|
||||
storeService storetypes.KVStoreService
|
||||
cdc codec.BinaryCodec
|
||||
authKeeper types.AccountKeeper
|
||||
bankKeeper types.BankKeeper
|
||||
hooks types.StakingHooks
|
||||
authority string
|
||||
}
|
||||
|
||||
// NewKeeper creates a new staking Keeper instance
|
||||
func NewKeeper(
|
||||
cdc codec.BinaryCodec,
|
||||
key storetypes.StoreKey,
|
||||
storeService storetypes.KVStoreService,
|
||||
ak types.AccountKeeper,
|
||||
bk types.BankKeeper,
|
||||
authority string,
|
||||
@ -52,18 +54,19 @@ func NewKeeper(
|
||||
}
|
||||
|
||||
return &Keeper{
|
||||
storeKey: key,
|
||||
cdc: cdc,
|
||||
authKeeper: ak,
|
||||
bankKeeper: bk,
|
||||
hooks: nil,
|
||||
authority: authority,
|
||||
storeService: storeService,
|
||||
cdc: cdc,
|
||||
authKeeper: ak,
|
||||
bankKeeper: bk,
|
||||
hooks: nil,
|
||||
authority: authority,
|
||||
}
|
||||
}
|
||||
|
||||
// Logger returns a module-specific logger.
|
||||
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
|
||||
return ctx.Logger().With("module", "x/"+types.ModuleName)
|
||||
func (k Keeper) Logger(ctx context.Context) log.Logger {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
return sdkCtx.Logger().With("module", "x/"+types.ModuleName)
|
||||
}
|
||||
|
||||
// Hooks gets the hooks for staking *Keeper {
|
||||
@ -87,25 +90,34 @@ func (k *Keeper) SetHooks(sh types.StakingHooks) {
|
||||
}
|
||||
|
||||
// GetLastTotalPower Load the last total validator power.
|
||||
func (k Keeper) GetLastTotalPower(ctx sdk.Context) math.Int {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get(types.LastTotalPowerKey)
|
||||
func (k Keeper) GetLastTotalPower(ctx context.Context) (math.Int, error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz, err := store.Get(types.LastTotalPowerKey)
|
||||
if err != nil {
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
|
||||
if bz == nil {
|
||||
return math.ZeroInt()
|
||||
return math.ZeroInt(), nil
|
||||
}
|
||||
|
||||
ip := sdk.IntProto{}
|
||||
k.cdc.MustUnmarshal(bz, &ip)
|
||||
err = k.cdc.Unmarshal(bz, &ip)
|
||||
if err != nil {
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
|
||||
return ip.Int
|
||||
return ip.Int, nil
|
||||
}
|
||||
|
||||
// SetLastTotalPower Set the last total validator power.
|
||||
func (k Keeper) SetLastTotalPower(ctx sdk.Context, power math.Int) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := k.cdc.MustMarshal(&sdk.IntProto{Int: power})
|
||||
store.Set(types.LastTotalPowerKey, bz)
|
||||
func (k Keeper) SetLastTotalPower(ctx context.Context, power math.Int) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz, err := k.cdc.Marshal(&sdk.IntProto{Int: power})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return store.Set(types.LastTotalPowerKey, bz)
|
||||
}
|
||||
|
||||
// GetAuthority returns the x/staking module's authority.
|
||||
@ -114,19 +126,28 @@ func (k Keeper) GetAuthority() string {
|
||||
}
|
||||
|
||||
// SetValidatorUpdates sets the ABCI validator power updates for the current block.
|
||||
func (k Keeper) SetValidatorUpdates(ctx sdk.Context, valUpdates []abci.ValidatorUpdate) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := k.cdc.MustMarshal(&types.ValidatorUpdates{Updates: valUpdates})
|
||||
store.Set(types.ValidatorUpdatesKey, bz)
|
||||
func (k Keeper) SetValidatorUpdates(ctx context.Context, valUpdates []abci.ValidatorUpdate) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz, err := k.cdc.Marshal(&types.ValidatorUpdates{Updates: valUpdates})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return store.Set(types.ValidatorUpdatesKey, bz)
|
||||
}
|
||||
|
||||
// GetValidatorUpdates returns the ABCI validator power updates within the current block.
|
||||
func (k Keeper) GetValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get(types.ValidatorUpdatesKey)
|
||||
func (k Keeper) GetValidatorUpdates(ctx context.Context) ([]abci.ValidatorUpdate, error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz, err := store.Get(types.ValidatorUpdatesKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var valUpdates types.ValidatorUpdates
|
||||
k.cdc.MustUnmarshal(bz, &valUpdates)
|
||||
err = k.cdc.Unmarshal(bz, &valUpdates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return valUpdates.Updates
|
||||
return valUpdates.Updates, nil
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec/address"
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -41,7 +42,9 @@ type KeeperTestSuite struct {
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) SetupTest() {
|
||||
require := s.Require()
|
||||
key := storetypes.NewKVStoreKey(stakingtypes.StoreKey)
|
||||
storeService := runtime.NewKVStoreService(key)
|
||||
testCtx := testutil.DefaultContextWithDB(s.T(), key, storetypes.NewTransientStoreKey("transient_test"))
|
||||
ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: cmttime.Now()})
|
||||
encCfg := moduletestutil.MakeTestEncodingConfig()
|
||||
@ -56,12 +59,12 @@ func (s *KeeperTestSuite) SetupTest() {
|
||||
|
||||
keeper := stakingkeeper.NewKeeper(
|
||||
encCfg.Codec,
|
||||
key,
|
||||
storeService,
|
||||
accountKeeper,
|
||||
bankKeeper,
|
||||
authtypes.NewModuleAddress(stakingtypes.GovModuleName).String(),
|
||||
)
|
||||
keeper.SetParams(ctx, stakingtypes.DefaultParams())
|
||||
require.NoError(keeper.SetParams(ctx, stakingtypes.DefaultParams()))
|
||||
|
||||
s.ctx = ctx
|
||||
s.stakingKeeper = keeper
|
||||
@ -81,13 +84,15 @@ func (s *KeeperTestSuite) TestParams() {
|
||||
|
||||
expParams := stakingtypes.DefaultParams()
|
||||
// check that the empty keeper loads the default
|
||||
resParams := keeper.GetParams(ctx)
|
||||
resParams, err := keeper.GetParams(ctx)
|
||||
require.NoError(err)
|
||||
require.Equal(expParams, resParams)
|
||||
|
||||
expParams.MaxValidators = 555
|
||||
expParams.MaxEntries = 111
|
||||
keeper.SetParams(ctx, expParams)
|
||||
resParams = keeper.GetParams(ctx)
|
||||
require.NoError(keeper.SetParams(ctx, expParams))
|
||||
resParams, err = keeper.GetParams(ctx)
|
||||
require.NoError(err)
|
||||
require.True(expParams.Equal(resParams))
|
||||
}
|
||||
|
||||
@ -96,8 +101,9 @@ func (s *KeeperTestSuite) TestLastTotalPower() {
|
||||
require := s.Require()
|
||||
|
||||
expTotalPower := math.NewInt(10 ^ 9)
|
||||
keeper.SetLastTotalPower(ctx, expTotalPower)
|
||||
resTotalPower := keeper.GetLastTotalPower(ctx)
|
||||
require.NoError(keeper.SetLastTotalPower(ctx, expTotalPower))
|
||||
resTotalPower, err := keeper.GetLastTotalPower(ctx)
|
||||
require.NoError(err)
|
||||
require.True(expTotalPower.Equal(resTotalPower))
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/exported"
|
||||
v2 "github.com/cosmos/cosmos-sdk/x/staking/migrations/v2"
|
||||
@ -25,20 +26,24 @@ func NewMigrator(keeper *Keeper, legacySubspace exported.Subspace) Migrator {
|
||||
|
||||
// Migrate1to2 migrates from version 1 to 2.
|
||||
func (m Migrator) Migrate1to2(ctx sdk.Context) error {
|
||||
return v2.MigrateStore(ctx, m.keeper.storeKey)
|
||||
store := runtime.KVStoreAdapter(m.keeper.storeService.OpenKVStore(ctx))
|
||||
return v2.MigrateStore(ctx, store)
|
||||
}
|
||||
|
||||
// Migrate2to3 migrates x/staking state from consensus version 2 to 3.
|
||||
func (m Migrator) Migrate2to3(ctx sdk.Context) error {
|
||||
return v3.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc, m.legacySubspace)
|
||||
store := runtime.KVStoreAdapter(m.keeper.storeService.OpenKVStore(ctx))
|
||||
return v3.MigrateStore(ctx, store, m.keeper.cdc, m.legacySubspace)
|
||||
}
|
||||
|
||||
// Migrate3to4 migrates x/staking state from consensus version 3 to 4.
|
||||
func (m Migrator) Migrate3to4(ctx sdk.Context) error {
|
||||
return v4.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc, m.legacySubspace)
|
||||
store := runtime.KVStoreAdapter(m.keeper.storeService.OpenKVStore(ctx))
|
||||
return v4.MigrateStore(ctx, store, m.keeper.cdc, m.legacySubspace)
|
||||
}
|
||||
|
||||
// Migrate4to5 migrates x/staking state from consensus version 4 to 5.
|
||||
func (m Migrator) Migrate4to5(ctx sdk.Context) error {
|
||||
return v5.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc)
|
||||
store := runtime.KVStoreAdapter(m.keeper.storeService.OpenKVStore(ctx))
|
||||
return v5.MigrateStore(ctx, store, m.keeper.cdc)
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ func NewMsgServerImpl(keeper *Keeper) types.MsgServer {
|
||||
var _ types.MsgServer = msgServer{}
|
||||
|
||||
// CreateValidator defines a method for creating a new validator
|
||||
func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateValidator) (*types.MsgCreateValidatorResponse, error) {
|
||||
func (k msgServer) CreateValidator(ctx context.Context, msg *types.MsgCreateValidator) (*types.MsgCreateValidatorResponse, error) {
|
||||
valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid validator address: %s", err)
|
||||
@ -42,14 +42,17 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
minCommRate, err := k.MinCommissionRate(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if msg.Commission.Rate.LT(k.MinCommissionRate(ctx)) {
|
||||
return nil, errorsmod.Wrapf(types.ErrCommissionLTMinRate, "cannot set validator commission to less than minimum rate of %s", k.MinCommissionRate(ctx))
|
||||
if msg.Commission.Rate.LT(minCommRate) {
|
||||
return nil, errorsmod.Wrapf(types.ErrCommissionLTMinRate, "cannot set validator commission to less than minimum rate of %s", minCommRate)
|
||||
}
|
||||
|
||||
// check to see if the pubkey or sender has been registered before
|
||||
if _, found := k.GetValidator(ctx, valAddr); found {
|
||||
if _, err := k.GetValidator(ctx, valAddr); err == nil {
|
||||
return nil, types.ErrValidatorOwnerExists
|
||||
}
|
||||
|
||||
@ -58,11 +61,15 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa
|
||||
return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidType, "Expecting cryptotypes.PubKey, got %T", pk)
|
||||
}
|
||||
|
||||
if _, found := k.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(pk)); found {
|
||||
if _, err := k.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(pk)); err == nil {
|
||||
return nil, types.ErrValidatorPubKeyExists
|
||||
}
|
||||
|
||||
bondDenom := k.BondDenom(ctx)
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if msg.Value.Denom != bondDenom {
|
||||
return nil, errorsmod.Wrapf(
|
||||
sdkerrors.ErrInvalidRequest, "invalid coin denomination: got %s, expected %s", msg.Value.Denom, bondDenom,
|
||||
@ -73,7 +80,8 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cp := ctx.ConsensusParams()
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
cp := sdkCtx.ConsensusParams()
|
||||
if cp.Validator != nil {
|
||||
pkType := pk.Type()
|
||||
hasKeyType := false
|
||||
@ -98,7 +106,7 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa
|
||||
|
||||
commission := types.NewCommissionWithTime(
|
||||
msg.Commission.Rate, msg.Commission.MaxRate,
|
||||
msg.Commission.MaxChangeRate, ctx.BlockHeader().Time,
|
||||
msg.Commission.MaxChangeRate, sdkCtx.BlockHeader().Time,
|
||||
)
|
||||
|
||||
validator, err = validator.SetInitialCommission(commission)
|
||||
@ -108,9 +116,20 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa
|
||||
|
||||
validator.MinSelfDelegation = msg.MinSelfDelegation
|
||||
|
||||
k.SetValidator(ctx, validator)
|
||||
k.SetValidatorByConsAddr(ctx, validator)
|
||||
k.SetNewValidatorByPowerIndex(ctx, validator)
|
||||
err = k.SetValidator(ctx, validator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = k.SetValidatorByConsAddr(ctx, validator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = k.SetNewValidatorByPowerIndex(ctx, validator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// call the after-creation hook
|
||||
if err := k.Hooks().AfterValidatorCreated(ctx, validator.GetOperator()); err != nil {
|
||||
@ -125,7 +144,7 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdkCtx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCreateValidator,
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, msg.ValidatorAddress),
|
||||
@ -137,7 +156,7 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa
|
||||
}
|
||||
|
||||
// EditValidator defines a method for editing an existing validator
|
||||
func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValidator) (*types.MsgEditValidatorResponse, error) {
|
||||
func (k msgServer) EditValidator(ctx context.Context, msg *types.MsgEditValidator) (*types.MsgEditValidatorResponse, error) {
|
||||
valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid validator address: %s", err)
|
||||
@ -160,12 +179,10 @@ func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValida
|
||||
}
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
// validator must already be registered
|
||||
validator, found := k.GetValidator(ctx, valAddr)
|
||||
if !found {
|
||||
return nil, types.ErrNoValidatorFound
|
||||
validator, err := k.GetValidator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// replace all editable fields (clients should autofill existing values)
|
||||
@ -202,9 +219,13 @@ func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValida
|
||||
validator.MinSelfDelegation = *msg.MinSelfDelegation
|
||||
}
|
||||
|
||||
k.SetValidator(ctx, validator)
|
||||
err = k.SetValidator(ctx, validator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
sdkCtx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeEditValidator,
|
||||
sdk.NewAttribute(types.AttributeKeyCommissionRate, validator.Commission.String()),
|
||||
@ -216,7 +237,7 @@ func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValida
|
||||
}
|
||||
|
||||
// Delegate defines a method for performing a delegation of coins from a delegator to a validator
|
||||
func (k msgServer) Delegate(goCtx context.Context, msg *types.MsgDelegate) (*types.MsgDelegateResponse, error) {
|
||||
func (k msgServer) Delegate(ctx context.Context, msg *types.MsgDelegate) (*types.MsgDelegateResponse, error) {
|
||||
valAddr, valErr := sdk.ValAddressFromBech32(msg.ValidatorAddress)
|
||||
if valErr != nil {
|
||||
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid validator address: %s", valErr)
|
||||
@ -234,14 +255,16 @@ func (k msgServer) Delegate(goCtx context.Context, msg *types.MsgDelegate) (*typ
|
||||
)
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
validator, found := k.GetValidator(ctx, valAddr)
|
||||
if !found {
|
||||
return nil, types.ErrNoValidatorFound
|
||||
validator, err := k.GetValidator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bondDenom := k.BondDenom(ctx)
|
||||
if msg.Amount.Denom != bondDenom {
|
||||
return nil, errorsmod.Wrapf(
|
||||
sdkerrors.ErrInvalidRequest, "invalid coin denomination: got %s, expected %s", msg.Amount.Denom, bondDenom,
|
||||
@ -265,7 +288,8 @@ func (k msgServer) Delegate(goCtx context.Context, msg *types.MsgDelegate) (*typ
|
||||
}()
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
sdkCtx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeDelegate,
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, msg.ValidatorAddress),
|
||||
@ -278,7 +302,7 @@ func (k msgServer) Delegate(goCtx context.Context, msg *types.MsgDelegate) (*typ
|
||||
}
|
||||
|
||||
// BeginRedelegate defines a method for performing a redelegation of coins from a delegator and source validator to a destination validator
|
||||
func (k msgServer) BeginRedelegate(goCtx context.Context, msg *types.MsgBeginRedelegate) (*types.MsgBeginRedelegateResponse, error) {
|
||||
func (k msgServer) BeginRedelegate(ctx context.Context, msg *types.MsgBeginRedelegate) (*types.MsgBeginRedelegateResponse, error) {
|
||||
valSrcAddr, err := sdk.ValAddressFromBech32(msg.ValidatorSrcAddress)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid source validator address: %s", err)
|
||||
@ -301,8 +325,6 @@ func (k msgServer) BeginRedelegate(goCtx context.Context, msg *types.MsgBeginRed
|
||||
)
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
shares, err := k.ValidateUnbondAmount(
|
||||
ctx, delegatorAddress, valSrcAddr, msg.Amount.Amount,
|
||||
)
|
||||
@ -310,7 +332,11 @@ func (k msgServer) BeginRedelegate(goCtx context.Context, msg *types.MsgBeginRed
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bondDenom := k.BondDenom(ctx)
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if msg.Amount.Denom != bondDenom {
|
||||
return nil, errorsmod.Wrapf(
|
||||
sdkerrors.ErrInvalidRequest, "invalid coin denomination: got %s, expected %s", msg.Amount.Denom, bondDenom,
|
||||
@ -335,7 +361,8 @@ func (k msgServer) BeginRedelegate(goCtx context.Context, msg *types.MsgBeginRed
|
||||
}()
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
sdkCtx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeRedelegate,
|
||||
sdk.NewAttribute(types.AttributeKeySrcValidator, msg.ValidatorSrcAddress),
|
||||
@ -351,7 +378,7 @@ func (k msgServer) BeginRedelegate(goCtx context.Context, msg *types.MsgBeginRed
|
||||
}
|
||||
|
||||
// Undelegate defines a method for performing an undelegation from a delegate and a validator
|
||||
func (k msgServer) Undelegate(goCtx context.Context, msg *types.MsgUndelegate) (*types.MsgUndelegateResponse, error) {
|
||||
func (k msgServer) Undelegate(ctx context.Context, msg *types.MsgUndelegate) (*types.MsgUndelegateResponse, error) {
|
||||
addr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid validator address: %s", err)
|
||||
@ -369,8 +396,6 @@ func (k msgServer) Undelegate(goCtx context.Context, msg *types.MsgUndelegate) (
|
||||
)
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
shares, err := k.ValidateUnbondAmount(
|
||||
ctx, delegatorAddress, addr, msg.Amount.Amount,
|
||||
)
|
||||
@ -378,7 +403,11 @@ func (k msgServer) Undelegate(goCtx context.Context, msg *types.MsgUndelegate) (
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bondDenom := k.BondDenom(ctx)
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if msg.Amount.Denom != bondDenom {
|
||||
return nil, errorsmod.Wrapf(
|
||||
sdkerrors.ErrInvalidRequest, "invalid coin denomination: got %s, expected %s", msg.Amount.Denom, bondDenom,
|
||||
@ -403,7 +432,8 @@ func (k msgServer) Undelegate(goCtx context.Context, msg *types.MsgUndelegate) (
|
||||
}()
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
sdkCtx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeUnbond,
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, msg.ValidatorAddress),
|
||||
@ -420,7 +450,7 @@ func (k msgServer) Undelegate(goCtx context.Context, msg *types.MsgUndelegate) (
|
||||
|
||||
// CancelUnbondingDelegation defines a method for canceling the unbonding delegation
|
||||
// and delegate back to the validator.
|
||||
func (k msgServer) CancelUnbondingDelegation(goCtx context.Context, msg *types.MsgCancelUnbondingDelegation) (*types.MsgCancelUnbondingDelegationResponse, error) {
|
||||
func (k msgServer) CancelUnbondingDelegation(ctx context.Context, msg *types.MsgCancelUnbondingDelegation) (*types.MsgCancelUnbondingDelegationResponse, error) {
|
||||
valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid validator address: %s", err)
|
||||
@ -445,18 +475,20 @@ func (k msgServer) CancelUnbondingDelegation(goCtx context.Context, msg *types.M
|
||||
)
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bondDenom := k.BondDenom(ctx)
|
||||
if msg.Amount.Denom != bondDenom {
|
||||
return nil, errorsmod.Wrapf(
|
||||
sdkerrors.ErrInvalidRequest, "invalid coin denomination: got %s, expected %s", msg.Amount.Denom, bondDenom,
|
||||
)
|
||||
}
|
||||
|
||||
validator, found := k.GetValidator(ctx, valAddr)
|
||||
if !found {
|
||||
return nil, types.ErrNoValidatorFound
|
||||
validator, err := k.GetValidator(ctx, valAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// In some situations, the exchange rate becomes invalid, e.g. if
|
||||
@ -470,8 +502,8 @@ func (k msgServer) CancelUnbondingDelegation(goCtx context.Context, msg *types.M
|
||||
return nil, types.ErrValidatorJailed
|
||||
}
|
||||
|
||||
ubd, found := k.GetUnbondingDelegation(ctx, delegatorAddress, valAddr)
|
||||
if !found {
|
||||
ubd, err := k.GetUnbondingDelegation(ctx, delegatorAddress, valAddr)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(
|
||||
codes.NotFound,
|
||||
"unbonding delegation with delegator %s not found for validator %s",
|
||||
@ -499,7 +531,8 @@ func (k msgServer) CancelUnbondingDelegation(goCtx context.Context, msg *types.M
|
||||
return nil, sdkerrors.ErrInvalidRequest.Wrap("amount is greater than the unbonding delegation entry balance")
|
||||
}
|
||||
|
||||
if unbondEntry.CompletionTime.Before(ctx.BlockTime()) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
if unbondEntry.CompletionTime.Before(sdkCtx.BlockTime()) {
|
||||
return nil, sdkerrors.ErrInvalidRequest.Wrap("unbonding delegation is already processed")
|
||||
}
|
||||
|
||||
@ -521,12 +554,16 @@ func (k msgServer) CancelUnbondingDelegation(goCtx context.Context, msg *types.M
|
||||
|
||||
// set the unbonding delegation or remove it if there are no more entries
|
||||
if len(ubd.Entries) == 0 {
|
||||
k.RemoveUnbondingDelegation(ctx, ubd)
|
||||
err = k.RemoveUnbondingDelegation(ctx, ubd)
|
||||
} else {
|
||||
k.SetUnbondingDelegation(ctx, ubd)
|
||||
err = k.SetUnbondingDelegation(ctx, ubd)
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sdkCtx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCancelUnbondingDelegation,
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Amount.String()),
|
||||
@ -539,7 +576,7 @@ func (k msgServer) CancelUnbondingDelegation(goCtx context.Context, msg *types.M
|
||||
return &types.MsgCancelUnbondingDelegationResponse{}, nil
|
||||
}
|
||||
|
||||
func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
|
||||
func (k msgServer) UpdateParams(ctx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
|
||||
if k.authority != msg.Authority {
|
||||
return nil, errorsmod.Wrapf(types.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Authority)
|
||||
}
|
||||
@ -548,8 +585,6 @@ func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParam
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
// store params
|
||||
if err := k.SetParams(ctx, msg.Params); err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -567,9 +567,9 @@ func (s *KeeperTestSuite) TestMsgBeginRedelegate() {
|
||||
|
||||
shares := math.LegacyNewDec(100)
|
||||
del := stakingtypes.NewDelegation(Addr, srcValAddr, shares)
|
||||
keeper.SetDelegation(ctx, del)
|
||||
_, found := keeper.GetDelegation(ctx, Addr, srcValAddr)
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetDelegation(ctx, del))
|
||||
_, err = keeper.GetDelegation(ctx, Addr, srcValAddr)
|
||||
require.NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@ -721,9 +721,9 @@ func (s *KeeperTestSuite) TestMsgUndelegate() {
|
||||
|
||||
shares := math.LegacyNewDec(100)
|
||||
del := stakingtypes.NewDelegation(Addr, ValAddr, shares)
|
||||
keeper.SetDelegation(ctx, del)
|
||||
_, found := keeper.GetDelegation(ctx, Addr, ValAddr)
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetDelegation(ctx, del))
|
||||
_, err = keeper.GetDelegation(ctx, Addr, ValAddr)
|
||||
require.NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@ -846,15 +846,15 @@ func (s *KeeperTestSuite) TestMsgCancelUnbondingDelegation() {
|
||||
|
||||
shares := math.LegacyNewDec(100)
|
||||
del := stakingtypes.NewDelegation(Addr, ValAddr, shares)
|
||||
keeper.SetDelegation(ctx, del)
|
||||
resDel, found := keeper.GetDelegation(ctx, Addr, ValAddr)
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetDelegation(ctx, del))
|
||||
resDel, err := keeper.GetDelegation(ctx, Addr, ValAddr)
|
||||
require.NoError(err)
|
||||
require.Equal(del, resDel)
|
||||
|
||||
ubd := stakingtypes.NewUnbondingDelegation(Addr, ValAddr, 10, ctx.BlockTime().Add(time.Minute*10), shares.RoundInt(), 0)
|
||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||
resUnbond, found := keeper.GetUnbondingDelegation(ctx, Addr, ValAddr)
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetUnbondingDelegation(ctx, ubd))
|
||||
resUnbond, err := keeper.GetUnbondingDelegation(ctx, Addr, ValAddr)
|
||||
require.NoError(err)
|
||||
require.Equal(ubd, resUnbond)
|
||||
|
||||
testCases := []struct {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
@ -10,66 +11,74 @@ import (
|
||||
)
|
||||
|
||||
// UnbondingTime - The time duration for unbonding
|
||||
func (k Keeper) UnbondingTime(ctx sdk.Context) time.Duration {
|
||||
return k.GetParams(ctx).UnbondingTime
|
||||
func (k Keeper) UnbondingTime(ctx context.Context) (time.Duration, error) {
|
||||
params, err := k.GetParams(ctx)
|
||||
return params.UnbondingTime, err
|
||||
}
|
||||
|
||||
// MaxValidators - Maximum number of validators
|
||||
func (k Keeper) MaxValidators(ctx sdk.Context) uint32 {
|
||||
return k.GetParams(ctx).MaxValidators
|
||||
func (k Keeper) MaxValidators(ctx context.Context) (uint32, error) {
|
||||
params, err := k.GetParams(ctx)
|
||||
return params.MaxValidators, err
|
||||
}
|
||||
|
||||
// MaxEntries - Maximum number of simultaneous unbonding
|
||||
// delegations or redelegations (per pair/trio)
|
||||
func (k Keeper) MaxEntries(ctx sdk.Context) uint32 {
|
||||
return k.GetParams(ctx).MaxEntries
|
||||
func (k Keeper) MaxEntries(ctx context.Context) (uint32, error) {
|
||||
params, err := k.GetParams(ctx)
|
||||
return params.MaxEntries, err
|
||||
}
|
||||
|
||||
// HistoricalEntries = number of historical info entries
|
||||
// to persist in store
|
||||
func (k Keeper) HistoricalEntries(ctx sdk.Context) uint32 {
|
||||
return k.GetParams(ctx).HistoricalEntries
|
||||
func (k Keeper) HistoricalEntries(ctx context.Context) (uint32, error) {
|
||||
params, err := k.GetParams(ctx)
|
||||
return params.HistoricalEntries, err
|
||||
}
|
||||
|
||||
// BondDenom - Bondable coin denomination
|
||||
func (k Keeper) BondDenom(ctx sdk.Context) string {
|
||||
return k.GetParams(ctx).BondDenom
|
||||
func (k Keeper) BondDenom(ctx context.Context) (string, error) {
|
||||
params, err := k.GetParams(ctx)
|
||||
return params.BondDenom, err
|
||||
}
|
||||
|
||||
// PowerReduction - is the amount of staking tokens required for 1 unit of consensus-engine power.
|
||||
// Currently, this returns a global variable that the app developer can tweak.
|
||||
// TODO: we might turn this into an on-chain param:
|
||||
// https://github.com/cosmos/cosmos-sdk/issues/8365
|
||||
func (k Keeper) PowerReduction(ctx sdk.Context) math.Int {
|
||||
func (k Keeper) PowerReduction(ctx context.Context) math.Int {
|
||||
return sdk.DefaultPowerReduction
|
||||
}
|
||||
|
||||
// MinCommissionRate - Minimum validator commission rate
|
||||
func (k Keeper) MinCommissionRate(ctx sdk.Context) math.LegacyDec {
|
||||
return k.GetParams(ctx).MinCommissionRate
|
||||
func (k Keeper) MinCommissionRate(ctx context.Context) (math.LegacyDec, error) {
|
||||
params, err := k.GetParams(ctx)
|
||||
return params.MinCommissionRate, err
|
||||
}
|
||||
|
||||
// SetParams sets the x/staking module parameters.
|
||||
// CONTRACT: This method performs no validation of the parameters.
|
||||
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) SetParams(ctx context.Context, params types.Params) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz, err := k.cdc.Marshal(¶ms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
store.Set(types.ParamsKey, bz)
|
||||
|
||||
return nil
|
||||
return store.Set(types.ParamsKey, bz)
|
||||
}
|
||||
|
||||
// GetParams sets the x/staking module parameters.
|
||||
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get(types.ParamsKey)
|
||||
if bz == nil {
|
||||
return params
|
||||
func (k Keeper) GetParams(ctx context.Context) (params types.Params, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz, err := store.Get(types.ParamsKey)
|
||||
if err != nil {
|
||||
return params, err
|
||||
}
|
||||
|
||||
k.cdc.MustUnmarshal(bz, ¶ms)
|
||||
return params
|
||||
if bz == nil {
|
||||
return params, nil
|
||||
}
|
||||
|
||||
err = k.cdc.Unmarshal(bz, ¶ms)
|
||||
return params, err
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -8,72 +10,104 @@ import (
|
||||
)
|
||||
|
||||
// GetBondedPool returns the bonded tokens pool's module account
|
||||
func (k Keeper) GetBondedPool(ctx sdk.Context) (bondedPool sdk.ModuleAccountI) {
|
||||
func (k Keeper) GetBondedPool(ctx context.Context) (bondedPool sdk.ModuleAccountI) {
|
||||
return k.authKeeper.GetModuleAccount(ctx, types.BondedPoolName)
|
||||
}
|
||||
|
||||
// GetNotBondedPool returns the not bonded tokens pool's module account
|
||||
func (k Keeper) GetNotBondedPool(ctx sdk.Context) (notBondedPool sdk.ModuleAccountI) {
|
||||
func (k Keeper) GetNotBondedPool(ctx context.Context) (notBondedPool sdk.ModuleAccountI) {
|
||||
return k.authKeeper.GetModuleAccount(ctx, types.NotBondedPoolName)
|
||||
}
|
||||
|
||||
// bondedTokensToNotBonded transfers coins from the bonded to the not bonded pool within staking
|
||||
func (k Keeper) bondedTokensToNotBonded(ctx sdk.Context, tokens math.Int) {
|
||||
coins := sdk.NewCoins(sdk.NewCoin(k.BondDenom(ctx), tokens))
|
||||
if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.BondedPoolName, types.NotBondedPoolName, coins); err != nil {
|
||||
panic(err)
|
||||
func (k Keeper) bondedTokensToNotBonded(ctx context.Context, tokens math.Int) error {
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
coins := sdk.NewCoins(sdk.NewCoin(bondDenom, tokens))
|
||||
return k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.BondedPoolName, types.NotBondedPoolName, coins)
|
||||
}
|
||||
|
||||
// notBondedTokensToBonded transfers coins from the not bonded to the bonded pool within staking
|
||||
func (k Keeper) notBondedTokensToBonded(ctx sdk.Context, tokens math.Int) {
|
||||
coins := sdk.NewCoins(sdk.NewCoin(k.BondDenom(ctx), tokens))
|
||||
if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.NotBondedPoolName, types.BondedPoolName, coins); err != nil {
|
||||
panic(err)
|
||||
func (k Keeper) notBondedTokensToBonded(ctx context.Context, tokens math.Int) error {
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
coins := sdk.NewCoins(sdk.NewCoin(bondDenom, tokens))
|
||||
return k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.NotBondedPoolName, types.BondedPoolName, coins)
|
||||
}
|
||||
|
||||
// burnBondedTokens removes coins from the bonded pool module account
|
||||
func (k Keeper) burnBondedTokens(ctx sdk.Context, amt math.Int) error {
|
||||
func (k Keeper) burnBondedTokens(ctx context.Context, amt math.Int) error {
|
||||
if !amt.IsPositive() {
|
||||
// skip as no coins need to be burned
|
||||
return nil
|
||||
}
|
||||
|
||||
coins := sdk.NewCoins(sdk.NewCoin(k.BondDenom(ctx), amt))
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
coins := sdk.NewCoins(sdk.NewCoin(bondDenom, amt))
|
||||
|
||||
return k.bankKeeper.BurnCoins(ctx, types.BondedPoolName, coins)
|
||||
}
|
||||
|
||||
// burnNotBondedTokens removes coins from the not bonded pool module account
|
||||
func (k Keeper) burnNotBondedTokens(ctx sdk.Context, amt math.Int) error {
|
||||
func (k Keeper) burnNotBondedTokens(ctx context.Context, amt math.Int) error {
|
||||
if !amt.IsPositive() {
|
||||
// skip as no coins need to be burned
|
||||
return nil
|
||||
}
|
||||
|
||||
coins := sdk.NewCoins(sdk.NewCoin(k.BondDenom(ctx), amt))
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
coins := sdk.NewCoins(sdk.NewCoin(bondDenom, amt))
|
||||
|
||||
return k.bankKeeper.BurnCoins(ctx, types.NotBondedPoolName, coins)
|
||||
}
|
||||
|
||||
// TotalBondedTokens total staking tokens supply which is bonded
|
||||
func (k Keeper) TotalBondedTokens(ctx sdk.Context) math.Int {
|
||||
func (k Keeper) TotalBondedTokens(ctx context.Context) (math.Int, error) {
|
||||
bondedPool := k.GetBondedPool(ctx)
|
||||
return k.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), k.BondDenom(ctx)).Amount
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
return k.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, nil
|
||||
}
|
||||
|
||||
// StakingTokenSupply staking tokens from the total supply
|
||||
func (k Keeper) StakingTokenSupply(ctx sdk.Context) math.Int {
|
||||
return k.bankKeeper.GetSupply(ctx, k.BondDenom(ctx)).Amount
|
||||
func (k Keeper) StakingTokenSupply(ctx context.Context) (math.Int, error) {
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
return k.bankKeeper.GetSupply(ctx, bondDenom).Amount, nil
|
||||
}
|
||||
|
||||
// BondedRatio the fraction of the staking tokens which are currently bonded
|
||||
func (k Keeper) BondedRatio(ctx sdk.Context) math.LegacyDec {
|
||||
stakeSupply := k.StakingTokenSupply(ctx)
|
||||
if stakeSupply.IsPositive() {
|
||||
return math.LegacyNewDecFromInt(k.TotalBondedTokens(ctx)).QuoInt(stakeSupply)
|
||||
func (k Keeper) BondedRatio(ctx context.Context) (math.LegacyDec, error) {
|
||||
stakeSupply, err := k.StakingTokenSupply(ctx)
|
||||
if err != nil {
|
||||
return math.LegacyZeroDec(), err
|
||||
}
|
||||
|
||||
return math.LegacyZeroDec()
|
||||
if stakeSupply.IsPositive() {
|
||||
totalBonded, err := k.TotalBondedTokens(ctx)
|
||||
if err != nil {
|
||||
return math.LegacyZeroDec(), err
|
||||
}
|
||||
return math.LegacyNewDecFromInt(totalBonded).QuoInt(stakeSupply), nil
|
||||
}
|
||||
|
||||
return math.LegacyZeroDec(), nil
|
||||
}
|
||||
|
||||
@ -1,16 +1,19 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// TokensToConsensusPower - convert input tokens to potential consensus-engine power
|
||||
func (k Keeper) TokensToConsensusPower(ctx sdk.Context, tokens math.Int) int64 {
|
||||
func (k Keeper) TokensToConsensusPower(ctx context.Context, tokens math.Int) int64 {
|
||||
return sdk.TokensToConsensusPower(tokens, k.PowerReduction(ctx))
|
||||
}
|
||||
|
||||
// TokensFromConsensusPower - convert input power to tokens
|
||||
func (k Keeper) TokensFromConsensusPower(ctx sdk.Context, power int64) math.Int {
|
||||
func (k Keeper) TokensFromConsensusPower(ctx context.Context, power int64) math.Int {
|
||||
return sdk.TokensFromConsensusPower(power, k.PowerReduction(ctx))
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -9,97 +11,107 @@ import (
|
||||
|
||||
// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned.
|
||||
func (k Keeper) GetDelegatorValidators(
|
||||
ctx sdk.Context, delegatorAddr sdk.AccAddress, maxRetrieve uint32,
|
||||
) types.Validators {
|
||||
ctx context.Context, delegatorAddr sdk.AccAddress, maxRetrieve uint32,
|
||||
) (types.Validators, error) {
|
||||
validators := make([]types.Validator, maxRetrieve)
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
delegatorPrefixKey := types.GetDelegationsKey(delegatorAddr)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, delegatorPrefixKey) // smallest to largest
|
||||
iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) // smallest to largest
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
i := 0
|
||||
for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() {
|
||||
delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
|
||||
|
||||
validator, found := k.GetValidator(ctx, delegation.GetValidatorAddr())
|
||||
if !found {
|
||||
panic(types.ErrNoValidatorFound)
|
||||
validator, err := k.GetValidator(ctx, delegation.GetValidatorAddr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validators[i] = validator
|
||||
i++
|
||||
}
|
||||
|
||||
return validators[:i] // trim
|
||||
return validators[:i], nil // trim
|
||||
}
|
||||
|
||||
// return a validator that a delegator is bonded to
|
||||
func (k Keeper) GetDelegatorValidator(
|
||||
ctx sdk.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress,
|
||||
ctx context.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress,
|
||||
) (validator types.Validator, err error) {
|
||||
delegation, found := k.GetDelegation(ctx, delegatorAddr, validatorAddr)
|
||||
if !found {
|
||||
return validator, types.ErrNoDelegation
|
||||
delegation, err := k.GetDelegation(ctx, delegatorAddr, validatorAddr)
|
||||
if err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
validator, found = k.GetValidator(ctx, delegation.GetValidatorAddr())
|
||||
if !found {
|
||||
panic(types.ErrNoValidatorFound)
|
||||
}
|
||||
|
||||
return validator, nil
|
||||
return k.GetValidator(ctx, delegation.GetValidatorAddr())
|
||||
}
|
||||
|
||||
// return all delegations for a delegator
|
||||
func (k Keeper) GetAllDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress) []types.Delegation {
|
||||
func (k Keeper) GetAllDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress) ([]types.Delegation, error) {
|
||||
delegations := make([]types.Delegation, 0)
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
delegatorPrefixKey := types.GetDelegationsKey(delegator)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, delegatorPrefixKey) // smallest to largest
|
||||
iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) // smallest to largest
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
i := 0
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
|
||||
for i := 0; iterator.Valid(); iterator.Next() {
|
||||
delegation, err := types.UnmarshalDelegation(k.cdc, iterator.Value())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
delegations = append(delegations, delegation)
|
||||
i++
|
||||
}
|
||||
|
||||
return delegations
|
||||
return delegations, nil
|
||||
}
|
||||
|
||||
// return all unbonding-delegations for a delegator
|
||||
func (k Keeper) GetAllUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress) []types.UnbondingDelegation {
|
||||
func (k Keeper) GetAllUnbondingDelegations(ctx context.Context, delegator sdk.AccAddress) ([]types.UnbondingDelegation, error) {
|
||||
unbondingDelegations := make([]types.UnbondingDelegation, 0)
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
delegatorPrefixKey := types.GetUBDsKey(delegator)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, delegatorPrefixKey) // smallest to largest
|
||||
iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) // smallest to largest
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
for i := 0; iterator.Valid(); iterator.Next() {
|
||||
unbondingDelegation := types.MustUnmarshalUBD(k.cdc, iterator.Value())
|
||||
unbondingDelegation, err := types.UnmarshalUBD(k.cdc, iterator.Value())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
unbondingDelegations = append(unbondingDelegations, unbondingDelegation)
|
||||
i++
|
||||
}
|
||||
|
||||
return unbondingDelegations
|
||||
return unbondingDelegations, nil
|
||||
}
|
||||
|
||||
// return all redelegations for a delegator
|
||||
func (k Keeper) GetAllRedelegations(
|
||||
ctx sdk.Context, delegator sdk.AccAddress, srcValAddress, dstValAddress sdk.ValAddress,
|
||||
) []types.Redelegation {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
ctx context.Context, delegator sdk.AccAddress, srcValAddress, dstValAddress sdk.ValAddress,
|
||||
) ([]types.Redelegation, error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
delegatorPrefixKey := types.GetREDsKey(delegator)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, delegatorPrefixKey) // smallest to largest
|
||||
iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) // smallest to largest
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
srcValFilter := !(srcValAddress.Empty())
|
||||
@ -111,11 +123,11 @@ func (k Keeper) GetAllRedelegations(
|
||||
redelegation := types.MustUnmarshalRED(k.cdc, iterator.Value())
|
||||
valSrcAddr, err := sdk.ValAddressFromBech32(redelegation.ValidatorSrcAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
valDstAddr, err := sdk.ValAddressFromBech32(redelegation.ValidatorDstAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
if srcValFilter && !(srcValAddress.Equals(valSrcAddr)) {
|
||||
continue
|
||||
@ -128,5 +140,5 @@ func (k Keeper) GetAllRedelegations(
|
||||
redelegations = append(redelegations, redelegation)
|
||||
}
|
||||
|
||||
return redelegations
|
||||
return redelegations, nil
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
@ -30,11 +32,12 @@ import (
|
||||
//
|
||||
// Infraction was committed at the current height or at a past height,
|
||||
// not at a height in the future
|
||||
func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec) math.Int {
|
||||
func (k Keeper) Slash(ctx context.Context, consAddr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec) (math.Int, error) {
|
||||
logger := k.Logger(ctx)
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
|
||||
if slashFactor.IsNegative() {
|
||||
panic(fmt.Errorf("attempted to slash with a negative slash factor: %v", slashFactor))
|
||||
return math.NewInt(0), fmt.Errorf("attempted to slash with a negative slash factor: %v", slashFactor)
|
||||
}
|
||||
|
||||
// Amount of slashing = slash slashFactor * power at time of infraction
|
||||
@ -44,8 +47,8 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||
|
||||
// ref https://github.com/cosmos/cosmos-sdk/issues/1348
|
||||
|
||||
validator, found := k.GetValidatorByConsAddr(ctx, consAddr)
|
||||
if !found {
|
||||
validator, err := k.GetValidatorByConsAddr(ctx, consAddr)
|
||||
if errors.Is(err, types.ErrNoValidatorFound) {
|
||||
// If not found, the validator must have been overslashed and removed - so we don't need to do anything
|
||||
// NOTE: Correctness dependent on invariant that unbonding delegations / redelegations must also have been completely
|
||||
// slashed in this case - which we don't explicitly check, but should be true.
|
||||
@ -54,12 +57,14 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||
"WARNING: ignored attempt to slash a nonexistent validator; we recommend you investigate immediately",
|
||||
"validator", consAddr.String(),
|
||||
)
|
||||
return math.NewInt(0)
|
||||
return math.NewInt(0), nil
|
||||
} else if err != nil {
|
||||
return math.NewInt(0), err
|
||||
}
|
||||
|
||||
// should not be slashing an unbonded validator
|
||||
if validator.IsUnbonded() {
|
||||
panic(fmt.Sprintf("should not be slashing unbonded validator: %s", validator.GetOperator()))
|
||||
return math.NewInt(0), fmt.Errorf("should not be slashing unbonded validator: %s", validator.GetOperator())
|
||||
}
|
||||
|
||||
operatorAddress := validator.GetOperator()
|
||||
@ -75,13 +80,13 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||
remainingSlashAmount := slashAmount
|
||||
|
||||
switch {
|
||||
case infractionHeight > ctx.BlockHeight():
|
||||
case infractionHeight > sdkCtx.BlockHeight():
|
||||
// Can't slash infractions in the future
|
||||
panic(fmt.Sprintf(
|
||||
return math.NewInt(0), fmt.Errorf(
|
||||
"impossible attempt to slash future infraction at height %d but we are at height %d",
|
||||
infractionHeight, ctx.BlockHeight()))
|
||||
infractionHeight, sdkCtx.BlockHeight())
|
||||
|
||||
case infractionHeight == ctx.BlockHeight():
|
||||
case infractionHeight == sdkCtx.BlockHeight():
|
||||
// Special-case slash at current height for efficiency - we don't need to
|
||||
// look through unbonding delegations or redelegations.
|
||||
logger.Info(
|
||||
@ -89,11 +94,18 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||
"height", infractionHeight,
|
||||
)
|
||||
|
||||
case infractionHeight < ctx.BlockHeight():
|
||||
case infractionHeight < sdkCtx.BlockHeight():
|
||||
// Iterate through unbonding delegations from slashed validator
|
||||
unbondingDelegations := k.GetUnbondingDelegationsFromValidator(ctx, operatorAddress)
|
||||
unbondingDelegations, err := k.GetUnbondingDelegationsFromValidator(ctx, operatorAddress)
|
||||
if err != nil {
|
||||
return math.NewInt(0), err
|
||||
}
|
||||
|
||||
for _, unbondingDelegation := range unbondingDelegations {
|
||||
amountSlashed := k.SlashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor)
|
||||
amountSlashed, err := k.SlashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor)
|
||||
if err != nil {
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
if amountSlashed.IsZero() {
|
||||
continue
|
||||
}
|
||||
@ -102,9 +114,17 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||
}
|
||||
|
||||
// Iterate through redelegations from slashed source validator
|
||||
redelegations := k.GetRedelegationsFromSrcValidator(ctx, operatorAddress)
|
||||
redelegations, err := k.GetRedelegationsFromSrcValidator(ctx, operatorAddress)
|
||||
if err != nil {
|
||||
return math.NewInt(0), err
|
||||
}
|
||||
|
||||
for _, redelegation := range redelegations {
|
||||
amountSlashed := k.SlashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor)
|
||||
amountSlashed, err := k.SlashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor)
|
||||
if err != nil {
|
||||
return math.NewInt(0), err
|
||||
}
|
||||
|
||||
if amountSlashed.IsZero() {
|
||||
continue
|
||||
}
|
||||
@ -132,16 +152,19 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||
|
||||
// Deduct from validator's bonded tokens and update the validator.
|
||||
// Burn the slashed tokens from the pool account and decrease the total supply.
|
||||
validator = k.RemoveValidatorTokens(ctx, validator, tokensToBurn)
|
||||
validator, err = k.RemoveValidatorTokens(ctx, validator, tokensToBurn)
|
||||
if err != nil {
|
||||
return math.NewInt(0), err
|
||||
}
|
||||
|
||||
switch validator.GetStatus() {
|
||||
case types.Bonded:
|
||||
if err := k.burnBondedTokens(ctx, tokensToBurn); err != nil {
|
||||
panic(err)
|
||||
return math.NewInt(0), err
|
||||
}
|
||||
case types.Unbonding, types.Unbonded:
|
||||
if err := k.burnNotBondedTokens(ctx, tokensToBurn); err != nil {
|
||||
panic(err)
|
||||
return math.NewInt(0), err
|
||||
}
|
||||
default:
|
||||
panic("invalid validator status")
|
||||
@ -153,28 +176,35 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||
"slash_factor", slashFactor.String(),
|
||||
"burned", tokensToBurn,
|
||||
)
|
||||
return tokensToBurn
|
||||
return tokensToBurn, nil
|
||||
}
|
||||
|
||||
// SlashWithInfractionReason implementation doesn't require the infraction (types.Infraction) to work but is required by Interchain Security.
|
||||
func (k Keeper) SlashWithInfractionReason(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec, _ types.Infraction) math.Int {
|
||||
func (k Keeper) SlashWithInfractionReason(ctx context.Context, consAddr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec, _ types.Infraction) (math.Int, error) {
|
||||
return k.Slash(ctx, consAddr, infractionHeight, power, slashFactor)
|
||||
}
|
||||
|
||||
// jail a validator
|
||||
func (k Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress) {
|
||||
func (k Keeper) Jail(ctx context.Context, consAddr sdk.ConsAddress) error {
|
||||
validator := k.mustGetValidatorByConsAddr(ctx, consAddr)
|
||||
k.jailValidator(ctx, validator)
|
||||
if err := k.jailValidator(ctx, validator); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := k.Logger(ctx)
|
||||
logger.Info("validator jailed", "validator", consAddr)
|
||||
return nil
|
||||
}
|
||||
|
||||
// unjail a validator
|
||||
func (k Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress) {
|
||||
func (k Keeper) Unjail(ctx context.Context, consAddr sdk.ConsAddress) error {
|
||||
validator := k.mustGetValidatorByConsAddr(ctx, consAddr)
|
||||
k.unjailValidator(ctx, validator)
|
||||
if err := k.unjailValidator(ctx, validator); err != nil {
|
||||
return err
|
||||
}
|
||||
logger := k.Logger(ctx)
|
||||
logger.Info("validator un-jailed", "validator", consAddr)
|
||||
return nil
|
||||
}
|
||||
|
||||
// slash an unbonding delegation and update the pool
|
||||
@ -182,10 +212,11 @@ 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 context.Context, unbondingDelegation types.UnbondingDelegation,
|
||||
infractionHeight int64, slashFactor math.LegacyDec,
|
||||
) (totalSlashAmount math.Int) {
|
||||
now := ctx.BlockHeader().Time
|
||||
) (totalSlashAmount math.Int, err error) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
now := sdkCtx.BlockHeader().Time
|
||||
totalSlashAmount = math.ZeroInt()
|
||||
burnedAmount := math.ZeroInt()
|
||||
|
||||
@ -220,14 +251,16 @@ func (k Keeper) SlashUnbondingDelegation(ctx sdk.Context, unbondingDelegation ty
|
||||
burnedAmount = burnedAmount.Add(unbondingSlashAmount)
|
||||
entry.Balance = entry.Balance.Sub(unbondingSlashAmount)
|
||||
unbondingDelegation.Entries[i] = entry
|
||||
k.SetUnbondingDelegation(ctx, unbondingDelegation)
|
||||
if err = k.SetUnbondingDelegation(ctx, unbondingDelegation); err != nil {
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
}
|
||||
|
||||
if err := k.burnNotBondedTokens(ctx, burnedAmount); err != nil {
|
||||
panic(err)
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
|
||||
return totalSlashAmount
|
||||
return totalSlashAmount, nil
|
||||
}
|
||||
|
||||
// slash a redelegation and update the pool
|
||||
@ -236,10 +269,11 @@ 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 context.Context, srcValidator types.Validator, redelegation types.Redelegation,
|
||||
infractionHeight int64, slashFactor math.LegacyDec,
|
||||
) (totalSlashAmount math.Int) {
|
||||
now := ctx.BlockHeader().Time
|
||||
) (totalSlashAmount math.Int, err error) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
now := sdkCtx.BlockHeader().Time
|
||||
totalSlashAmount = math.ZeroInt()
|
||||
bondedBurnedAmount, notBondedBurnedAmount := math.ZeroInt(), math.ZeroInt()
|
||||
|
||||
@ -276,8 +310,8 @@ func (k Keeper) SlashRedelegation(ctx sdk.Context, srcValidator types.Validator,
|
||||
panic(err)
|
||||
}
|
||||
|
||||
delegation, found := k.GetDelegation(ctx, delegatorAddress, valDstAddr)
|
||||
if !found {
|
||||
delegation, err := k.GetDelegation(ctx, delegatorAddress, valDstAddr)
|
||||
if err != nil {
|
||||
// If deleted, delegation has zero shares, and we can't unbond any more
|
||||
continue
|
||||
}
|
||||
@ -288,12 +322,12 @@ func (k Keeper) SlashRedelegation(ctx sdk.Context, srcValidator types.Validator,
|
||||
|
||||
tokensToBurn, err := k.Unbond(ctx, delegatorAddress, valDstAddr, sharesToUnbond)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error unbonding delegator: %v", err))
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
|
||||
dstValidator, found := k.GetValidator(ctx, valDstAddr)
|
||||
if !found {
|
||||
panic("destination validator not found")
|
||||
dstValidator, err := k.GetValidator(ctx, valDstAddr)
|
||||
if err != nil {
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
|
||||
// tokens of a redelegation currently live in the destination validator
|
||||
@ -309,12 +343,12 @@ func (k Keeper) SlashRedelegation(ctx sdk.Context, srcValidator types.Validator,
|
||||
}
|
||||
|
||||
if err := k.burnBondedTokens(ctx, bondedBurnedAmount); err != nil {
|
||||
panic(err)
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
|
||||
if err := k.burnNotBondedTokens(ctx, notBondedBurnedAmount); err != nil {
|
||||
panic(err)
|
||||
return math.ZeroInt(), err
|
||||
}
|
||||
|
||||
return totalSlashAmount
|
||||
return totalSlashAmount, nil
|
||||
}
|
||||
|
||||
@ -15,36 +15,36 @@ func (s *KeeperTestSuite) TestRevocation() {
|
||||
validator := testutil.NewValidator(s.T(), valAddr, PKs[0])
|
||||
|
||||
// initial state
|
||||
keeper.SetValidator(ctx, validator)
|
||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||
val, found := keeper.GetValidator(ctx, valAddr)
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetValidator(ctx, validator))
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
|
||||
val, err := keeper.GetValidator(ctx, valAddr)
|
||||
require.NoError(err)
|
||||
require.False(val.IsJailed())
|
||||
|
||||
// test jail
|
||||
keeper.Jail(ctx, consAddr)
|
||||
val, found = keeper.GetValidator(ctx, valAddr)
|
||||
require.True(found)
|
||||
require.NoError(keeper.Jail(ctx, consAddr))
|
||||
val, err = keeper.GetValidator(ctx, valAddr)
|
||||
require.NoError(err)
|
||||
require.True(val.IsJailed())
|
||||
|
||||
// test unjail
|
||||
keeper.Unjail(ctx, consAddr)
|
||||
val, found = keeper.GetValidator(ctx, valAddr)
|
||||
require.True(found)
|
||||
require.NoError(keeper.Unjail(ctx, consAddr))
|
||||
val, err = keeper.GetValidator(ctx, valAddr)
|
||||
require.NoError(err)
|
||||
require.False(val.IsJailed())
|
||||
}
|
||||
|
||||
// tests Slash at a future height (must panic)
|
||||
// tests Slash at a future height (must error)
|
||||
func (s *KeeperTestSuite) TestSlashAtFutureHeight() {
|
||||
ctx, keeper := s.ctx, s.stakingKeeper
|
||||
require := s.Require()
|
||||
|
||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||
validator := testutil.NewValidator(s.T(), sdk.ValAddress(PKs[0].Address().Bytes()), PKs[0])
|
||||
keeper.SetValidator(ctx, validator)
|
||||
err := keeper.SetValidatorByConsAddr(ctx, validator)
|
||||
require.NoError(err)
|
||||
require.NoError(keeper.SetValidator(ctx, validator))
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
|
||||
|
||||
fraction := sdk.NewDecWithPrec(5, 1)
|
||||
require.Panics(func() { keeper.Slash(ctx, consAddr, 1, 10, fraction) })
|
||||
_, err := keeper.Slash(ctx, consAddr, 1, 10, fraction)
|
||||
require.Error(err)
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package keeper // noalias
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
@ -10,20 +11,30 @@ import (
|
||||
)
|
||||
|
||||
// does a certain by-power index record exist
|
||||
func ValidatorByPowerIndexExists(ctx sdk.Context, keeper *Keeper, power []byte) bool {
|
||||
store := ctx.KVStore(keeper.storeKey)
|
||||
return store.Has(power)
|
||||
func ValidatorByPowerIndexExists(ctx context.Context, keeper *Keeper, power []byte) bool {
|
||||
store := keeper.storeService.OpenKVStore(ctx)
|
||||
has, err := store.Has(power)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return has
|
||||
}
|
||||
|
||||
// update validator for testing
|
||||
func TestingUpdateValidator(keeper *Keeper, ctx sdk.Context, validator types.Validator, apply bool) types.Validator {
|
||||
keeper.SetValidator(ctx, validator)
|
||||
err := keeper.SetValidator(ctx, validator)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Remove any existing power key for validator.
|
||||
store := ctx.KVStore(keeper.storeKey)
|
||||
store := keeper.storeService.OpenKVStore(ctx)
|
||||
deleted := false
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, types.ValidatorsByPowerIndexKey)
|
||||
iterator, err := store.Iterator(types.ValidatorsByPowerIndexKey, storetypes.PrefixEndBytes(types.ValidatorsByPowerIndexKey))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
@ -35,23 +46,27 @@ func TestingUpdateValidator(keeper *Keeper, ctx sdk.Context, validator types.Val
|
||||
deleted = true
|
||||
}
|
||||
|
||||
store.Delete(iterator.Key())
|
||||
if err = store.Delete(iterator.Key()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keeper.SetValidatorByPowerIndex(ctx, validator)
|
||||
if err = keeper.SetValidatorByPowerIndex(ctx, validator); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if !apply {
|
||||
ctx, _ = ctx.CacheContext()
|
||||
}
|
||||
_, err := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
_, err = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
validator, found := keeper.GetValidator(ctx, validator.GetOperator())
|
||||
if !found {
|
||||
panic("validator expected but not found")
|
||||
validator, err = keeper.GetValidator(ctx, validator.GetOperator())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return validator
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
@ -10,9 +11,13 @@ import (
|
||||
)
|
||||
|
||||
// IncrementUnbondingID increments and returns a unique ID for an unbonding operation
|
||||
func (k Keeper) IncrementUnbondingID(ctx sdk.Context) (unbondingID uint64) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get(types.UnbondingIDKey)
|
||||
func (k Keeper) IncrementUnbondingID(ctx context.Context) (unbondingID uint64, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz, err := store.Get(types.UnbondingIDKey)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if bz != nil {
|
||||
unbondingID = binary.BigEndian.Uint64(bz)
|
||||
}
|
||||
@ -23,203 +28,239 @@ func (k Keeper) IncrementUnbondingID(ctx sdk.Context) (unbondingID uint64) {
|
||||
bz = make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(bz, unbondingID)
|
||||
|
||||
store.Set(types.UnbondingIDKey, bz)
|
||||
if err = store.Set(types.UnbondingIDKey, bz); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return unbondingID
|
||||
return unbondingID, err
|
||||
}
|
||||
|
||||
// DeleteUnbondingIndex removes a mapping from UnbondingId to unbonding operation
|
||||
func (k Keeper) DeleteUnbondingIndex(ctx sdk.Context, id uint64) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(types.GetUnbondingIndexKey(id))
|
||||
func (k Keeper) DeleteUnbondingIndex(ctx context.Context, id uint64) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
return store.Delete(types.GetUnbondingIndexKey(id))
|
||||
}
|
||||
|
||||
func (k Keeper) GetUnbondingType(ctx sdk.Context, id uint64) (unbondingType types.UnbondingType, found bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetUnbondingType(ctx context.Context, id uint64) (unbondingType types.UnbondingType, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
|
||||
bz := store.Get(types.GetUnbondingTypeKey(id))
|
||||
if bz == nil {
|
||||
return unbondingType, false
|
||||
bz, err := store.Get(types.GetUnbondingTypeKey(id))
|
||||
if err != nil {
|
||||
return unbondingType, err
|
||||
}
|
||||
|
||||
return types.UnbondingType(binary.BigEndian.Uint64(bz)), true
|
||||
if bz == nil {
|
||||
return unbondingType, types.ErrNoUnbondingType
|
||||
}
|
||||
|
||||
return types.UnbondingType(binary.BigEndian.Uint64(bz)), nil
|
||||
}
|
||||
|
||||
func (k Keeper) SetUnbondingType(ctx sdk.Context, id uint64, unbondingType types.UnbondingType) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) SetUnbondingType(ctx context.Context, id uint64, unbondingType types.UnbondingType) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
|
||||
// Convert into bytes for storage
|
||||
bz := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(bz, uint64(unbondingType))
|
||||
|
||||
store.Set(types.GetUnbondingTypeKey(id), bz)
|
||||
return store.Set(types.GetUnbondingTypeKey(id), bz)
|
||||
}
|
||||
|
||||
// GetUnbondingDelegationByUnbondingID returns a unbonding delegation that has an unbonding delegation entry with a certain ID
|
||||
func (k Keeper) GetUnbondingDelegationByUnbondingID(ctx sdk.Context, id uint64) (ubd types.UnbondingDelegation, found bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetUnbondingDelegationByUnbondingID(ctx context.Context, id uint64) (ubd types.UnbondingDelegation, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
|
||||
ubdKey, err := store.Get(types.GetUnbondingIndexKey(id))
|
||||
if err != nil {
|
||||
return types.UnbondingDelegation{}, err
|
||||
}
|
||||
|
||||
ubdKey := store.Get(types.GetUnbondingIndexKey(id))
|
||||
if ubdKey == nil {
|
||||
return types.UnbondingDelegation{}, false
|
||||
return types.UnbondingDelegation{}, types.ErrNoUnbondingDelegation
|
||||
}
|
||||
|
||||
value, err := store.Get(ubdKey)
|
||||
if err != nil {
|
||||
return types.UnbondingDelegation{}, err
|
||||
}
|
||||
|
||||
value := store.Get(ubdKey)
|
||||
if value == nil {
|
||||
return types.UnbondingDelegation{}, false
|
||||
return types.UnbondingDelegation{}, types.ErrNoUnbondingDelegation
|
||||
}
|
||||
|
||||
ubd, err := types.UnmarshalUBD(k.cdc, value)
|
||||
ubd, err = types.UnmarshalUBD(k.cdc, value)
|
||||
// An error here means that what we got wasn't the right type
|
||||
if err != nil {
|
||||
return types.UnbondingDelegation{}, false
|
||||
return types.UnbondingDelegation{}, err
|
||||
}
|
||||
|
||||
return ubd, true
|
||||
return ubd, nil
|
||||
}
|
||||
|
||||
// GetRedelegationByUnbondingID returns a unbonding delegation that has an unbonding delegation entry with a certain ID
|
||||
func (k Keeper) GetRedelegationByUnbondingID(ctx sdk.Context, id uint64) (red types.Redelegation, found bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetRedelegationByUnbondingID(ctx context.Context, id uint64) (red types.Redelegation, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
|
||||
redKey, err := store.Get(types.GetUnbondingIndexKey(id))
|
||||
if err != nil {
|
||||
return types.Redelegation{}, err
|
||||
}
|
||||
|
||||
redKey := store.Get(types.GetUnbondingIndexKey(id))
|
||||
if redKey == nil {
|
||||
return types.Redelegation{}, false
|
||||
return types.Redelegation{}, types.ErrNoRedelegation
|
||||
}
|
||||
|
||||
value, err := store.Get(redKey)
|
||||
if err != nil {
|
||||
return types.Redelegation{}, err
|
||||
}
|
||||
|
||||
value := store.Get(redKey)
|
||||
if value == nil {
|
||||
return types.Redelegation{}, false
|
||||
return types.Redelegation{}, types.ErrNoRedelegation
|
||||
}
|
||||
|
||||
red, err := types.UnmarshalRED(k.cdc, value)
|
||||
red, err = types.UnmarshalRED(k.cdc, value)
|
||||
// An error here means that what we got wasn't the right type
|
||||
if err != nil {
|
||||
return types.Redelegation{}, false
|
||||
return types.Redelegation{}, err
|
||||
}
|
||||
|
||||
return red, true
|
||||
return red, nil
|
||||
}
|
||||
|
||||
// GetValidatorByUnbondingID returns the validator that is unbonding with a certain unbonding op ID
|
||||
func (k Keeper) GetValidatorByUnbondingID(ctx sdk.Context, id uint64) (val types.Validator, found bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetValidatorByUnbondingID(ctx context.Context, id uint64) (val types.Validator, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
|
||||
valKey, err := store.Get(types.GetUnbondingIndexKey(id))
|
||||
if err != nil {
|
||||
return types.Validator{}, err
|
||||
}
|
||||
|
||||
valKey := store.Get(types.GetUnbondingIndexKey(id))
|
||||
if valKey == nil {
|
||||
return types.Validator{}, false
|
||||
return types.Validator{}, types.ErrNoValidatorFound
|
||||
}
|
||||
|
||||
value, err := store.Get(valKey)
|
||||
if err != nil {
|
||||
return types.Validator{}, err
|
||||
}
|
||||
|
||||
value := store.Get(valKey)
|
||||
if value == nil {
|
||||
return types.Validator{}, false
|
||||
return types.Validator{}, types.ErrNoValidatorFound
|
||||
}
|
||||
|
||||
val, err := types.UnmarshalValidator(k.cdc, value)
|
||||
val, err = types.UnmarshalValidator(k.cdc, value)
|
||||
// An error here means that what we got wasn't the right type
|
||||
if err != nil {
|
||||
return types.Validator{}, false
|
||||
return types.Validator{}, err
|
||||
}
|
||||
|
||||
return val, true
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// SetUnbondingDelegationByUnbondingID sets an index to look up an UnbondingDelegation by the unbondingID of an UnbondingDelegationEntry that it contains
|
||||
// Note, it does not set the unbonding delegation itself, use SetUnbondingDelegation(ctx, ubd) for that
|
||||
func (k Keeper) SetUnbondingDelegationByUnbondingID(ctx sdk.Context, ubd types.UnbondingDelegation, id uint64) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) SetUnbondingDelegationByUnbondingID(ctx context.Context, ubd types.UnbondingDelegation, id uint64) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(ubd.DelegatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
valAddr, err := sdk.ValAddressFromBech32(ubd.ValidatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
ubdKey := types.GetUBDKey(delAddr, valAddr)
|
||||
store.Set(types.GetUnbondingIndexKey(id), ubdKey)
|
||||
if err = store.Set(types.GetUnbondingIndexKey(id), ubdKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set unbonding type so that we know how to deserialize it later
|
||||
k.SetUnbondingType(ctx, id, types.UnbondingType_UnbondingDelegation)
|
||||
return k.SetUnbondingType(ctx, id, types.UnbondingType_UnbondingDelegation)
|
||||
}
|
||||
|
||||
// SetRedelegationByUnbondingID sets an index to look up an Redelegation by the unbondingID of an RedelegationEntry that it contains
|
||||
// Note, it does not set the redelegation itself, use SetRedelegation(ctx, red) for that
|
||||
func (k Keeper) SetRedelegationByUnbondingID(ctx sdk.Context, red types.Redelegation, id uint64) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) SetRedelegationByUnbondingID(ctx context.Context, red types.Redelegation, id uint64) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(red.DelegatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
valSrcAddr, err := sdk.ValAddressFromBech32(red.ValidatorSrcAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
valDstAddr, err := sdk.ValAddressFromBech32(red.ValidatorDstAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
redKey := types.GetREDKey(delAddr, valSrcAddr, valDstAddr)
|
||||
store.Set(types.GetUnbondingIndexKey(id), redKey)
|
||||
if err = store.Set(types.GetUnbondingIndexKey(id), redKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set unbonding type so that we know how to deserialize it later
|
||||
k.SetUnbondingType(ctx, id, types.UnbondingType_Redelegation)
|
||||
return k.SetUnbondingType(ctx, id, types.UnbondingType_Redelegation)
|
||||
}
|
||||
|
||||
// SetValidatorByUnbondingID sets an index to look up a Validator by the unbondingID corresponding to its current unbonding
|
||||
// Note, it does not set the validator itself, use SetValidator(ctx, val) for that
|
||||
func (k Keeper) SetValidatorByUnbondingID(ctx sdk.Context, val types.Validator, id uint64) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) SetValidatorByUnbondingID(ctx context.Context, val types.Validator, id uint64) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
|
||||
valAddr, err := sdk.ValAddressFromBech32(val.OperatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
valKey := types.GetValidatorKey(valAddr)
|
||||
store.Set(types.GetUnbondingIndexKey(id), valKey)
|
||||
if err = store.Set(types.GetUnbondingIndexKey(id), valKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set unbonding type so that we know how to deserialize it later
|
||||
k.SetUnbondingType(ctx, id, types.UnbondingType_ValidatorUnbonding)
|
||||
return k.SetUnbondingType(ctx, id, types.UnbondingType_ValidatorUnbonding)
|
||||
}
|
||||
|
||||
// unbondingDelegationEntryArrayIndex and redelegationEntryArrayIndex are utilities to find
|
||||
// at which position in the Entries array the entry with a given id is
|
||||
func unbondingDelegationEntryArrayIndex(ubd types.UnbondingDelegation, id uint64) (index int, found bool) {
|
||||
func unbondingDelegationEntryArrayIndex(ubd types.UnbondingDelegation, id uint64) (index int, err error) {
|
||||
for i, entry := range ubd.Entries {
|
||||
// we find the entry with the right ID
|
||||
if entry.UnbondingId == id {
|
||||
return i, true
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, false
|
||||
return 0, types.ErrNoUnbondingDelegation
|
||||
}
|
||||
|
||||
func redelegationEntryArrayIndex(red types.Redelegation, id uint64) (index int, found bool) {
|
||||
func redelegationEntryArrayIndex(red types.Redelegation, id uint64) (index int, err error) {
|
||||
for i, entry := range red.Entries {
|
||||
// we find the entry with the right ID
|
||||
if entry.UnbondingId == id {
|
||||
return i, true
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, false
|
||||
return 0, types.ErrNoRedelegation
|
||||
}
|
||||
|
||||
// UnbondingCanComplete allows a stopped unbonding operation, such as an
|
||||
// unbonding delegation, a redelegation, or a validator unbonding to complete.
|
||||
// In order for the unbonding operation with `id` to eventually complete, every call
|
||||
// to PutUnbondingOnHold(id) must be matched by a call to UnbondingCanComplete(id).
|
||||
func (k Keeper) UnbondingCanComplete(ctx sdk.Context, id uint64) error {
|
||||
unbondingType, found := k.GetUnbondingType(ctx, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
func (k Keeper) UnbondingCanComplete(ctx context.Context, id uint64) error {
|
||||
unbondingType, err := k.GetUnbondingType(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch unbondingType {
|
||||
@ -242,15 +283,15 @@ func (k Keeper) UnbondingCanComplete(ctx sdk.Context, id uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k Keeper) unbondingDelegationEntryCanComplete(ctx sdk.Context, id uint64) error {
|
||||
ubd, found := k.GetUnbondingDelegationByUnbondingID(ctx, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
func (k Keeper) unbondingDelegationEntryCanComplete(ctx context.Context, id uint64) error {
|
||||
ubd, err := k.GetUnbondingDelegationByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i, found := unbondingDelegationEntryArrayIndex(ubd, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
i, err := unbondingDelegationEntryArrayIndex(ubd, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The entry must be on hold
|
||||
@ -263,15 +304,19 @@ func (k Keeper) unbondingDelegationEntryCanComplete(ctx sdk.Context, id uint64)
|
||||
}
|
||||
ubd.Entries[i].UnbondingOnHoldRefCount--
|
||||
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
// Check if entry is matured.
|
||||
if !ubd.Entries[i].OnHold() && ubd.Entries[i].IsMature(ctx.BlockHeader().Time) {
|
||||
if !ubd.Entries[i].OnHold() && ubd.Entries[i].IsMature(sdkCtx.BlockHeader().Time) {
|
||||
// If matured, complete it.
|
||||
delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(ubd.DelegatorAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bondDenom := k.GetParams(ctx).BondDenom
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// track undelegation only when remaining or truncated shares are non-zero
|
||||
if !ubd.Entries[i].Balance.IsZero() {
|
||||
@ -286,29 +331,30 @@ func (k Keeper) unbondingDelegationEntryCanComplete(ctx sdk.Context, id uint64)
|
||||
// Remove entry
|
||||
ubd.RemoveEntry(int64(i))
|
||||
// Remove from the UnbondingIndex
|
||||
k.DeleteUnbondingIndex(ctx, id)
|
||||
err = k.DeleteUnbondingIndex(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// set the unbonding delegation or remove it if there are no more entries
|
||||
if len(ubd.Entries) == 0 {
|
||||
k.RemoveUnbondingDelegation(ctx, ubd)
|
||||
} else {
|
||||
k.SetUnbondingDelegation(ctx, ubd)
|
||||
return k.RemoveUnbondingDelegation(ctx, ubd)
|
||||
}
|
||||
|
||||
// Successfully completed unbonding
|
||||
return nil
|
||||
return k.SetUnbondingDelegation(ctx, ubd)
|
||||
}
|
||||
|
||||
func (k Keeper) redelegationEntryCanComplete(ctx sdk.Context, id uint64) error {
|
||||
red, found := k.GetRedelegationByUnbondingID(ctx, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
func (k Keeper) redelegationEntryCanComplete(ctx context.Context, id uint64) error {
|
||||
red, err := k.GetRedelegationByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i, found := redelegationEntryArrayIndex(red, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
i, err := redelegationEntryArrayIndex(red, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The entry must be on hold
|
||||
@ -321,29 +367,29 @@ func (k Keeper) redelegationEntryCanComplete(ctx sdk.Context, id uint64) error {
|
||||
}
|
||||
red.Entries[i].UnbondingOnHoldRefCount--
|
||||
|
||||
if !red.Entries[i].OnHold() && red.Entries[i].IsMature(ctx.BlockHeader().Time) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
if !red.Entries[i].OnHold() && red.Entries[i].IsMature(sdkCtx.BlockHeader().Time) {
|
||||
// If matured, complete it.
|
||||
// Remove entry
|
||||
red.RemoveEntry(int64(i))
|
||||
// Remove from the Unbonding index
|
||||
k.DeleteUnbondingIndex(ctx, id)
|
||||
if err = k.DeleteUnbondingIndex(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// set the redelegation or remove it if there are no more entries
|
||||
if len(red.Entries) == 0 {
|
||||
k.RemoveRedelegation(ctx, red)
|
||||
} else {
|
||||
k.SetRedelegation(ctx, red)
|
||||
return k.RemoveRedelegation(ctx, red)
|
||||
}
|
||||
|
||||
// Successfully completed unbonding
|
||||
return nil
|
||||
return k.SetRedelegation(ctx, red)
|
||||
}
|
||||
|
||||
func (k Keeper) validatorUnbondingCanComplete(ctx sdk.Context, id uint64) error {
|
||||
val, found := k.GetValidatorByUnbondingID(ctx, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
func (k Keeper) validatorUnbondingCanComplete(ctx context.Context, id uint64) error {
|
||||
val, err := k.GetValidatorByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.UnbondingOnHoldRefCount <= 0 {
|
||||
@ -354,19 +400,17 @@ func (k Keeper) validatorUnbondingCanComplete(ctx sdk.Context, id uint64) error
|
||||
)
|
||||
}
|
||||
val.UnbondingOnHoldRefCount--
|
||||
k.SetValidator(ctx, val)
|
||||
|
||||
return nil
|
||||
return k.SetValidator(ctx, val)
|
||||
}
|
||||
|
||||
// PutUnbondingOnHold allows an external module to stop an unbonding operation,
|
||||
// such as an unbonding delegation, a redelegation, or a validator unbonding.
|
||||
// In order for the unbonding operation with `id` to eventually complete, every call
|
||||
// to PutUnbondingOnHold(id) must be matched by a call to UnbondingCanComplete(id).
|
||||
func (k Keeper) PutUnbondingOnHold(ctx sdk.Context, id uint64) error {
|
||||
unbondingType, found := k.GetUnbondingType(ctx, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
func (k Keeper) PutUnbondingOnHold(ctx context.Context, id uint64) error {
|
||||
unbondingType, err := k.GetUnbondingType(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch unbondingType {
|
||||
case types.UnbondingType_UnbondingDelegation:
|
||||
@ -388,48 +432,42 @@ func (k Keeper) PutUnbondingOnHold(ctx sdk.Context, id uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k Keeper) putUnbondingDelegationEntryOnHold(ctx sdk.Context, id uint64) error {
|
||||
ubd, found := k.GetUnbondingDelegationByUnbondingID(ctx, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
func (k Keeper) putUnbondingDelegationEntryOnHold(ctx context.Context, id uint64) error {
|
||||
ubd, err := k.GetUnbondingDelegationByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i, found := unbondingDelegationEntryArrayIndex(ubd, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
i, err := unbondingDelegationEntryArrayIndex(ubd, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ubd.Entries[i].UnbondingOnHoldRefCount++
|
||||
k.SetUnbondingDelegation(ctx, ubd)
|
||||
|
||||
return nil
|
||||
return k.SetUnbondingDelegation(ctx, ubd)
|
||||
}
|
||||
|
||||
func (k Keeper) putRedelegationEntryOnHold(ctx sdk.Context, id uint64) error {
|
||||
red, found := k.GetRedelegationByUnbondingID(ctx, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
func (k Keeper) putRedelegationEntryOnHold(ctx context.Context, id uint64) error {
|
||||
red, err := k.GetRedelegationByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i, found := redelegationEntryArrayIndex(red, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
i, err := redelegationEntryArrayIndex(red, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
red.Entries[i].UnbondingOnHoldRefCount++
|
||||
k.SetRedelegation(ctx, red)
|
||||
|
||||
return nil
|
||||
return k.SetRedelegation(ctx, red)
|
||||
}
|
||||
|
||||
func (k Keeper) putValidatorOnHold(ctx sdk.Context, id uint64) error {
|
||||
val, found := k.GetValidatorByUnbondingID(ctx, id)
|
||||
if !found {
|
||||
return types.ErrUnbondingNotFound
|
||||
func (k Keeper) putValidatorOnHold(ctx context.Context, id uint64) error {
|
||||
val, err := k.GetValidatorByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.UnbondingOnHoldRefCount++
|
||||
k.SetValidator(ctx, val)
|
||||
|
||||
return nil
|
||||
return k.SetValidator(ctx, val)
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
@ -11,11 +12,14 @@ import (
|
||||
|
||||
func (s *KeeperTestSuite) TestIncrementUnbondingID() {
|
||||
for i := 1; i < 10; i++ {
|
||||
s.Require().Equal(uint64(i), s.stakingKeeper.IncrementUnbondingID(s.ctx))
|
||||
id, err := s.stakingKeeper.IncrementUnbondingID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(uint64(i), id)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestUnbondingTypeAccessors() {
|
||||
require := s.Require()
|
||||
cases := []struct {
|
||||
exists bool
|
||||
name string
|
||||
@ -40,15 +44,15 @@ func (s *KeeperTestSuite) TestUnbondingTypeAccessors() {
|
||||
for i, tc := range cases {
|
||||
s.Run(tc.name, func() {
|
||||
if tc.exists {
|
||||
s.stakingKeeper.SetUnbondingType(s.ctx, uint64(i), tc.expected)
|
||||
require.NoError(s.stakingKeeper.SetUnbondingType(s.ctx, uint64(i), tc.expected))
|
||||
}
|
||||
|
||||
unbondingType, found := s.stakingKeeper.GetUnbondingType(s.ctx, uint64(i))
|
||||
unbondingType, err := s.stakingKeeper.GetUnbondingType(s.ctx, uint64(i))
|
||||
if tc.exists {
|
||||
s.Require().True(found)
|
||||
s.Require().Equal(tc.expected, unbondingType)
|
||||
require.NoError(err)
|
||||
require.Equal(tc.expected, unbondingType)
|
||||
} else {
|
||||
s.Require().False(found)
|
||||
require.ErrorIs(err, types.ErrNoUnbondingType)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -56,6 +60,7 @@ func (s *KeeperTestSuite) TestUnbondingTypeAccessors() {
|
||||
|
||||
func (s *KeeperTestSuite) TestUnbondingDelegationByUnbondingIDAccessors() {
|
||||
delAddrs, valAddrs := createValAddrs(2)
|
||||
require := s.Require()
|
||||
|
||||
type exists struct {
|
||||
setUnbondingDelegation bool
|
||||
@ -108,19 +113,19 @@ func (s *KeeperTestSuite) TestUnbondingDelegationByUnbondingIDAccessors() {
|
||||
for i, tc := range cases {
|
||||
s.Run(tc.name, func() {
|
||||
if tc.exists.setUnbondingDelegation {
|
||||
s.stakingKeeper.SetUnbondingDelegation(s.ctx, tc.expected)
|
||||
require.NoError(s.stakingKeeper.SetUnbondingDelegation(s.ctx, tc.expected))
|
||||
}
|
||||
|
||||
if tc.exists.setUnbondingDelegationByUnbondingID {
|
||||
s.stakingKeeper.SetUnbondingDelegationByUnbondingID(s.ctx, tc.expected, uint64(i))
|
||||
require.NoError(s.stakingKeeper.SetUnbondingDelegationByUnbondingID(s.ctx, tc.expected, uint64(i)))
|
||||
}
|
||||
|
||||
ubd, found := s.stakingKeeper.GetUnbondingDelegationByUnbondingID(s.ctx, uint64(i))
|
||||
ubd, err := s.stakingKeeper.GetUnbondingDelegationByUnbondingID(s.ctx, uint64(i))
|
||||
if tc.exists.setUnbondingDelegation && tc.exists.setUnbondingDelegationByUnbondingID {
|
||||
s.Require().True(found)
|
||||
s.Require().Equal(tc.expected, ubd)
|
||||
require.NoError(err)
|
||||
require.Equal(tc.expected, ubd)
|
||||
} else {
|
||||
s.Require().False(found)
|
||||
require.ErrorIs(err, types.ErrNoUnbondingDelegation)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -128,6 +133,7 @@ func (s *KeeperTestSuite) TestUnbondingDelegationByUnbondingIDAccessors() {
|
||||
|
||||
func (s *KeeperTestSuite) TestRedelegationByUnbondingIDAccessors() {
|
||||
delAddrs, valAddrs := createValAddrs(2)
|
||||
require := s.Require()
|
||||
|
||||
type exists struct {
|
||||
setRedelegation bool
|
||||
@ -186,19 +192,19 @@ func (s *KeeperTestSuite) TestRedelegationByUnbondingIDAccessors() {
|
||||
for i, tc := range cases {
|
||||
s.Run(tc.name, func() {
|
||||
if tc.exists.setRedelegation {
|
||||
s.stakingKeeper.SetRedelegation(s.ctx, tc.expected)
|
||||
require.NoError(s.stakingKeeper.SetRedelegation(s.ctx, tc.expected))
|
||||
}
|
||||
|
||||
if tc.exists.setRedelegationByUnbondingID {
|
||||
s.stakingKeeper.SetRedelegationByUnbondingID(s.ctx, tc.expected, uint64(i))
|
||||
require.NoError(s.stakingKeeper.SetRedelegationByUnbondingID(s.ctx, tc.expected, uint64(i)))
|
||||
}
|
||||
|
||||
red, found := s.stakingKeeper.GetRedelegationByUnbondingID(s.ctx, uint64(i))
|
||||
red, err := s.stakingKeeper.GetRedelegationByUnbondingID(s.ctx, uint64(i))
|
||||
if tc.exists.setRedelegation && tc.exists.setRedelegationByUnbondingID {
|
||||
s.Require().True(found)
|
||||
s.Require().Equal(tc.expected, red)
|
||||
require.NoError(err)
|
||||
require.Equal(tc.expected, red)
|
||||
} else {
|
||||
s.Require().False(found)
|
||||
require.ErrorIs(err, types.ErrNoRedelegation)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -206,6 +212,7 @@ func (s *KeeperTestSuite) TestRedelegationByUnbondingIDAccessors() {
|
||||
|
||||
func (s *KeeperTestSuite) TestValidatorByUnbondingIDAccessors() {
|
||||
_, valAddrs := createValAddrs(3)
|
||||
require := s.Require()
|
||||
|
||||
type exists struct {
|
||||
setValidator bool
|
||||
@ -237,19 +244,19 @@ func (s *KeeperTestSuite) TestValidatorByUnbondingIDAccessors() {
|
||||
for i, tc := range cases {
|
||||
s.Run(tc.name, func() {
|
||||
if tc.exists.setValidator {
|
||||
s.stakingKeeper.SetValidator(s.ctx, tc.validator)
|
||||
require.NoError(s.stakingKeeper.SetValidator(s.ctx, tc.validator))
|
||||
}
|
||||
|
||||
if tc.exists.setValidatorByUnbondingID {
|
||||
s.stakingKeeper.SetValidatorByUnbondingID(s.ctx, tc.validator, uint64(i))
|
||||
require.NoError(s.stakingKeeper.SetValidatorByUnbondingID(s.ctx, tc.validator, uint64(i)))
|
||||
}
|
||||
|
||||
val, found := s.stakingKeeper.GetValidatorByUnbondingID(s.ctx, uint64(i))
|
||||
val, err := s.stakingKeeper.GetValidatorByUnbondingID(s.ctx, uint64(i))
|
||||
if tc.exists.setValidator && tc.exists.setValidatorByUnbondingID {
|
||||
s.Require().True(found)
|
||||
s.Require().Equal(tc.validator, val)
|
||||
require.NoError(err)
|
||||
require.Equal(tc.validator, val)
|
||||
} else {
|
||||
s.Require().False(found)
|
||||
require.ErrorIs(err, types.ErrNoValidatorFound)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -257,17 +264,18 @@ func (s *KeeperTestSuite) TestValidatorByUnbondingIDAccessors() {
|
||||
|
||||
func (s *KeeperTestSuite) TestUnbondingCanComplete() {
|
||||
delAddrs, valAddrs := createValAddrs(3)
|
||||
require := s.Require()
|
||||
|
||||
unbondingID := uint64(1)
|
||||
|
||||
// no unbondingID set
|
||||
err := s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
s.Require().ErrorIs(err, types.ErrUnbondingNotFound)
|
||||
require.ErrorIs(err, types.ErrNoUnbondingType)
|
||||
|
||||
// unbonding delegation
|
||||
s.stakingKeeper.SetUnbondingType(s.ctx, unbondingID, types.UnbondingType_UnbondingDelegation)
|
||||
require.NoError(s.stakingKeeper.SetUnbondingType(s.ctx, unbondingID, types.UnbondingType_UnbondingDelegation))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
s.Require().ErrorIs(err, types.ErrUnbondingNotFound)
|
||||
require.ErrorIs(err, types.ErrNoUnbondingDelegation)
|
||||
|
||||
ubd := types.NewUnbondingDelegation(
|
||||
delAddrs[0],
|
||||
@ -277,22 +285,22 @@ func (s *KeeperTestSuite) TestUnbondingCanComplete() {
|
||||
sdk.NewInt(5),
|
||||
unbondingID,
|
||||
)
|
||||
s.stakingKeeper.SetUnbondingDelegation(s.ctx, ubd)
|
||||
s.stakingKeeper.SetUnbondingDelegationByUnbondingID(s.ctx, ubd, unbondingID)
|
||||
require.NoError(s.stakingKeeper.SetUnbondingDelegation(s.ctx, ubd))
|
||||
require.NoError(s.stakingKeeper.SetUnbondingDelegationByUnbondingID(s.ctx, ubd, unbondingID))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
s.Require().ErrorIs(err, types.ErrUnbondingOnHoldRefCountNegative)
|
||||
require.ErrorIs(err, types.ErrUnbondingOnHoldRefCountNegative)
|
||||
|
||||
err = s.stakingKeeper.PutUnbondingOnHold(s.ctx, unbondingID)
|
||||
s.Require().NoError(err)
|
||||
require.NoError(err)
|
||||
s.bankKeeper.EXPECT().UndelegateCoinsFromModuleToAccount(s.ctx, types.NotBondedPoolName, delAddrs[0], sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(5)))).Return(nil)
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
s.Require().NoError(err)
|
||||
require.NoError(err)
|
||||
|
||||
// redelegation
|
||||
unbondingID++
|
||||
s.stakingKeeper.SetUnbondingType(s.ctx, unbondingID, types.UnbondingType_Redelegation)
|
||||
require.NoError(s.stakingKeeper.SetUnbondingType(s.ctx, unbondingID, types.UnbondingType_Redelegation))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
s.Require().ErrorIs(err, types.ErrUnbondingNotFound)
|
||||
require.ErrorIs(err, types.ErrNoRedelegation)
|
||||
|
||||
red := types.NewRedelegation(
|
||||
delAddrs[0],
|
||||
@ -304,30 +312,26 @@ func (s *KeeperTestSuite) TestUnbondingCanComplete() {
|
||||
math.LegacyNewDec(10),
|
||||
unbondingID,
|
||||
)
|
||||
s.stakingKeeper.SetRedelegation(s.ctx, red)
|
||||
s.stakingKeeper.SetRedelegationByUnbondingID(s.ctx, red, unbondingID)
|
||||
require.NoError(s.stakingKeeper.SetRedelegation(s.ctx, red))
|
||||
require.NoError(s.stakingKeeper.SetRedelegationByUnbondingID(s.ctx, red, unbondingID))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
s.Require().ErrorIs(err, types.ErrUnbondingOnHoldRefCountNegative)
|
||||
require.ErrorIs(err, types.ErrUnbondingOnHoldRefCountNegative)
|
||||
|
||||
err = s.stakingKeeper.PutUnbondingOnHold(s.ctx, unbondingID)
|
||||
s.Require().NoError(err)
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
s.Require().NoError(err)
|
||||
require.NoError(s.stakingKeeper.PutUnbondingOnHold(s.ctx, unbondingID))
|
||||
require.NoError(s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID))
|
||||
|
||||
// validator unbonding
|
||||
unbondingID++
|
||||
s.stakingKeeper.SetUnbondingType(s.ctx, unbondingID, types.UnbondingType_ValidatorUnbonding)
|
||||
require.NoError(s.stakingKeeper.SetUnbondingType(s.ctx, unbondingID, types.UnbondingType_ValidatorUnbonding))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
s.Require().ErrorIs(err, types.ErrUnbondingNotFound)
|
||||
require.ErrorIs(err, types.ErrNoValidatorFound)
|
||||
|
||||
val := testutil.NewValidator(s.T(), valAddrs[0], PKs[0])
|
||||
s.stakingKeeper.SetValidator(s.ctx, val)
|
||||
s.stakingKeeper.SetValidatorByUnbondingID(s.ctx, val, unbondingID)
|
||||
require.NoError(s.stakingKeeper.SetValidator(s.ctx, val))
|
||||
require.NoError(s.stakingKeeper.SetValidatorByUnbondingID(s.ctx, val, unbondingID))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
s.Require().ErrorIs(err, types.ErrUnbondingOnHoldRefCountNegative)
|
||||
require.ErrorIs(err, types.ErrUnbondingOnHoldRefCountNegative)
|
||||
|
||||
err = s.stakingKeeper.PutUnbondingOnHold(s.ctx, unbondingID)
|
||||
s.Require().NoError(err)
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
s.Require().NoError(err)
|
||||
require.NoError(s.stakingKeeper.PutUnbondingOnHold(s.ctx, unbondingID))
|
||||
require.NoError(s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID))
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
@ -16,7 +17,7 @@ import (
|
||||
|
||||
// BlockValidatorUpdates calculates the ValidatorUpdates for the current block
|
||||
// Called in each EndBlock
|
||||
func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate {
|
||||
func (k Keeper) BlockValidatorUpdates(ctx context.Context) ([]abci.ValidatorUpdate, error) {
|
||||
// Calculate validator set changes.
|
||||
//
|
||||
// NOTE: ApplyAndReturnValidatorSetUpdates has to come before
|
||||
@ -28,22 +29,30 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate {
|
||||
// UnbondAllMatureValidatorQueue).
|
||||
validatorUpdates, err := k.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// unbond all mature validators from the unbonding queue
|
||||
k.UnbondAllMatureValidators(ctx)
|
||||
err = k.UnbondAllMatureValidators(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
// Remove all mature unbonding delegations from the ubd queue.
|
||||
matureUnbonds := k.DequeueAllMatureUBDQueue(ctx, ctx.BlockHeader().Time)
|
||||
matureUnbonds, err := k.DequeueAllMatureUBDQueue(ctx, sdkCtx.BlockHeader().Time)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, dvPair := range matureUnbonds {
|
||||
addr, err := sdk.ValAddressFromBech32(dvPair.ValidatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(dvPair.DelegatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
balances, err := k.CompleteUnbonding(ctx, delegatorAddress, addr)
|
||||
@ -51,7 +60,7 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate {
|
||||
continue
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdkCtx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCompleteUnbonding,
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, balances.String()),
|
||||
@ -62,19 +71,23 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate {
|
||||
}
|
||||
|
||||
// Remove all mature redelegations from the red queue.
|
||||
matureRedelegations := k.DequeueAllMatureRedelegationQueue(ctx, ctx.BlockHeader().Time)
|
||||
matureRedelegations, err := k.DequeueAllMatureRedelegationQueue(ctx, sdkCtx.BlockHeader().Time)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, dvvTriplet := range matureRedelegations {
|
||||
valSrcAddr, err := sdk.ValAddressFromBech32(dvvTriplet.ValidatorSrcAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
valDstAddr, err := sdk.ValAddressFromBech32(dvvTriplet.ValidatorDstAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(dvvTriplet.DelegatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
balances, err := k.CompleteRedelegation(
|
||||
@ -87,7 +100,7 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate {
|
||||
continue
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdkCtx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCompleteRedelegation,
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, balances.String()),
|
||||
@ -98,7 +111,7 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate {
|
||||
)
|
||||
}
|
||||
|
||||
return validatorUpdates
|
||||
return validatorUpdates, nil
|
||||
}
|
||||
|
||||
// ApplyAndReturnValidatorSetUpdates applies and return accumulated updates to the bonded validator set. Also,
|
||||
@ -113,8 +126,11 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate {
|
||||
// CONTRACT: Only validators with non-zero power or zero-power that were bonded
|
||||
// at the previous block height or were removed from the validator set entirely
|
||||
// are returned to CometBFT.
|
||||
func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []abci.ValidatorUpdate, err error) {
|
||||
params := k.GetParams(ctx)
|
||||
func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx context.Context) (updates []abci.ValidatorUpdate, err error) {
|
||||
params, err := k.GetParams(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
maxValidators := params.MaxValidators
|
||||
powerReduction := k.PowerReduction(ctx)
|
||||
totalPower := math.ZeroInt()
|
||||
@ -129,7 +145,10 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
|
||||
}
|
||||
|
||||
// Iterate over validators, highest power to lowest.
|
||||
iterator := k.ValidatorsPowerStoreIterator(ctx)
|
||||
iterator, err := k.ValidatorsPowerStoreIterator(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
for count := 0; iterator.Valid() && count < int(maxValidators); iterator.Next() {
|
||||
@ -181,7 +200,9 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
|
||||
if !found || !bytes.Equal(oldPowerBytes, newPowerBytes) {
|
||||
updates = append(updates, validator.ABCIValidatorUpdate(powerReduction))
|
||||
|
||||
k.SetLastValidatorPower(ctx, valAddr, newPower)
|
||||
if err = k.SetLastValidatorPower(ctx, valAddr, newPower); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
delete(last, valAddrStr)
|
||||
@ -199,10 +220,13 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
|
||||
validator := k.mustGetValidator(ctx, sdk.ValAddress(valAddrBytes))
|
||||
validator, err = k.bondedToUnbonding(ctx, validator)
|
||||
if err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
amtFromBondedToNotBonded = amtFromBondedToNotBonded.Add(validator.GetTokens())
|
||||
k.DeleteLastValidatorPower(ctx, validator.GetOperator())
|
||||
if err = k.DeleteLastValidatorPower(ctx, validator.GetOperator()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updates = append(updates, validator.ABCIValidatorUpdateZero())
|
||||
}
|
||||
|
||||
@ -215,26 +239,34 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
|
||||
// Compare and subtract the respective amounts to only perform one transfer.
|
||||
// This is done in order to avoid doing multiple updates inside each iterator/loop.
|
||||
case amtFromNotBondedToBonded.GT(amtFromBondedToNotBonded):
|
||||
k.notBondedTokensToBonded(ctx, amtFromNotBondedToBonded.Sub(amtFromBondedToNotBonded))
|
||||
if err = k.notBondedTokensToBonded(ctx, amtFromNotBondedToBonded.Sub(amtFromBondedToNotBonded)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case amtFromNotBondedToBonded.LT(amtFromBondedToNotBonded):
|
||||
k.bondedTokensToNotBonded(ctx, amtFromBondedToNotBonded.Sub(amtFromNotBondedToBonded))
|
||||
if err = k.bondedTokensToNotBonded(ctx, amtFromBondedToNotBonded.Sub(amtFromNotBondedToBonded)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default: // equal amounts of tokens; no update required
|
||||
}
|
||||
|
||||
// set total power on lookup index if there are any updates
|
||||
if len(updates) > 0 {
|
||||
k.SetLastTotalPower(ctx, totalPower)
|
||||
if err = k.SetLastTotalPower(ctx, totalPower); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// set the list of validator updates
|
||||
k.SetValidatorUpdates(ctx, updates)
|
||||
if err = k.SetValidatorUpdates(ctx, updates); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return updates, err
|
||||
}
|
||||
|
||||
// Validator state transitions
|
||||
|
||||
func (k Keeper) bondedToUnbonding(ctx sdk.Context, validator types.Validator) (types.Validator, error) {
|
||||
func (k Keeper) bondedToUnbonding(ctx context.Context, validator types.Validator) (types.Validator, error) {
|
||||
if !validator.IsBonded() {
|
||||
panic(fmt.Sprintf("bad state transition bondedToUnbonding, validator: %v\n", validator))
|
||||
}
|
||||
@ -242,7 +274,7 @@ func (k Keeper) bondedToUnbonding(ctx sdk.Context, validator types.Validator) (t
|
||||
return k.BeginUnbondingValidator(ctx, validator)
|
||||
}
|
||||
|
||||
func (k Keeper) unbondingToBonded(ctx sdk.Context, validator types.Validator) (types.Validator, error) {
|
||||
func (k Keeper) unbondingToBonded(ctx context.Context, validator types.Validator) (types.Validator, error) {
|
||||
if !validator.IsUnbonding() {
|
||||
panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator))
|
||||
}
|
||||
@ -250,7 +282,7 @@ func (k Keeper) unbondingToBonded(ctx sdk.Context, validator types.Validator) (t
|
||||
return k.bondValidator(ctx, validator)
|
||||
}
|
||||
|
||||
func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) (types.Validator, error) {
|
||||
func (k Keeper) unbondedToBonded(ctx context.Context, validator types.Validator) (types.Validator, error) {
|
||||
if !validator.IsUnbonded() {
|
||||
panic(fmt.Sprintf("bad state transition unbondedToBonded, validator: %v\n", validator))
|
||||
}
|
||||
@ -259,49 +291,64 @@ func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) (ty
|
||||
}
|
||||
|
||||
// UnbondingToUnbonded 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 context.Context, validator types.Validator) (types.Validator, error) {
|
||||
if !validator.IsUnbonding() {
|
||||
panic(fmt.Sprintf("bad state transition unbondingToUnbonded, validator: %v\n", validator))
|
||||
return types.Validator{}, fmt.Errorf("bad state transition unbondingToUnbonded, validator: %v", validator)
|
||||
}
|
||||
|
||||
return k.completeUnbondingValidator(ctx, validator)
|
||||
}
|
||||
|
||||
// send a validator to jail
|
||||
func (k Keeper) jailValidator(ctx sdk.Context, validator types.Validator) {
|
||||
func (k Keeper) jailValidator(ctx context.Context, validator types.Validator) error {
|
||||
if validator.Jailed {
|
||||
panic(fmt.Sprintf("cannot jail already jailed validator, validator: %v\n", validator))
|
||||
return types.ErrValidatorJailed.Wrapf("cannot jail already jailed validator, validator: %v", validator)
|
||||
}
|
||||
|
||||
validator.Jailed = true
|
||||
k.SetValidator(ctx, validator)
|
||||
k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
if err := k.SetValidator(ctx, validator); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
}
|
||||
|
||||
// remove a validator from jail
|
||||
func (k Keeper) unjailValidator(ctx sdk.Context, validator types.Validator) {
|
||||
func (k Keeper) unjailValidator(ctx context.Context, validator types.Validator) error {
|
||||
if !validator.Jailed {
|
||||
panic(fmt.Sprintf("cannot unjail already unjailed validator, validator: %v\n", validator))
|
||||
return fmt.Errorf("cannot unjail already unjailed validator, validator: %v", validator)
|
||||
}
|
||||
|
||||
validator.Jailed = false
|
||||
k.SetValidator(ctx, validator)
|
||||
k.SetValidatorByPowerIndex(ctx, validator)
|
||||
if err := k.SetValidator(ctx, validator); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return k.SetValidatorByPowerIndex(ctx, validator)
|
||||
}
|
||||
|
||||
// perform all the store operations for when a validator status becomes bonded
|
||||
func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) (types.Validator, error) {
|
||||
func (k Keeper) bondValidator(ctx context.Context, validator types.Validator) (types.Validator, error) {
|
||||
// delete the validator by power index, as the key will change
|
||||
k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
if err := k.DeleteValidatorByPowerIndex(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
validator = validator.UpdateStatus(types.Bonded)
|
||||
|
||||
// save the now bonded validator record to the two referenced stores
|
||||
k.SetValidator(ctx, validator)
|
||||
k.SetValidatorByPowerIndex(ctx, validator)
|
||||
if err := k.SetValidator(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
if err := k.SetValidatorByPowerIndex(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
// delete from queue if present
|
||||
k.DeleteValidatorQueue(ctx, validator)
|
||||
if err := k.DeleteValidatorQueue(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
// trigger hook
|
||||
consAddr, err := validator.GetConsAddr()
|
||||
@ -317,33 +364,49 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) (types
|
||||
}
|
||||
|
||||
// BeginUnbondingValidator performs all the store operations for when a validator begins unbonding
|
||||
func (k Keeper) BeginUnbondingValidator(ctx sdk.Context, validator types.Validator) (types.Validator, error) {
|
||||
params := k.GetParams(ctx)
|
||||
func (k Keeper) BeginUnbondingValidator(ctx context.Context, validator types.Validator) (types.Validator, error) {
|
||||
params, err := k.GetParams(ctx)
|
||||
if err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
// delete the validator by power index, as the key will change
|
||||
k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
if err = k.DeleteValidatorByPowerIndex(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if validator.Status != types.Bonded {
|
||||
panic(fmt.Sprintf("should not already be unbonded or unbonding, validator: %v\n", validator))
|
||||
}
|
||||
|
||||
id := k.IncrementUnbondingID(ctx)
|
||||
id, err := k.IncrementUnbondingID(ctx)
|
||||
if err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
validator = validator.UpdateStatus(types.Unbonding)
|
||||
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
// set the unbonding completion time and completion height appropriately
|
||||
validator.UnbondingTime = ctx.BlockHeader().Time.Add(params.UnbondingTime)
|
||||
validator.UnbondingHeight = ctx.BlockHeader().Height
|
||||
validator.UnbondingTime = sdkCtx.BlockHeader().Time.Add(params.UnbondingTime)
|
||||
validator.UnbondingHeight = sdkCtx.BlockHeader().Height
|
||||
|
||||
validator.UnbondingIds = append(validator.UnbondingIds, id)
|
||||
|
||||
// save the now unbonded validator record and power index
|
||||
k.SetValidator(ctx, validator)
|
||||
k.SetValidatorByPowerIndex(ctx, validator)
|
||||
if err = k.SetValidator(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
if err = k.SetValidatorByPowerIndex(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
// Adds to unbonding validator queue
|
||||
k.InsertUnbondingValidatorQueue(ctx, validator)
|
||||
if err = k.InsertUnbondingValidatorQueue(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
// trigger hook
|
||||
consAddr, err := validator.GetConsAddr()
|
||||
@ -355,7 +418,9 @@ func (k Keeper) BeginUnbondingValidator(ctx sdk.Context, validator types.Validat
|
||||
return validator, err
|
||||
}
|
||||
|
||||
k.SetValidatorByUnbondingID(ctx, validator, id)
|
||||
if err := k.SetValidatorByUnbondingID(ctx, validator, id); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
if err := k.Hooks().AfterUnbondingInitiated(ctx, id); err != nil {
|
||||
return validator, err
|
||||
@ -365,11 +430,13 @@ func (k Keeper) BeginUnbondingValidator(ctx sdk.Context, validator types.Validat
|
||||
}
|
||||
|
||||
// perform all the store operations for when a validator status becomes unbonded
|
||||
func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Validator) types.Validator {
|
||||
func (k Keeper) completeUnbondingValidator(ctx context.Context, validator types.Validator) (types.Validator, error) {
|
||||
validator = validator.UpdateStatus(types.Unbonded)
|
||||
k.SetValidator(ctx, validator)
|
||||
if err := k.SetValidator(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
return validator
|
||||
return validator, nil
|
||||
}
|
||||
|
||||
// map of operator bech32-addresses to serialized power
|
||||
@ -377,10 +444,13 @@ func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Vali
|
||||
type validatorsByAddr map[string][]byte
|
||||
|
||||
// get the last validator set
|
||||
func (k Keeper) getLastValidatorsByAddr(ctx sdk.Context) (validatorsByAddr, error) {
|
||||
func (k Keeper) getLastValidatorsByAddr(ctx context.Context) (validatorsByAddr, error) {
|
||||
last := make(validatorsByAddr)
|
||||
|
||||
iterator := k.LastValidatorsIterator(ctx)
|
||||
iterator, err := k.LastValidatorsIterator(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
gogotypes "github.com/cosmos/gogoproto/types"
|
||||
|
||||
corestore "cosmossdk.io/core/store"
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"cosmossdk.io/math"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
@ -14,21 +18,23 @@ import (
|
||||
)
|
||||
|
||||
// get a single validator
|
||||
func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator types.Validator, found bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
value := store.Get(types.GetValidatorKey(addr))
|
||||
if value == nil {
|
||||
return validator, false
|
||||
func (k Keeper) GetValidator(ctx context.Context, addr sdk.ValAddress) (validator types.Validator, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
value, err := store.Get(types.GetValidatorKey(addr))
|
||||
if err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
validator = types.MustUnmarshalValidator(k.cdc, value)
|
||||
return validator, true
|
||||
if value == nil {
|
||||
return validator, types.ErrNoValidatorFound
|
||||
}
|
||||
|
||||
return types.UnmarshalValidator(k.cdc, value)
|
||||
}
|
||||
|
||||
func (k Keeper) mustGetValidator(ctx sdk.Context, addr sdk.ValAddress) types.Validator {
|
||||
validator, found := k.GetValidator(ctx, addr)
|
||||
if !found {
|
||||
func (k Keeper) mustGetValidator(ctx context.Context, addr sdk.ValAddress) types.Validator {
|
||||
validator, err := k.GetValidator(ctx, addr)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("validator record not found for address: %X\n", addr))
|
||||
}
|
||||
|
||||
@ -36,20 +42,23 @@ func (k Keeper) mustGetValidator(ctx sdk.Context, addr sdk.ValAddress) types.Val
|
||||
}
|
||||
|
||||
// get a single validator by consensus address
|
||||
func (k Keeper) GetValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) (validator types.Validator, found bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (validator types.Validator, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
opAddr, err := store.Get(types.GetValidatorByConsAddrKey(consAddr))
|
||||
if err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
opAddr := store.Get(types.GetValidatorByConsAddrKey(consAddr))
|
||||
if opAddr == nil {
|
||||
return validator, false
|
||||
return validator, types.ErrNoValidatorFound
|
||||
}
|
||||
|
||||
return k.GetValidator(ctx, opAddr)
|
||||
}
|
||||
|
||||
func (k Keeper) mustGetValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) types.Validator {
|
||||
validator, found := k.GetValidatorByConsAddr(ctx, consAddr)
|
||||
if !found {
|
||||
func (k Keeper) mustGetValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) types.Validator {
|
||||
validator, err := k.GetValidatorByConsAddr(ctx, consAddr)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("validator with consensus-Address %s not found", consAddr))
|
||||
}
|
||||
|
||||
@ -57,96 +66,122 @@ func (k Keeper) mustGetValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAdd
|
||||
}
|
||||
|
||||
// set the main record holding validator details
|
||||
func (k Keeper) SetValidator(ctx sdk.Context, validator types.Validator) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) SetValidator(ctx context.Context, validator types.Validator) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz := types.MustMarshalValidator(k.cdc, &validator)
|
||||
store.Set(types.GetValidatorKey(validator.GetOperator()), bz)
|
||||
return store.Set(types.GetValidatorKey(validator.GetOperator()), bz)
|
||||
}
|
||||
|
||||
// validator index
|
||||
func (k Keeper) SetValidatorByConsAddr(ctx sdk.Context, validator types.Validator) error {
|
||||
func (k Keeper) SetValidatorByConsAddr(ctx context.Context, validator types.Validator) error {
|
||||
consPk, err := validator.GetConsAddr()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Set(types.GetValidatorByConsAddrKey(consPk), validator.GetOperator())
|
||||
return nil
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
return store.Set(types.GetValidatorByConsAddrKey(consPk), validator.GetOperator())
|
||||
}
|
||||
|
||||
// validator index
|
||||
func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Validator) {
|
||||
func (k Keeper) SetValidatorByPowerIndex(ctx context.Context, validator types.Validator) error {
|
||||
// jailed validators are not kept in the power index
|
||||
if validator.Jailed {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Set(types.GetValidatorsByPowerIndexKey(validator, k.PowerReduction(ctx)), validator.GetOperator())
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
return store.Set(types.GetValidatorsByPowerIndexKey(validator, k.PowerReduction(ctx)), validator.GetOperator())
|
||||
}
|
||||
|
||||
// validator index
|
||||
func (k Keeper) DeleteValidatorByPowerIndex(ctx sdk.Context, validator types.Validator) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(types.GetValidatorsByPowerIndexKey(validator, k.PowerReduction(ctx)))
|
||||
func (k Keeper) DeleteValidatorByPowerIndex(ctx context.Context, validator types.Validator) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
return store.Delete(types.GetValidatorsByPowerIndexKey(validator, k.PowerReduction(ctx)))
|
||||
}
|
||||
|
||||
// validator index
|
||||
func (k Keeper) SetNewValidatorByPowerIndex(ctx sdk.Context, validator types.Validator) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Set(types.GetValidatorsByPowerIndexKey(validator, k.PowerReduction(ctx)), validator.GetOperator())
|
||||
func (k Keeper) SetNewValidatorByPowerIndex(ctx context.Context, validator types.Validator) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
return store.Set(types.GetValidatorsByPowerIndexKey(validator, k.PowerReduction(ctx)), validator.GetOperator())
|
||||
}
|
||||
|
||||
// Update the tokens of an existing validator, update the validators power index key
|
||||
func (k Keeper) AddValidatorTokensAndShares(ctx sdk.Context, validator types.Validator,
|
||||
func (k Keeper) AddValidatorTokensAndShares(ctx context.Context, validator types.Validator,
|
||||
tokensToAdd math.Int,
|
||||
) (valOut types.Validator, addedShares math.LegacyDec) {
|
||||
k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
) (valOut types.Validator, addedShares math.LegacyDec, err error) {
|
||||
err = k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
if err != nil {
|
||||
return valOut, addedShares, err
|
||||
}
|
||||
|
||||
validator, addedShares = validator.AddTokensFromDel(tokensToAdd)
|
||||
k.SetValidator(ctx, validator)
|
||||
k.SetValidatorByPowerIndex(ctx, validator)
|
||||
err = k.SetValidator(ctx, validator)
|
||||
if err != nil {
|
||||
return validator, addedShares, err
|
||||
}
|
||||
|
||||
return validator, addedShares
|
||||
err = k.SetValidatorByPowerIndex(ctx, validator)
|
||||
return validator, addedShares, err
|
||||
}
|
||||
|
||||
// Update the tokens of an existing validator, update the validators power index key
|
||||
func (k Keeper) RemoveValidatorTokensAndShares(ctx sdk.Context, validator types.Validator,
|
||||
func (k Keeper) RemoveValidatorTokensAndShares(ctx context.Context, validator types.Validator,
|
||||
sharesToRemove math.LegacyDec,
|
||||
) (valOut types.Validator, removedTokens math.Int) {
|
||||
k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
) (valOut types.Validator, removedTokens math.Int, err error) {
|
||||
err = k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
if err != nil {
|
||||
return valOut, removedTokens, err
|
||||
}
|
||||
validator, removedTokens = validator.RemoveDelShares(sharesToRemove)
|
||||
k.SetValidator(ctx, validator)
|
||||
k.SetValidatorByPowerIndex(ctx, validator)
|
||||
err = k.SetValidator(ctx, validator)
|
||||
if err != nil {
|
||||
return validator, removedTokens, err
|
||||
}
|
||||
|
||||
return validator, removedTokens
|
||||
err = k.SetValidatorByPowerIndex(ctx, validator)
|
||||
return validator, removedTokens, err
|
||||
}
|
||||
|
||||
// Update the tokens of an existing validator, update the validators power index key
|
||||
func (k Keeper) RemoveValidatorTokens(ctx sdk.Context,
|
||||
func (k Keeper) RemoveValidatorTokens(ctx context.Context,
|
||||
validator types.Validator, tokensToRemove math.Int,
|
||||
) types.Validator {
|
||||
k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
validator = validator.RemoveTokens(tokensToRemove)
|
||||
k.SetValidator(ctx, validator)
|
||||
k.SetValidatorByPowerIndex(ctx, validator)
|
||||
) (types.Validator, error) {
|
||||
if err := k.DeleteValidatorByPowerIndex(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
return validator
|
||||
validator = validator.RemoveTokens(tokensToRemove)
|
||||
if err := k.SetValidator(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
if err := k.SetValidatorByPowerIndex(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
return validator, nil
|
||||
}
|
||||
|
||||
// UpdateValidatorCommission attempts to update a validator's commission rate.
|
||||
// An error is returned if the new commission rate is invalid.
|
||||
func (k Keeper) UpdateValidatorCommission(ctx sdk.Context,
|
||||
func (k Keeper) UpdateValidatorCommission(ctx context.Context,
|
||||
validator types.Validator, newRate math.LegacyDec,
|
||||
) (types.Commission, error) {
|
||||
commission := validator.Commission
|
||||
blockTime := ctx.BlockHeader().Time
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
blockTime := sdkCtx.BlockHeader().Time
|
||||
|
||||
if err := commission.ValidateNewRate(newRate, blockTime); err != nil {
|
||||
return commission, err
|
||||
}
|
||||
|
||||
if newRate.LT(k.MinCommissionRate(ctx)) {
|
||||
return commission, fmt.Errorf("cannot set validator commission to less than minimum rate of %s", k.MinCommissionRate(ctx))
|
||||
minCommissionRate, err := k.MinCommissionRate(ctx)
|
||||
if err != nil {
|
||||
return commission, err
|
||||
}
|
||||
|
||||
if newRate.LT(minCommissionRate) {
|
||||
return commission, fmt.Errorf("cannot set validator commission to less than minimum rate of %s", minCommissionRate)
|
||||
}
|
||||
|
||||
commission.Rate = newRate
|
||||
@ -157,79 +192,105 @@ func (k Keeper) UpdateValidatorCommission(ctx sdk.Context,
|
||||
|
||||
// remove the validator record and associated indexes
|
||||
// except for the bonded validator index which is only handled in ApplyAndReturnTendermintUpdates
|
||||
// TODO, this function panics, and it's not good.
|
||||
func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) {
|
||||
func (k Keeper) RemoveValidator(ctx context.Context, address sdk.ValAddress) error {
|
||||
// first retrieve the old validator record
|
||||
validator, found := k.GetValidator(ctx, address)
|
||||
if !found {
|
||||
return
|
||||
validator, err := k.GetValidator(ctx, address)
|
||||
if errors.Is(err, types.ErrNoValidatorFound) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !validator.IsUnbonded() {
|
||||
panic("cannot call RemoveValidator on bonded or unbonding validators")
|
||||
return types.ErrBadRemoveValidator.Wrap("cannot call RemoveValidator on bonded or unbonding validators")
|
||||
}
|
||||
|
||||
if validator.Tokens.IsPositive() {
|
||||
panic("attempting to remove a validator which still contains tokens")
|
||||
return types.ErrBadRemoveValidator.Wrap("attempting to remove a validator which still contains tokens")
|
||||
}
|
||||
|
||||
valConsAddr, err := validator.GetConsAddr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// delete the old validator record
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(types.GetValidatorKey(address))
|
||||
store.Delete(types.GetValidatorByConsAddrKey(valConsAddr))
|
||||
store.Delete(types.GetValidatorsByPowerIndexKey(validator, k.PowerReduction(ctx)))
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
if err = store.Delete(types.GetValidatorKey(address)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = store.Delete(types.GetValidatorByConsAddrKey(valConsAddr)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = store.Delete(types.GetValidatorsByPowerIndexKey(validator, k.PowerReduction(ctx))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := k.Hooks().AfterValidatorRemoved(ctx, valConsAddr, validator.GetOperator()); err != nil {
|
||||
k.Logger(ctx).Error("error in after validator removed hook", "error", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// get groups of validators
|
||||
|
||||
// get the set of all validators with no limits, used during genesis dump
|
||||
func (k Keeper) GetAllValidators(ctx sdk.Context) (validators []types.Validator) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetAllValidators(ctx context.Context) (validators []types.Validator, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, types.ValidatorsKey)
|
||||
iterator, err := store.Iterator(types.ValidatorsKey, storetypes.PrefixEndBytes(types.ValidatorsKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
validator := types.MustUnmarshalValidator(k.cdc, iterator.Value())
|
||||
validator, err := types.UnmarshalValidator(k.cdc, iterator.Value())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validators = append(validators, validator)
|
||||
}
|
||||
|
||||
return validators
|
||||
return validators, nil
|
||||
}
|
||||
|
||||
// return a given amount of all the validators
|
||||
func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve uint32) (validators []types.Validator) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetValidators(ctx context.Context, maxRetrieve uint32) (validators []types.Validator, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
validators = make([]types.Validator, maxRetrieve)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, types.ValidatorsKey)
|
||||
defer iterator.Close()
|
||||
iterator, err := store.Iterator(types.ValidatorsKey, storetypes.PrefixEndBytes(types.ValidatorsKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i := 0
|
||||
for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() {
|
||||
validator := types.MustUnmarshalValidator(k.cdc, iterator.Value())
|
||||
validator, err := types.UnmarshalValidator(k.cdc, iterator.Value())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validators[i] = validator
|
||||
i++
|
||||
}
|
||||
|
||||
return validators[:i] // trim if the array length < maxRetrieve
|
||||
return validators[:i], nil // trim if the array length < maxRetrieve
|
||||
}
|
||||
|
||||
// get the current group of bonded validators sorted by power-rank
|
||||
func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator {
|
||||
maxValidators := k.MaxValidators(ctx)
|
||||
func (k Keeper) GetBondedValidatorsByPower(ctx context.Context) ([]types.Validator, error) {
|
||||
maxValidators, err := k.MaxValidators(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validators := make([]types.Validator, maxValidators)
|
||||
|
||||
iterator := k.ValidatorsPowerStoreIterator(ctx)
|
||||
iterator, err := k.ValidatorsPowerStoreIterator(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
i := 0
|
||||
@ -243,82 +304,99 @@ func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator {
|
||||
}
|
||||
}
|
||||
|
||||
return validators[:i] // trim
|
||||
return validators[:i], nil // trim
|
||||
}
|
||||
|
||||
// returns an iterator for the current validator power store
|
||||
func (k Keeper) ValidatorsPowerStoreIterator(ctx sdk.Context) storetypes.Iterator {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
return storetypes.KVStoreReversePrefixIterator(store, types.ValidatorsByPowerIndexKey)
|
||||
func (k Keeper) ValidatorsPowerStoreIterator(ctx context.Context) (corestore.Iterator, error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
return store.ReverseIterator(types.ValidatorsByPowerIndexKey, storetypes.PrefixEndBytes(types.ValidatorsByPowerIndexKey))
|
||||
}
|
||||
|
||||
// Last Validator Index
|
||||
|
||||
// Load the last validator power.
|
||||
// Returns zero if the operator was not a validator last block.
|
||||
func (k Keeper) GetLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress) (power int64) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetLastValidatorPower(ctx context.Context, operator sdk.ValAddress) (power int64, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz, err := store.Get(types.GetLastValidatorPowerKey(operator))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
bz := store.Get(types.GetLastValidatorPowerKey(operator))
|
||||
if bz == nil {
|
||||
return 0
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
intV := gogotypes.Int64Value{}
|
||||
k.cdc.MustUnmarshal(bz, &intV)
|
||||
err = k.cdc.Unmarshal(bz, &intV)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return intV.GetValue()
|
||||
return intV.GetValue(), nil
|
||||
}
|
||||
|
||||
// Set the last validator power.
|
||||
func (k Keeper) SetLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress, power int64) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := k.cdc.MustMarshal(&gogotypes.Int64Value{Value: power})
|
||||
store.Set(types.GetLastValidatorPowerKey(operator), bz)
|
||||
func (k Keeper) SetLastValidatorPower(ctx context.Context, operator sdk.ValAddress, power int64) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz, err := k.cdc.Marshal(&gogotypes.Int64Value{Value: power})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return store.Set(types.GetLastValidatorPowerKey(operator), bz)
|
||||
}
|
||||
|
||||
// Delete the last validator power.
|
||||
func (k Keeper) DeleteLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(types.GetLastValidatorPowerKey(operator))
|
||||
func (k Keeper) DeleteLastValidatorPower(ctx context.Context, operator sdk.ValAddress) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
return store.Delete(types.GetLastValidatorPowerKey(operator))
|
||||
}
|
||||
|
||||
// returns an iterator for the consensus validators in the last block
|
||||
func (k Keeper) LastValidatorsIterator(ctx sdk.Context) (iterator storetypes.Iterator) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
iterator = storetypes.KVStorePrefixIterator(store, types.LastValidatorPowerKey)
|
||||
|
||||
return iterator
|
||||
func (k Keeper) LastValidatorsIterator(ctx context.Context) (corestore.Iterator, error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
return store.Iterator(types.LastValidatorPowerKey, storetypes.PrefixEndBytes(types.LastValidatorPowerKey))
|
||||
}
|
||||
|
||||
// Iterate over last validator powers.
|
||||
func (k Keeper) IterateLastValidatorPowers(ctx sdk.Context, handler func(operator sdk.ValAddress, power int64) (stop bool)) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
iter := storetypes.KVStorePrefixIterator(store, types.LastValidatorPowerKey)
|
||||
defer iter.Close()
|
||||
func (k Keeper) IterateLastValidatorPowers(ctx context.Context, handler func(operator sdk.ValAddress, power int64) (stop bool)) error {
|
||||
iter, err := k.LastValidatorsIterator(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
addr := sdk.ValAddress(types.AddressFromLastValidatorPowerKey(iter.Key()))
|
||||
intV := &gogotypes.Int64Value{}
|
||||
|
||||
k.cdc.MustUnmarshal(iter.Value(), intV)
|
||||
if err = k.cdc.Unmarshal(iter.Value(), intV); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if handler(addr, intV.GetValue()) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// get the group of the bonded validators
|
||||
func (k Keeper) GetLastValidators(ctx sdk.Context) (validators []types.Validator) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetLastValidators(ctx context.Context) (validators []types.Validator, err error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
|
||||
// add the actual validator power sorted store
|
||||
maxValidators := k.MaxValidators(ctx)
|
||||
maxValidators, err := k.MaxValidators(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validators = make([]types.Validator, maxValidators)
|
||||
|
||||
iterator := storetypes.KVStorePrefixIterator(store, types.LastValidatorPowerKey)
|
||||
iterator, err := store.Iterator(types.LastValidatorPowerKey, storetypes.PrefixEndBytes(types.LastValidatorPowerKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer iterator.Close()
|
||||
|
||||
i := 0
|
||||
@ -329,72 +407,90 @@ func (k Keeper) GetLastValidators(ctx sdk.Context) (validators []types.Validator
|
||||
}
|
||||
|
||||
address := types.AddressFromLastValidatorPowerKey(iterator.Key())
|
||||
validator := k.mustGetValidator(ctx, address)
|
||||
validator, err := k.GetValidator(ctx, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validators[i] = validator
|
||||
i++
|
||||
}
|
||||
|
||||
return validators[:i] // trim
|
||||
return validators[:i], nil // trim
|
||||
}
|
||||
|
||||
// GetUnbondingValidators returns a slice of mature validator addresses that
|
||||
// complete their unbonding at a given time and height.
|
||||
func (k Keeper) GetUnbondingValidators(ctx sdk.Context, endTime time.Time, endHeight int64) []string {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) GetUnbondingValidators(ctx context.Context, endTime time.Time, endHeight int64) ([]string, error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
|
||||
bz, err := store.Get(types.GetValidatorQueueKey(endTime, endHeight))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bz := store.Get(types.GetValidatorQueueKey(endTime, endHeight))
|
||||
if bz == nil {
|
||||
return []string{}
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
addrs := types.ValAddresses{}
|
||||
k.cdc.MustUnmarshal(bz, &addrs)
|
||||
if err = k.cdc.Unmarshal(bz, &addrs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return addrs.Addresses
|
||||
return addrs.Addresses, nil
|
||||
}
|
||||
|
||||
// SetUnbondingValidatorsQueue sets a given slice of validator addresses into
|
||||
// the unbonding validator queue by a given height and time.
|
||||
func (k Keeper) SetUnbondingValidatorsQueue(ctx sdk.Context, endTime time.Time, endHeight int64, addrs []string) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := k.cdc.MustMarshal(&types.ValAddresses{Addresses: addrs})
|
||||
store.Set(types.GetValidatorQueueKey(endTime, endHeight), bz)
|
||||
func (k Keeper) SetUnbondingValidatorsQueue(ctx context.Context, endTime time.Time, endHeight int64, addrs []string) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
bz, err := k.cdc.Marshal(&types.ValAddresses{Addresses: addrs})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return store.Set(types.GetValidatorQueueKey(endTime, endHeight), bz)
|
||||
}
|
||||
|
||||
// InsertUnbondingValidatorQueue inserts a given unbonding validator address into
|
||||
// the unbonding validator queue for a given height and time.
|
||||
func (k Keeper) InsertUnbondingValidatorQueue(ctx sdk.Context, val types.Validator) {
|
||||
addrs := k.GetUnbondingValidators(ctx, val.UnbondingTime, val.UnbondingHeight)
|
||||
func (k Keeper) InsertUnbondingValidatorQueue(ctx context.Context, val types.Validator) error {
|
||||
addrs, err := k.GetUnbondingValidators(ctx, val.UnbondingTime, val.UnbondingHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addrs = append(addrs, val.OperatorAddress)
|
||||
k.SetUnbondingValidatorsQueue(ctx, val.UnbondingTime, val.UnbondingHeight, addrs)
|
||||
return k.SetUnbondingValidatorsQueue(ctx, val.UnbondingTime, val.UnbondingHeight, addrs)
|
||||
}
|
||||
|
||||
// DeleteValidatorQueueTimeSlice deletes all entries in the queue indexed by a
|
||||
// given height and time.
|
||||
func (k Keeper) DeleteValidatorQueueTimeSlice(ctx sdk.Context, endTime time.Time, endHeight int64) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(types.GetValidatorQueueKey(endTime, endHeight))
|
||||
func (k Keeper) DeleteValidatorQueueTimeSlice(ctx context.Context, endTime time.Time, endHeight int64) error {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
return store.Delete(types.GetValidatorQueueKey(endTime, endHeight))
|
||||
}
|
||||
|
||||
// DeleteValidatorQueue removes a validator by address from the unbonding queue
|
||||
// indexed by a given height and time.
|
||||
func (k Keeper) DeleteValidatorQueue(ctx sdk.Context, val types.Validator) {
|
||||
addrs := k.GetUnbondingValidators(ctx, val.UnbondingTime, val.UnbondingHeight)
|
||||
func (k Keeper) DeleteValidatorQueue(ctx context.Context, val types.Validator) error {
|
||||
addrs, err := k.GetUnbondingValidators(ctx, val.UnbondingTime, val.UnbondingHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newAddrs := []string{}
|
||||
|
||||
// since address string may change due to Bech32 prefix change, we parse the addresses into bytes
|
||||
// format for normalization
|
||||
deletingAddr, err := sdk.ValAddressFromBech32(val.OperatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
storedAddr, err := sdk.ValAddressFromBech32(addr)
|
||||
if err != nil {
|
||||
// even if we don't panic here, it will panic in UnbondAllMatureValidators at unbond time
|
||||
panic(err)
|
||||
// even if we don't error here, it will error in UnbondAllMatureValidators at unbond time
|
||||
return err
|
||||
}
|
||||
if !storedAddr.Equals(deletingAddr) {
|
||||
newAddrs = append(newAddrs, storedAddr.String())
|
||||
@ -402,38 +498,42 @@ func (k Keeper) DeleteValidatorQueue(ctx sdk.Context, val types.Validator) {
|
||||
}
|
||||
|
||||
if len(newAddrs) == 0 {
|
||||
k.DeleteValidatorQueueTimeSlice(ctx, val.UnbondingTime, val.UnbondingHeight)
|
||||
} else {
|
||||
k.SetUnbondingValidatorsQueue(ctx, val.UnbondingTime, val.UnbondingHeight, newAddrs)
|
||||
return k.DeleteValidatorQueueTimeSlice(ctx, val.UnbondingTime, val.UnbondingHeight)
|
||||
}
|
||||
|
||||
return k.SetUnbondingValidatorsQueue(ctx, val.UnbondingTime, val.UnbondingHeight, newAddrs)
|
||||
}
|
||||
|
||||
// ValidatorQueueIterator returns an interator ranging over validators that are
|
||||
// unbonding whose unbonding completion occurs at the given height and time.
|
||||
func (k Keeper) ValidatorQueueIterator(ctx sdk.Context, endTime time.Time, endHeight int64) storetypes.Iterator {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
func (k Keeper) ValidatorQueueIterator(ctx context.Context, endTime time.Time, endHeight int64) (corestore.Iterator, error) {
|
||||
store := k.storeService.OpenKVStore(ctx)
|
||||
return store.Iterator(types.ValidatorQueueKey, storetypes.InclusiveEndBytes(types.GetValidatorQueueKey(endTime, endHeight)))
|
||||
}
|
||||
|
||||
// UnbondAllMatureValidators unbonds all the mature unbonding validators that
|
||||
// have finished their unbonding period.
|
||||
func (k Keeper) UnbondAllMatureValidators(ctx sdk.Context) {
|
||||
blockTime := ctx.BlockTime()
|
||||
blockHeight := ctx.BlockHeight()
|
||||
func (k Keeper) UnbondAllMatureValidators(ctx context.Context) error {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
blockTime := sdkCtx.BlockTime()
|
||||
blockHeight := sdkCtx.BlockHeight()
|
||||
|
||||
// unbondingValIterator will contains all validator addresses indexed under
|
||||
// the ValidatorQueueKey prefix. Note, the entire index key is composed as
|
||||
// ValidatorQueueKey | timeBzLen (8-byte big endian) | timeBz | heightBz (8-byte big endian),
|
||||
// so it may be possible that certain validator addresses that are iterated
|
||||
// over are not ready to unbond, so an explicit check is required.
|
||||
unbondingValIterator := k.ValidatorQueueIterator(ctx, blockTime, blockHeight)
|
||||
unbondingValIterator, err := k.ValidatorQueueIterator(ctx, blockTime, blockHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer unbondingValIterator.Close()
|
||||
|
||||
for ; unbondingValIterator.Valid(); unbondingValIterator.Next() {
|
||||
key := unbondingValIterator.Key()
|
||||
keyTime, keyHeight, err := types.ParseValidatorQueueKey(key)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to parse unbonding key: %w", err))
|
||||
return fmt.Errorf("failed to parse unbonding key: %w", err)
|
||||
}
|
||||
|
||||
// All addresses for the given key have the same unbonding height and time.
|
||||
@ -441,49 +541,61 @@ func (k Keeper) UnbondAllMatureValidators(ctx sdk.Context) {
|
||||
// and time.
|
||||
if keyHeight <= blockHeight && (keyTime.Before(blockTime) || keyTime.Equal(blockTime)) {
|
||||
addrs := types.ValAddresses{}
|
||||
k.cdc.MustUnmarshal(unbondingValIterator.Value(), &addrs)
|
||||
if err = k.cdc.Unmarshal(unbondingValIterator.Value(), &addrs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, valAddr := range addrs.Addresses {
|
||||
addr, err := sdk.ValAddressFromBech32(valAddr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
val, found := k.GetValidator(ctx, addr)
|
||||
if !found {
|
||||
panic("validator in the unbonding queue was not found")
|
||||
val, err := k.GetValidator(ctx, addr)
|
||||
if err != nil {
|
||||
return errorsmod.Wrap(err, "validator in the unbonding queue was not found")
|
||||
}
|
||||
|
||||
if !val.IsUnbonding() {
|
||||
panic("unexpected validator in unbonding queue; status was not unbonding")
|
||||
return fmt.Errorf("unexpected validator in unbonding queue; status was not unbonding")
|
||||
}
|
||||
|
||||
if val.UnbondingOnHoldRefCount == 0 {
|
||||
for _, id := range val.UnbondingIds {
|
||||
k.DeleteUnbondingIndex(ctx, id)
|
||||
if err = k.DeleteUnbondingIndex(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
val = k.UnbondingToUnbonded(ctx, val)
|
||||
val, err = k.UnbondingToUnbonded(ctx, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.GetDelegatorShares().IsZero() {
|
||||
k.RemoveValidator(ctx, val.GetOperator())
|
||||
if err = k.RemoveValidator(ctx, val.GetOperator()); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// remove unbonding ids
|
||||
val.UnbondingIds = []uint64{}
|
||||
}
|
||||
|
||||
// remove validator from queue
|
||||
k.DeleteValidatorQueue(ctx, val)
|
||||
if err = k.DeleteValidatorQueue(ctx, val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k Keeper) IsValidatorJailed(ctx sdk.Context, addr sdk.ConsAddress) bool {
|
||||
v, ok := k.GetValidatorByConsAddr(ctx, addr)
|
||||
if !ok {
|
||||
return false
|
||||
func (k Keeper) IsValidatorJailed(ctx context.Context, addr sdk.ConsAddress) (bool, error) {
|
||||
v, err := k.GetValidatorByConsAddr(ctx, addr)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return v.Jailed
|
||||
return v.Jailed, nil
|
||||
}
|
||||
|
||||
@ -6,9 +6,11 @@ import (
|
||||
"github.com/golang/mock/gomock"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/testutil"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
@ -37,15 +39,15 @@ func (s *KeeperTestSuite) TestValidator() {
|
||||
require.Equal(stakingtypes.Unbonded, validator.Status)
|
||||
require.Equal(valTokens, validator.Tokens)
|
||||
require.Equal(valTokens, validator.DelegatorShares.RoundInt())
|
||||
keeper.SetValidator(ctx, validator)
|
||||
keeper.SetValidatorByPowerIndex(ctx, validator)
|
||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||
require.NoError(keeper.SetValidator(ctx, validator))
|
||||
require.NoError(keeper.SetValidatorByPowerIndex(ctx, validator))
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
|
||||
|
||||
// ensure update
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
|
||||
updates := s.applyValidatorSetUpdates(ctx, keeper, 1)
|
||||
validator, found := keeper.GetValidator(ctx, valAddr)
|
||||
require.True(found)
|
||||
validator, err := keeper.GetValidator(ctx, valAddr)
|
||||
require.NoError(err)
|
||||
require.Equal(validator.ABCIValidatorUpdate(keeper.PowerReduction(ctx)), updates[0])
|
||||
|
||||
// after the save the validator should be bonded
|
||||
@ -56,28 +58,33 @@ func (s *KeeperTestSuite) TestValidator() {
|
||||
// check each store for being saved
|
||||
consAddr, err := validator.GetConsAddr()
|
||||
require.NoError(err)
|
||||
resVal, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||
require.True(found)
|
||||
resVal, err := keeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||
require.NoError(err)
|
||||
require.True(validator.MinEqual(&resVal))
|
||||
|
||||
resVals := keeper.GetLastValidators(ctx)
|
||||
resVals, err := keeper.GetLastValidators(ctx)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resVals))
|
||||
require.True(validator.MinEqual(&resVals[0]))
|
||||
|
||||
resVals = keeper.GetBondedValidatorsByPower(ctx)
|
||||
resVals, err = keeper.GetBondedValidatorsByPower(ctx)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resVals))
|
||||
require.True(validator.MinEqual(&resVals[0]))
|
||||
|
||||
allVals := keeper.GetAllValidators(ctx)
|
||||
allVals, err := keeper.GetAllValidators(ctx)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(allVals))
|
||||
|
||||
// check the last validator power
|
||||
power := int64(100)
|
||||
keeper.SetLastValidatorPower(ctx, valAddr, power)
|
||||
resPower := keeper.GetLastValidatorPower(ctx, valAddr)
|
||||
require.NoError(keeper.SetLastValidatorPower(ctx, valAddr, power))
|
||||
resPower, err := keeper.GetLastValidatorPower(ctx, valAddr)
|
||||
require.NoError(err)
|
||||
require.Equal(power, resPower)
|
||||
keeper.DeleteLastValidatorPower(ctx, valAddr)
|
||||
resPower = keeper.GetLastValidatorPower(ctx, valAddr)
|
||||
require.NoError(keeper.DeleteLastValidatorPower(ctx, valAddr))
|
||||
resPower, err = keeper.GetLastValidatorPower(ctx, valAddr)
|
||||
require.NoError(err)
|
||||
require.Equal(int64(0), resPower)
|
||||
}
|
||||
|
||||
@ -103,31 +110,34 @@ func (s *KeeperTestSuite) TestValidatorBasics() {
|
||||
require.Equal(keeper.TokensFromConsensusPower(ctx, 7), validators[2].Tokens)
|
||||
|
||||
// check the empty keeper first
|
||||
_, found := keeper.GetValidator(ctx, sdk.ValAddress(PKs[0].Address().Bytes()))
|
||||
require.False(found)
|
||||
resVals := keeper.GetLastValidators(ctx)
|
||||
_, err := keeper.GetValidator(ctx, sdk.ValAddress(PKs[0].Address().Bytes()))
|
||||
require.ErrorIs(err, stakingtypes.ErrNoValidatorFound)
|
||||
resVals, err := keeper.GetLastValidators(ctx)
|
||||
require.NoError(err)
|
||||
require.Zero(len(resVals))
|
||||
|
||||
resVals = keeper.GetValidators(ctx, 2)
|
||||
resVals, err = keeper.GetValidators(ctx, 2)
|
||||
require.NoError(err)
|
||||
require.Len(resVals, 0)
|
||||
|
||||
// set and retrieve a record
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
|
||||
validators[0] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[0], true)
|
||||
keeper.SetValidatorByConsAddr(ctx, validators[0])
|
||||
resVal, found := keeper.GetValidator(ctx, sdk.ValAddress(PKs[0].Address().Bytes()))
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetValidatorByConsAddr(ctx, validators[0]))
|
||||
resVal, err := keeper.GetValidator(ctx, sdk.ValAddress(PKs[0].Address().Bytes()))
|
||||
require.NoError(err)
|
||||
require.True(validators[0].MinEqual(&resVal))
|
||||
|
||||
// retrieve from consensus
|
||||
resVal, found = keeper.GetValidatorByConsAddr(ctx, sdk.ConsAddress(PKs[0].Address()))
|
||||
require.True(found)
|
||||
resVal, err = keeper.GetValidatorByConsAddr(ctx, sdk.ConsAddress(PKs[0].Address()))
|
||||
require.NoError(err)
|
||||
require.True(validators[0].MinEqual(&resVal))
|
||||
resVal, found = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
|
||||
require.True(found)
|
||||
resVal, err = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
|
||||
require.NoError(err)
|
||||
require.True(validators[0].MinEqual(&resVal))
|
||||
|
||||
resVals = keeper.GetLastValidators(ctx)
|
||||
resVals, err = keeper.GetLastValidators(ctx)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resVals))
|
||||
require.True(validators[0].MinEqual(&resVals[0]))
|
||||
require.Equal(stakingtypes.Bonded, validators[0].Status)
|
||||
@ -138,11 +148,12 @@ func (s *KeeperTestSuite) TestValidatorBasics() {
|
||||
validators[0].Tokens = keeper.TokensFromConsensusPower(ctx, 10)
|
||||
validators[0].DelegatorShares = math.LegacyNewDecFromInt(validators[0].Tokens)
|
||||
validators[0] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[0], true)
|
||||
resVal, found = keeper.GetValidator(ctx, sdk.ValAddress(PKs[0].Address().Bytes()))
|
||||
require.True(found)
|
||||
resVal, err = keeper.GetValidator(ctx, sdk.ValAddress(PKs[0].Address().Bytes()))
|
||||
require.NoError(err)
|
||||
require.True(validators[0].MinEqual(&resVal))
|
||||
|
||||
resVals = keeper.GetLastValidators(ctx)
|
||||
resVals, err = keeper.GetLastValidators(ctx)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resVals))
|
||||
require.True(validators[0].MinEqual(&resVals[0]))
|
||||
|
||||
@ -151,33 +162,32 @@ func (s *KeeperTestSuite) TestValidatorBasics() {
|
||||
validators[1] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[1], true)
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
|
||||
validators[2] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[2], true)
|
||||
resVal, found = keeper.GetValidator(ctx, sdk.ValAddress(PKs[1].Address().Bytes()))
|
||||
require.True(found)
|
||||
resVal, err = keeper.GetValidator(ctx, sdk.ValAddress(PKs[1].Address().Bytes()))
|
||||
require.NoError(err)
|
||||
require.True(validators[1].MinEqual(&resVal))
|
||||
resVal, found = keeper.GetValidator(ctx, sdk.ValAddress(PKs[2].Address().Bytes()))
|
||||
require.True(found)
|
||||
resVal, err = keeper.GetValidator(ctx, sdk.ValAddress(PKs[2].Address().Bytes()))
|
||||
require.NoError(err)
|
||||
require.True(validators[2].MinEqual(&resVal))
|
||||
|
||||
resVals = keeper.GetLastValidators(ctx)
|
||||
resVals, err = keeper.GetLastValidators(ctx)
|
||||
require.NoError(err)
|
||||
require.Equal(3, len(resVals))
|
||||
|
||||
// remove a record
|
||||
|
||||
// shouldn't be able to remove if status is not unbonded
|
||||
require.PanicsWithValue("cannot call RemoveValidator on bonded or unbonding validators",
|
||||
func() { keeper.RemoveValidator(ctx, validators[1].GetOperator()) })
|
||||
require.EqualError(keeper.RemoveValidator(ctx, validators[1].GetOperator()), "cannot call RemoveValidator on bonded or unbonding validators: failed to remove validator")
|
||||
|
||||
// shouldn't be able to remove if there are still tokens left
|
||||
validators[1].Status = stakingtypes.Unbonded
|
||||
keeper.SetValidator(ctx, validators[1])
|
||||
require.PanicsWithValue("attempting to remove a validator which still contains tokens",
|
||||
func() { keeper.RemoveValidator(ctx, validators[1].GetOperator()) })
|
||||
require.NoError(keeper.SetValidator(ctx, validators[1]))
|
||||
require.EqualError(keeper.RemoveValidator(ctx, validators[1].GetOperator()), "attempting to remove a validator which still contains tokens: failed to remove validator")
|
||||
|
||||
validators[1].Tokens = math.ZeroInt() // ...remove all tokens
|
||||
keeper.SetValidator(ctx, validators[1]) // ...set the validator
|
||||
keeper.RemoveValidator(ctx, validators[1].GetOperator()) // Now it can be removed.
|
||||
_, found = keeper.GetValidator(ctx, sdk.ValAddress(PKs[1].Address().Bytes()))
|
||||
require.False(found)
|
||||
validators[1].Tokens = math.ZeroInt() // ...remove all tokens
|
||||
require.NoError(keeper.SetValidator(ctx, validators[1])) // ...set the validator
|
||||
require.NoError(keeper.RemoveValidator(ctx, validators[1].GetOperator())) // Now it can be removed.
|
||||
_, err = keeper.GetValidator(ctx, sdk.ValAddress(PKs[1].Address().Bytes()))
|
||||
require.ErrorIs(err, stakingtypes.ErrNoValidatorFound)
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestUpdateValidatorByPowerIndex() {
|
||||
@ -196,30 +206,30 @@ func (s *KeeperTestSuite) TestUpdateValidatorByPowerIndex() {
|
||||
|
||||
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
|
||||
stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
|
||||
validator, found := keeper.GetValidator(ctx, valAddr)
|
||||
require.True(found)
|
||||
validator, err := keeper.GetValidator(ctx, valAddr)
|
||||
require.NoError(err)
|
||||
require.Equal(valTokens, validator.Tokens)
|
||||
|
||||
power := stakingtypes.GetValidatorsByPowerIndexKey(validator, keeper.PowerReduction(ctx))
|
||||
require.True(stakingkeeper.ValidatorByPowerIndexExists(ctx, keeper, power))
|
||||
|
||||
// burn half the delegator shares
|
||||
keeper.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
require.NoError(keeper.DeleteValidatorByPowerIndex(ctx, validator))
|
||||
validator, burned := validator.RemoveDelShares(delSharesCreated.Quo(math.LegacyNewDec(2)))
|
||||
require.Equal(keeper.TokensFromConsensusPower(ctx, 50), burned)
|
||||
stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true) // update the validator, possibly kicking it out
|
||||
require.False(stakingkeeper.ValidatorByPowerIndexExists(ctx, keeper, power))
|
||||
|
||||
validator, found = keeper.GetValidator(ctx, valAddr)
|
||||
require.True(found)
|
||||
validator, err = keeper.GetValidator(ctx, valAddr)
|
||||
require.NoError(err)
|
||||
|
||||
power = stakingtypes.GetValidatorsByPowerIndexKey(validator, keeper.PowerReduction(ctx))
|
||||
require.True(stakingkeeper.ValidatorByPowerIndexExists(ctx, keeper, power))
|
||||
|
||||
// set new validator by power index
|
||||
keeper.DeleteValidatorByPowerIndex(ctx, validator)
|
||||
require.NoError(keeper.DeleteValidatorByPowerIndex(ctx, validator))
|
||||
require.False(stakingkeeper.ValidatorByPowerIndexExists(ctx, keeper, power))
|
||||
keeper.SetNewValidatorByPowerIndex(ctx, validator)
|
||||
require.NoError(keeper.SetNewValidatorByPowerIndex(ctx, validator))
|
||||
require.True(stakingkeeper.ValidatorByPowerIndexExists(ctx, keeper, power))
|
||||
}
|
||||
|
||||
@ -272,9 +282,10 @@ func (s *KeeperTestSuite) TestUpdateValidatorCommission() {
|
||||
require := s.Require()
|
||||
|
||||
// Set MinCommissionRate to 0.05
|
||||
params := keeper.GetParams(ctx)
|
||||
params, err := keeper.GetParams(ctx)
|
||||
require.NoError(err)
|
||||
params.MinCommissionRate = math.LegacyNewDecWithPrec(5, 2)
|
||||
keeper.SetParams(ctx, params)
|
||||
require.NoError(keeper.SetParams(ctx, params))
|
||||
|
||||
commission1 := stakingtypes.NewCommissionWithTime(
|
||||
math.LegacyNewDecWithPrec(1, 1), math.LegacyNewDecWithPrec(3, 1),
|
||||
@ -288,8 +299,8 @@ func (s *KeeperTestSuite) TestUpdateValidatorCommission() {
|
||||
val1, _ = val1.SetInitialCommission(commission1)
|
||||
val2, _ = val2.SetInitialCommission(commission2)
|
||||
|
||||
keeper.SetValidator(ctx, val1)
|
||||
keeper.SetValidator(ctx, val2)
|
||||
require.NoError(keeper.SetValidator(ctx, val1))
|
||||
require.NoError(keeper.SetValidator(ctx, val2))
|
||||
|
||||
testCases := []struct {
|
||||
validator stakingtypes.Validator
|
||||
@ -310,16 +321,19 @@ func (s *KeeperTestSuite) TestUpdateValidatorCommission() {
|
||||
if tc.expectedErr {
|
||||
require.Error(err, "expected error for test case #%d with rate: %s", i, tc.newRate)
|
||||
} else {
|
||||
tc.validator.Commission = commission
|
||||
keeper.SetValidator(ctx, tc.validator)
|
||||
val, found := keeper.GetValidator(ctx, tc.validator.GetOperator())
|
||||
|
||||
require.True(found,
|
||||
"expected to find validator for test case #%d with rate: %s", i, tc.newRate,
|
||||
)
|
||||
require.NoError(err,
|
||||
"unexpected error for test case #%d with rate: %s", i, tc.newRate,
|
||||
)
|
||||
|
||||
tc.validator.Commission = commission
|
||||
err = keeper.SetValidator(ctx, tc.validator)
|
||||
require.NoError(err)
|
||||
|
||||
val, err := keeper.GetValidator(ctx, tc.validator.GetOperator())
|
||||
require.NoError(err,
|
||||
"expected to find validator for test case #%d with rate: %s", i, tc.newRate,
|
||||
)
|
||||
|
||||
require.Equal(tc.newRate, val.Commission.Rate,
|
||||
"expected new validator commission rate for test case #%d with rate: %s", i, tc.newRate,
|
||||
)
|
||||
@ -340,17 +354,20 @@ func (s *KeeperTestSuite) TestValidatorToken() {
|
||||
delTokens := keeper.TokensFromConsensusPower(ctx, 5)
|
||||
|
||||
validator := testutil.NewValidator(s.T(), valAddr, valPubKey)
|
||||
validator, _ = keeper.AddValidatorTokensAndShares(ctx, validator, addTokens)
|
||||
validator, _, err := keeper.AddValidatorTokensAndShares(ctx, validator, addTokens)
|
||||
require.NoError(err)
|
||||
require.Equal(addTokens, validator.Tokens)
|
||||
validator, _ = keeper.GetValidator(ctx, valAddr)
|
||||
require.Equal(math.LegacyNewDecFromInt(addTokens), validator.DelegatorShares)
|
||||
|
||||
keeper.RemoveValidatorTokensAndShares(ctx, validator, math.LegacyNewDecFromInt(delTokens))
|
||||
_, _, err = keeper.RemoveValidatorTokensAndShares(ctx, validator, math.LegacyNewDecFromInt(delTokens))
|
||||
require.NoError(err)
|
||||
validator, _ = keeper.GetValidator(ctx, valAddr)
|
||||
require.Equal(delTokens, validator.Tokens)
|
||||
require.True(validator.DelegatorShares.Equal(math.LegacyNewDecFromInt(delTokens)))
|
||||
|
||||
keeper.RemoveValidatorTokens(ctx, validator, delTokens)
|
||||
_, err = keeper.RemoveValidatorTokens(ctx, validator, delTokens)
|
||||
require.NoError(err)
|
||||
validator, _ = keeper.GetValidator(ctx, valAddr)
|
||||
require.True(validator.Tokens.IsZero())
|
||||
}
|
||||
@ -367,9 +384,10 @@ func (s *KeeperTestSuite) TestUnbondingValidator() {
|
||||
// set unbonding validator
|
||||
endTime := time.Now()
|
||||
endHeight := ctx.BlockHeight() + 10
|
||||
keeper.SetUnbondingValidatorsQueue(ctx, endTime, endHeight, []string{valAddr.String()})
|
||||
require.NoError(keeper.SetUnbondingValidatorsQueue(ctx, endTime, endHeight, []string{valAddr.String()}))
|
||||
|
||||
resVals := keeper.GetUnbondingValidators(ctx, endTime, endHeight)
|
||||
resVals, err := keeper.GetUnbondingValidators(ctx, endTime, endHeight)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resVals))
|
||||
require.Equal(valAddr.String(), resVals[0])
|
||||
|
||||
@ -378,42 +396,43 @@ func (s *KeeperTestSuite) TestUnbondingValidator() {
|
||||
validator1 := testutil.NewValidator(s.T(), valAddr1, PKs[1])
|
||||
validator1.UnbondingHeight = endHeight
|
||||
validator1.UnbondingTime = endTime
|
||||
keeper.InsertUnbondingValidatorQueue(ctx, validator1)
|
||||
require.NoError(keeper.InsertUnbondingValidatorQueue(ctx, validator1))
|
||||
|
||||
resVals = keeper.GetUnbondingValidators(ctx, endTime, endHeight)
|
||||
resVals, err = keeper.GetUnbondingValidators(ctx, endTime, endHeight)
|
||||
require.NoError(err)
|
||||
require.Equal(2, len(resVals))
|
||||
|
||||
// delete unbonding validator from the queue
|
||||
keeper.DeleteValidatorQueue(ctx, validator1)
|
||||
resVals = keeper.GetUnbondingValidators(ctx, endTime, endHeight)
|
||||
require.NoError(keeper.DeleteValidatorQueue(ctx, validator1))
|
||||
resVals, err = keeper.GetUnbondingValidators(ctx, endTime, endHeight)
|
||||
require.NoError(err)
|
||||
require.Equal(1, len(resVals))
|
||||
require.Equal(valAddr.String(), resVals[0])
|
||||
|
||||
// check unbonding mature validators
|
||||
ctx = ctx.WithBlockHeight(endHeight).WithBlockTime(endTime)
|
||||
require.PanicsWithValue("validator in the unbonding queue was not found", func() {
|
||||
keeper.UnbondAllMatureValidators(ctx)
|
||||
})
|
||||
err = keeper.UnbondAllMatureValidators(ctx)
|
||||
require.EqualError(err, "validator in the unbonding queue was not found: validator does not exist")
|
||||
|
||||
keeper.SetValidator(ctx, validator)
|
||||
require.NoError(keeper.SetValidator(ctx, validator))
|
||||
ctx = ctx.WithBlockHeight(endHeight).WithBlockTime(endTime)
|
||||
require.PanicsWithValue("unexpected validator in unbonding queue; status was not unbonding", func() {
|
||||
keeper.UnbondAllMatureValidators(ctx)
|
||||
})
|
||||
|
||||
err = keeper.UnbondAllMatureValidators(ctx)
|
||||
require.EqualError(err, "unexpected validator in unbonding queue; status was not unbonding")
|
||||
|
||||
validator.Status = stakingtypes.Unbonding
|
||||
keeper.SetValidator(ctx, validator)
|
||||
keeper.UnbondAllMatureValidators(ctx)
|
||||
validator, found := keeper.GetValidator(ctx, valAddr)
|
||||
require.False(found)
|
||||
require.NoError(keeper.SetValidator(ctx, validator))
|
||||
require.NoError(keeper.UnbondAllMatureValidators(ctx))
|
||||
validator, err = keeper.GetValidator(ctx, valAddr)
|
||||
require.ErrorIs(err, stakingtypes.ErrNoValidatorFound)
|
||||
|
||||
keeper.SetUnbondingValidatorsQueue(ctx, endTime, endHeight, []string{valAddr.String()})
|
||||
require.NoError(keeper.SetUnbondingValidatorsQueue(ctx, endTime, endHeight, []string{valAddr.String()}))
|
||||
validator = testutil.NewValidator(s.T(), valAddr, valPubKey)
|
||||
validator, _ = validator.AddTokensFromDel(addTokens)
|
||||
validator.Status = stakingtypes.Unbonding
|
||||
keeper.SetValidator(ctx, validator)
|
||||
keeper.UnbondAllMatureValidators(ctx)
|
||||
validator, found = keeper.GetValidator(ctx, valAddr)
|
||||
require.True(found)
|
||||
require.NoError(keeper.SetValidator(ctx, validator))
|
||||
require.NoError(keeper.UnbondAllMatureValidators(ctx))
|
||||
validator, err = keeper.GetValidator(ctx, valAddr)
|
||||
require.NoError(err)
|
||||
require.Equal(stakingtypes.Unbonded, validator.Status)
|
||||
}
|
||||
|
||||
@ -59,9 +59,7 @@ func migrateValidatorsByPowerIndexKey(store storetypes.KVStore) {
|
||||
// migration includes:
|
||||
//
|
||||
// - Setting the Power Reduction param in the paramstore
|
||||
func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey) error {
|
||||
store := ctx.KVStore(storeKey)
|
||||
|
||||
func MigrateStore(ctx sdk.Context, store storetypes.KVStore) error {
|
||||
MigratePrefixAddress(store, v1.LastValidatorPowerKey)
|
||||
|
||||
MigratePrefixAddress(store, v1.ValidatorsKey)
|
||||
|
||||
@ -124,7 +124,7 @@ func TestStoreMigration(t *testing.T) {
|
||||
}
|
||||
|
||||
// Run migrations.
|
||||
err := v2.MigrateStore(ctx, stakingKey)
|
||||
err := v2.MigrateStore(ctx, store)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Make sure the new keys are set and old keys are deleted.
|
||||
|
||||
@ -23,7 +23,7 @@ type subspace interface {
|
||||
// The migration includes:
|
||||
//
|
||||
// - Setting the MinCommissionRate param in the paramstore
|
||||
func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec, paramstore exported.Subspace) error {
|
||||
func MigrateStore(ctx sdk.Context, store storetypes.KVStore, cdc codec.BinaryCodec, paramstore exported.Subspace) error {
|
||||
migrateParamsStore(ctx, paramstore.(subspace))
|
||||
|
||||
return nil
|
||||
|
||||
@ -20,12 +20,13 @@ func TestStoreMigration(t *testing.T) {
|
||||
tStakingKey := storetypes.NewTransientStoreKey("transient_test")
|
||||
ctx := testutil.DefaultContext(stakingKey, tStakingKey)
|
||||
paramstore := paramtypes.NewSubspace(encCfg.Codec, encCfg.Amino, stakingKey, tStakingKey, "staking")
|
||||
store := ctx.KVStore(stakingKey)
|
||||
|
||||
// Check no params
|
||||
require.False(t, paramstore.Has(ctx, types.KeyMinCommissionRate))
|
||||
|
||||
// Run migrations.
|
||||
err := v3.MigrateStore(ctx, stakingKey, encCfg.Codec, paramstore)
|
||||
err := v3.MigrateStore(ctx, store, encCfg.Codec, paramstore)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Make sure the new params are set.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user