From 1be7d9805e0bb9f49ebfedced8de607424a4300d Mon Sep 17 00:00:00 2001 From: Facundo Medica <14063057+facundomedica@users.noreply.github.com> Date: Fri, 16 Jun 2023 20:40:44 +0200 Subject: [PATCH] refactor(x/staking)!: KVStoreService, return errors and use context.Context (#16324) Co-authored-by: Aleksandr Bezobchuk --- CHANGELOG.md | 2 + simapp/app.go | 2 +- simapp/export.go | 27 +- simapp/test_helpers.go | 6 +- .../auth/migrations/v2/store_test.go | 112 ++- .../distribution/keeper/msg_server_test.go | 13 +- .../evidence/keeper/infraction_test.go | 62 +- tests/integration/gov/keeper/keeper_test.go | 2 +- .../slashing/keeper/keeper_test.go | 40 +- .../integration/staking/keeper/common_test.go | 16 +- .../staking/keeper/delegation_test.go | 24 +- .../staking/keeper/determinstic_test.go | 47 +- .../staking/keeper/genesis_test.go | 26 +- .../staking/keeper/grpc_query_test.go | 12 +- .../staking/keeper/msg_server_test.go | 17 +- .../integration/staking/keeper/slash_test.go | 138 +-- .../staking/keeper/unbonding_test.go | 51 +- .../staking/keeper/validator_test.go | 125 ++- .../staking/simulation/operations_test.go | 24 +- testutil/sims/address_helpers.go | 15 +- x/distribution/keeper/allocation.go | 12 +- x/distribution/keeper/allocation_test.go | 12 +- x/distribution/keeper/delegation.go | 18 +- x/distribution/keeper/delegation_test.go | 58 +- x/distribution/keeper/grpc_query.go | 92 +- x/distribution/keeper/hooks.go | 47 +- x/distribution/keeper/invariants.go | 24 +- x/distribution/keeper/keeper.go | 17 +- x/distribution/keeper/msg_server.go | 7 +- x/distribution/keeper/validator.go | 5 +- x/distribution/simulation/operations.go | 17 +- x/distribution/simulation/operations_test.go | 3 +- .../testutil/expected_keepers_mocks.go | 54 +- x/distribution/types/expected_keepers.go | 24 +- x/evidence/go.mod | 2 +- x/evidence/go.sum | 2 + x/evidence/keeper/infraction.go | 7 +- x/evidence/testutil/expected_keepers_mocks.go | 10 +- x/evidence/types/expected_keepers.go | 4 +- x/genutil/testutil/expected_keepers_mocks.go | 2 +- x/genutil/types/expected_keepers.go | 2 +- x/gov/keeper/common_test.go | 4 +- x/gov/keeper/tally.go | 21 +- x/gov/testutil/expected_keepers.go | 4 +- x/gov/testutil/expected_keepers_mocks.go | 24 +- x/gov/types/expected_keepers.go | 10 +- x/mint/abci.go | 15 +- x/mint/keeper/keeper.go | 10 +- x/mint/keeper/keeper_test.go | 12 +- x/mint/testutil/expected_keepers_mocks.go | 10 +- x/mint/types/expected_keepers.go | 4 +- x/params/proposal_handler_test.go | 8 +- x/params/testutil/staking_keeper_mock.go | 7 +- x/slashing/abci_test.go | 20 +- x/slashing/app_test.go | 5 +- x/slashing/keeper/genesis_test.go | 2 +- x/slashing/keeper/hooks.go | 37 +- x/slashing/keeper/hooks_test.go | 2 +- x/slashing/keeper/infractions.go | 18 +- x/slashing/keeper/keeper.go | 6 +- x/slashing/keeper/keeper_test.go | 8 +- x/slashing/keeper/msg_server_test.go | 24 +- x/slashing/keeper/unjail.go | 16 +- x/slashing/simulation/operations.go | 13 +- x/slashing/testutil/expected_keepers_mocks.go | 78 +- x/slashing/types/expected_keepers.go | 44 +- x/staking/app_test.go | 23 +- x/staking/client/cli/tx_test.go | 16 +- x/staking/genesis.go | 5 +- x/staking/keeper/abci.go | 9 +- x/staking/keeper/alias_functions.go | 111 ++- x/staking/keeper/delegation.go | 895 ++++++++++++------ x/staking/keeper/delegation_test.go | 397 ++++---- x/staking/keeper/genesis.go | 101 +- x/staking/keeper/grpc_query.go | 131 ++- x/staking/keeper/grpc_query_test.go | 2 +- x/staking/keeper/historical_info.go | 95 +- x/staking/keeper/historical_info_test.go | 53 +- x/staking/keeper/invariants.go | 42 +- x/staking/keeper/keeper.go | 91 +- x/staking/keeper/keeper_test.go | 20 +- x/staking/keeper/migrations.go | 13 +- x/staking/keeper/msg_server.go | 141 +-- x/staking/keeper/msg_server_test.go | 24 +- x/staking/keeper/params.go | 57 +- x/staking/keeper/pool.go | 78 +- x/staking/keeper/power_reduction.go | 7 +- x/staking/keeper/query_utils.go | 90 +- x/staking/keeper/slash.go | 118 ++- x/staking/keeper/slash_test.go | 30 +- x/staking/keeper/test_common.go | 39 +- x/staking/keeper/unbonding.go | 314 +++--- x/staking/keeper/unbonding_test.go | 104 +- x/staking/keeper/val_state_change.go | 182 ++-- x/staking/keeper/validator.go | 434 +++++---- x/staking/keeper/validator_test.go | 193 ++-- x/staking/migrations/v2/store.go | 4 +- x/staking/migrations/v2/store_test.go | 2 +- x/staking/migrations/v3/store.go | 2 +- x/staking/migrations/v3/store_test.go | 3 +- x/staking/migrations/v4/migrations_test.go | 2 +- x/staking/migrations/v4/store.go | 4 +- x/staking/migrations/v5/migrations_test.go | 9 +- x/staking/migrations/v5/store.go | 10 +- x/staking/module.go | 11 +- x/staking/simulation/operations.go | 123 ++- x/staking/testutil/expected_keepers_mocks.go | 98 +- x/staking/testutil/helpers.go | 10 +- x/staking/types/errors.go | 7 +- x/staking/types/expected_keepers.go | 62 +- x/staking/types/hooks.go | 24 +- 111 files changed, 3566 insertions(+), 2202 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 015fa223b3d7..f7ba5799b129 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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: diff --git a/simapp/app.go b/simapp/app.go index 7f8d69385a71..feed299e107e 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -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()) diff --git a/simapp/export.go b/simapp/export.go index 9b233dc74680..21f0394fbea4 100644 --- a/simapp/export.go +++ b/simapp/export.go @@ -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) } diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index bb36b5ee2d5f..f81e99857495 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -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) diff --git a/tests/integration/auth/migrations/v2/store_test.go b/tests/integration/auth/migrations/v2/store_test.go index bcc3a29c18a1..24abfade89e1 100644 --- a/tests/integration/auth/migrations/v2/store_test.go +++ b/tests/integration/auth/migrations/v2/store_test.go @@ -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( diff --git a/tests/integration/distribution/keeper/msg_server_test.go b/tests/integration/distribution/keeper/msg_server_test.go index c26f7c267b66..77903dd92fb5 100644 --- a/tests/integration/distribution/keeper/msg_server_test.go +++ b/tests/integration/distribution/keeper/msg_server_test.go @@ -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", diff --git a/tests/integration/evidence/keeper/infraction_test.go b/tests/integration/evidence/keeper/infraction_test.go index 13816e90ad8d..03268cdaa366 100644 --- a/tests/integration/evidence/keeper/infraction_test.go +++ b/tests/integration/evidence/keeper/infraction_test.go @@ -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) { diff --git a/tests/integration/gov/keeper/keeper_test.go b/tests/integration/gov/keeper/keeper_test.go index 0a4455b93d35..4d2a6b75404b 100644 --- a/tests/integration/gov/keeper/keeper_test.go +++ b/tests/integration/gov/keeper/keeper_test.go @@ -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()) diff --git a/tests/integration/slashing/keeper/keeper_test.go b/tests/integration/slashing/keeper/keeper_test.go index c7eb5f36631a..a31a8f080bfb 100644 --- a/tests/integration/slashing/keeper/keeper_test.go +++ b/tests/integration/slashing/keeper/keeper_test.go @@ -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) diff --git a/tests/integration/staking/keeper/common_test.go b/tests/integration/staking/keeper/common_test.go index 853a506810e3..5a6334715a1a 100644 --- a/tests/integration/staking/keeper/common_test.go +++ b/tests/integration/staking/keeper/common_test.go @@ -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, diff --git a/tests/integration/staking/keeper/delegation_test.go b/tests/integration/staking/keeper/delegation_test.go index 3d30da540d41..42e268e2a738 100644 --- a/tests/integration/staking/keeper/delegation_test.go +++ b/tests/integration/staking/keeper/delegation_test.go @@ -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 diff --git a/tests/integration/staking/keeper/determinstic_test.go b/tests/integration/staking/keeper/determinstic_test.go index cd0ab10e216f..4117e4616f7e 100644 --- a/tests/integration/staking/keeper/determinstic_test.go +++ b/tests/integration/staking/keeper/determinstic_test.go @@ -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, diff --git a/tests/integration/staking/keeper/genesis_test.go b/tests/integration/staking/keeper/genesis_test.go index 68be2c93e5e4..3ef026278452 100644 --- a/tests/integration/staking/keeper/genesis_test.go +++ b/tests/integration/staking/keeper/genesis_test.go @@ -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( diff --git a/tests/integration/staking/keeper/grpc_query_test.go b/tests/integration/staking/keeper/grpc_query_test.go index de9b774a5ab4..cd423c52bd34 100644 --- a/tests/integration/staking/keeper/grpc_query_test.go +++ b/tests/integration/staking/keeper/grpc_query_test.go @@ -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) { diff --git a/tests/integration/staking/keeper/msg_server_test.go b/tests/integration/staking/keeper/msg_server_test.go index 9c08804f577c..cb8fb6b48f97 100644 --- a/tests/integration/staking/keeper/msg_server_test.go +++ b/tests/integration/staking/keeper/msg_server_test.go @@ -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", diff --git a/tests/integration/staking/keeper/slash_test.go b/tests/integration/staking/keeper/slash_test.go index 6beea0b0b3e9..7c4c162eb778 100644 --- a/tests/integration/staking/keeper/slash_test.go +++ b/tests/integration/staking/keeper/slash_test.go @@ -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)) } diff --git a/tests/integration/staking/keeper/unbonding_test.go b/tests/integration/staking/keeper/unbonding_test.go index b61fc93653ac..4e9bb12d1156 100644 --- a/tests/integration/staking/keeper/unbonding_test.go +++ b/tests/integration/staking/keeper/unbonding_test.go @@ -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)) } diff --git a/tests/integration/staking/keeper/validator_test.go b/tests/integration/staking/keeper/validator_test.go index 3cf24ad300ed..aa982d2dacf4 100644 --- a/tests/integration/staking/keeper/validator_test.go +++ b/tests/integration/staking/keeper/validator_test.go @@ -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) diff --git a/tests/integration/staking/simulation/operations_test.go b/tests/integration/staking/simulation/operations_test.go index a011db97cd40..97d4f566184e 100644 --- a/tests/integration/staking/simulation/operations_test.go +++ b/tests/integration/staking/simulation/operations_test.go @@ -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 } diff --git a/testutil/sims/address_helpers.go b/testutil/sims/address_helpers.go index 52f1db8faffe..4bd7ef65e415 100644 --- a/testutil/sims/address_helpers.go +++ b/testutil/sims/address_helpers.go @@ -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) diff --git a/x/distribution/keeper/allocation.go b/x/distribution/keeper/allocation.go index 9f460f8e99f3..4925def82fbf 100644 --- a/x/distribution/keeper/allocation.go +++ b/x/distribution/keeper/allocation.go @@ -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 } diff --git a/x/distribution/keeper/allocation_test.go b/x/distribution/keeper/allocation_test.go index fc1d4f97c11e..dd67e4017f20 100644 --- a/x/distribution/keeper/allocation_test.go +++ b/x/distribution/keeper/allocation_test.go @@ -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(), diff --git a/x/distribution/keeper/delegation.go b/x/distribution/keeper/delegation.go index ea61b35adb4e..69befb094051 100644 --- a/x/distribution/keeper/delegation.go +++ b/x/distribution/keeper/delegation.go @@ -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()))) } diff --git a/x/distribution/keeper/delegation_test.go b/x/distribution/keeper/delegation_test.go index 125723658c1e..b037f396c0d5 100644 --- a/x/distribution/keeper/delegation_test.go +++ b/x/distribution/keeper/delegation_test.go @@ -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) diff --git a/x/distribution/keeper/grpc_query.go b/x/distribution/keeper/grpc_query.go index ddcb0bbe5cb8..d08052f8d412 100644 --- a/x/distribution/keeper/grpc_query.go +++ b/x/distribution/keeper/grpc_query.go @@ -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 } diff --git a/x/distribution/keeper/hooks.go b/x/distribution/keeper/hooks.go index ab6aca15d0a4..c28b179b2054 100644 --- a/x/distribution/keeper/hooks.go +++ b/x/distribution/keeper/hooks.go @@ -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 } diff --git a/x/distribution/keeper/invariants.go b/x/distribution/keeper/invariants.go index f66242134ceb..133f239a8101 100644 --- a/x/distribution/keeper/invariants.go +++ b/x/distribution/keeper/invariants.go @@ -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) { diff --git a/x/distribution/keeper/keeper.go b/x/distribution/keeper/keeper.go index 163a83025a22..a36ff470c4c7 100644 --- a/x/distribution/keeper/keeper.go +++ b/x/distribution/keeper/keeper.go @@ -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 } diff --git a/x/distribution/keeper/msg_server.go b/x/distribution/keeper/msg_server.go index e2b5e737d1dd..94c34588abc1 100644 --- a/x/distribution/keeper/msg_server.go +++ b/x/distribution/keeper/msg_server.go @@ -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()) } diff --git a/x/distribution/keeper/validator.go b/x/distribution/keeper/validator.go index 2a6a69173a54..846249984546 100644 --- a/x/distribution/keeper/validator.go +++ b/x/distribution/keeper/validator.go @@ -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) diff --git a/x/distribution/simulation/operations.go b/x/distribution/simulation/operations.go index 29f12ecc3130..a6dc26963049 100644 --- a/x/distribution/simulation/operations.go +++ b/x/distribution/simulation/operations.go @@ -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 } diff --git a/x/distribution/simulation/operations_test.go b/x/distribution/simulation/operations_test.go index b5f7a8eabd73..4dedb3c11c84 100644 --- a/x/distribution/simulation/operations_test.go +++ b/x/distribution/simulation/operations_test.go @@ -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 } diff --git a/x/distribution/testutil/expected_keepers_mocks.go b/x/distribution/testutil/expected_keepers_mocks.go index c4d2ab9eea77..0262a57fc1c0 100644 --- a/x/distribution/testutil/expected_keepers_mocks.go +++ b/x/distribution/testutil/expected_keepers_mocks.go @@ -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. diff --git a/x/distribution/types/expected_keepers.go b/x/distribution/types/expected_keepers.go index fde51dc75169..75090b6914ca 100644 --- a/x/distribution/types/expected_keepers.go +++ b/x/distribution/types/expected_keepers.go @@ -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 } diff --git a/x/evidence/go.mod b/x/evidence/go.mod index 5e812f2cbc25..7da4a0553117 100644 --- a/x/evidence/go.mod +++ b/x/evidence/go.mod @@ -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 diff --git a/x/evidence/go.sum b/x/evidence/go.sum index a00fe9c3b75a..97435f5c341c 100644 --- a/x/evidence/go.sum +++ b/x/evidence/go.sum @@ -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= diff --git a/x/evidence/keeper/infraction.go b/x/evidence/keeper/infraction.go index 04f18db3eac7..e9655ccbd8b8 100644 --- a/x/evidence/keeper/infraction.go +++ b/x/evidence/keeper/infraction.go @@ -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. diff --git a/x/evidence/testutil/expected_keepers_mocks.go b/x/evidence/testutil/expected_keepers_mocks.go index cbfc0dd44a71..400a48a69472 100644 --- a/x/evidence/testutil/expected_keepers_mocks.go +++ b/x/evidence/testutil/expected_keepers_mocks.go @@ -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. diff --git a/x/evidence/types/expected_keepers.go b/x/evidence/types/expected_keepers.go index cca18222cc9b..75c942e790c3 100644 --- a/x/evidence/types/expected_keepers.go +++ b/x/evidence/types/expected_keepers.go @@ -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 diff --git a/x/genutil/testutil/expected_keepers_mocks.go b/x/genutil/testutil/expected_keepers_mocks.go index 1b33fb0d3092..434c83bacaaa 100644 --- a/x/genutil/testutil/expected_keepers_mocks.go +++ b/x/genutil/testutil/expected_keepers_mocks.go @@ -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) diff --git a/x/genutil/types/expected_keepers.go b/x/genutil/types/expected_keepers.go index 634109a7e1e5..3cffa44409ba 100644 --- a/x/genutil/types/expected_keepers.go +++ b/x/genutil/types/expected_keepers.go @@ -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) diff --git a/x/gov/keeper/common_test.go b/x/gov/keeper/common_test.go index 7e3f0c466066..fb87ed94bfbd 100644 --- a/x/gov/keeper/common_test.go +++ b/x/gov/keeper/common_test.go @@ -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 diff --git a/x/gov/keeper/tally.go b/x/gov/keeper/tally.go index acd79d7abb64..1cb7d53546bc 100644 --- a/x/gov/keeper/tally.go +++ b/x/gov/keeper/tally.go @@ -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 diff --git a/x/gov/testutil/expected_keepers.go b/x/gov/testutil/expected_keepers.go index 0ac7521a2d2d..ed6994662bca 100644 --- a/x/gov/testutil/expected_keepers.go +++ b/x/gov/testutil/expected_keepers.go @@ -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 diff --git a/x/gov/testutil/expected_keepers_mocks.go b/x/gov/testutil/expected_keepers_mocks.go index 92c8a5574130..cf036c1a98c6 100644 --- a/x/gov/testutil/expected_keepers_mocks.go +++ b/x/gov/testutil/expected_keepers_mocks.go @@ -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. diff --git a/x/gov/types/expected_keepers.go b/x/gov/types/expected_keepers.go index 859b3a87c299..4a1917c437e7 100644 --- a/x/gov/types/expected_keepers.go +++ b/x/gov/types/expected_keepers.go @@ -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) diff --git a/x/mint/abci.go b/x/mint/abci.go index 2e4b699971a1..b225fa0e1fdd 100644 --- a/x/mint/abci.go +++ b/x/mint/abci.go @@ -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 } diff --git a/x/mint/keeper/keeper.go b/x/mint/keeper/keeper.go index 0eceb52ab50e..ddb6b14acf5c 100644 --- a/x/mint/keeper/keeper.go +++ b/x/mint/keeper/keeper.go @@ -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 diff --git a/x/mint/keeper/keeper_test.go b/x/mint/keeper/keeper_test.go index f3d5602ea60d..2ee25b6a53a5 100644 --- a/x/mint/keeper/keeper_test.go +++ b/x/mint/keeper/keeper_test.go @@ -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) diff --git a/x/mint/testutil/expected_keepers_mocks.go b/x/mint/testutil/expected_keepers_mocks.go index 723e1effb1dc..26be50dd5327 100644 --- a/x/mint/testutil/expected_keepers_mocks.go +++ b/x/mint/testutil/expected_keepers_mocks.go @@ -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. diff --git a/x/mint/types/expected_keepers.go b/x/mint/types/expected_keepers.go index 1b04abfa9f3a..82edcc6a2092 100644 --- a/x/mint/types/expected_keepers.go +++ b/x/mint/types/expected_keepers.go @@ -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. diff --git a/x/params/proposal_handler_test.go b/x/params/proposal_handler_test.go index 5b36ea9f067e..4816f84c02e4 100644 --- a/x/params/proposal_handler_test.go +++ b/x/params/proposal_handler_test.go @@ -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, diff --git a/x/params/testutil/staking_keeper_mock.go b/x/params/testutil/staking_keeper_mock.go index a90f80ad43ae..bc5a94ffb50b 100644 --- a/x/params/testutil/staking_keeper_mock.go +++ b/x/params/testutil/staking_keeper_mock.go @@ -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. diff --git a/x/slashing/abci_test.go b/x/slashing/abci_test.go index 79c5fbbcffb7..407950fca251 100644 --- a/x/slashing/abci_test.go +++ b/x/slashing/abci_test.go @@ -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()) } diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index 9add8e28167d..833d5af756f3 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -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())) diff --git a/x/slashing/keeper/genesis_test.go b/x/slashing/keeper/genesis_test.go index eac73841f166..b5eedcc08bba 100644 --- a/x/slashing/keeper/genesis_test.go +++ b/x/slashing/keeper/genesis_test.go @@ -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 diff --git a/x/slashing/keeper/hooks.go b/x/slashing/keeper/hooks.go index 0a307d1e72db..42bf403d4eda 100644 --- a/x/slashing/keeper/hooks.go +++ b/x/slashing/keeper/hooks.go @@ -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 } diff --git a/x/slashing/keeper/hooks_test.go b/x/slashing/keeper/hooks_test.go index d9c592ffc15b..35d399981603 100644 --- a/x/slashing/keeper/hooks_test.go +++ b/x/slashing/keeper/hooks_test.go @@ -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) diff --git a/x/slashing/keeper/infractions.go b/x/slashing/keeper/infractions.go index 5a6fee86d6a4..57f3e0df86cb 100644 --- a/x/slashing/keeper/infractions.go +++ b/x/slashing/keeper/infractions.go @@ -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, diff --git a/x/slashing/keeper/keeper.go b/x/slashing/keeper/keeper.go index 374f702f0675..5e8e41524167 100644 --- a/x/slashing/keeper/keeper.go +++ b/x/slashing/keeper/keeper.go @@ -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, diff --git a/x/slashing/keeper/keeper_test.go b/x/slashing/keeper/keeper_test.go index 83f44bba3359..d514e685861a 100644 --- a/x/slashing/keeper/keeper_test.go +++ b/x/slashing/keeper/keeper_test.go @@ -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) } diff --git a/x/slashing/keeper/msg_server_test.go b/x/slashing/keeper/msg_server_test.go index cb401957771e..29f066acf01d 100644 --- a/x/slashing/keeper/msg_server_test.go +++ b/x/slashing/keeper/msg_server_test.go @@ -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(), diff --git a/x/slashing/keeper/unjail.go b/x/slashing/keeper/unjail.go index 92168dc2c76a..b3ab0706e243 100644 --- a/x/slashing/keeper/unjail.go +++ b/x/slashing/keeper/unjail.go @@ -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) } diff --git a/x/slashing/simulation/operations.go b/x/slashing/simulation/operations.go index a2618a522c5a..839edc172fa1 100644 --- a/x/slashing/simulation/operations.go +++ b/x/slashing/simulation/operations.go @@ -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 } diff --git a/x/slashing/testutil/expected_keepers_mocks.go b/x/slashing/testutil/expected_keepers_mocks.go index 037343fb226f..a9e6ce81d2d6 100644 --- a/x/slashing/testutil/expected_keepers_mocks.go +++ b/x/slashing/testutil/expected_keepers_mocks.go @@ -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) diff --git a/x/slashing/types/expected_keepers.go b/x/slashing/types/expected_keepers.go index 2e57cf09d28a..468a8700bd28 100644 --- a/x/slashing/types/expected_keepers.go +++ b/x/slashing/types/expected_keepers.go @@ -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 } diff --git a/x/staking/app_test.go b/x/staking/app_test.go index 4749eb6a30c5..5f72696e1862 100644 --- a/x/staking/app_test.go +++ b/x/staking/app_test.go @@ -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))) diff --git a/x/staking/client/cli/tx_test.go b/x/staking/client/cli/tx_test.go index 1e43f2e3a86c..8b9c8195c65a 100644 --- a/x/staking/client/cli/tx_test.go +++ b/x/staking/client/cli/tx_test.go @@ -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) }) } } diff --git a/x/staking/genesis.go b/x/staking/genesis.go index 7e2cf1efe04a..1d4cd64e4bba 100644 --- a/x/staking/genesis.go +++ b/x/staking/genesis.go @@ -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 } diff --git a/x/staking/keeper/abci.go b/x/staking/keeper/abci.go index b8e91bc6fa7d..6a21b2b02300 100644 --- a/x/staking/keeper/abci.go +++ b/x/staking/keeper/abci.go @@ -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) } diff --git a/x/staking/keeper/alias_functions.go b/x/staking/keeper/alias_functions.go index 8660d7735d9d..0047b92192c0 100644 --- a/x/staking/keeper/alias_functions.go +++ b/x/staking/keeper/alias_functions.go @@ -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) } diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 0047ef5414b6..bd30d7655355 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -2,9 +2,12 @@ package keeper import ( "bytes" + "context" + "errors" "fmt" "time" + corestore "cosmossdk.io/core/store" "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" @@ -16,25 +19,29 @@ import ( ) // GetDelegation returns a specific delegation. -func (k Keeper) GetDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (delegation types.Delegation, found bool) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) GetDelegation(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (types.Delegation, error) { + store := k.storeService.OpenKVStore(ctx) key := types.GetDelegationKey(delAddr, valAddr) - value := store.Get(key) - if value == nil { - return delegation, false + value, err := store.Get(key) + if err != nil { + return types.Delegation{}, err } - delegation = types.MustUnmarshalDelegation(k.cdc, value) + if value == nil { + return types.Delegation{}, types.ErrNoDelegation + } - return delegation, true + return types.UnmarshalDelegation(k.cdc, value) } // IterateAllDelegations iterates through all of the delegations. -func (k Keeper) IterateAllDelegations(ctx sdk.Context, cb func(delegation types.Delegation) (stop bool)) { - store := ctx.KVStore(k.storeKey) - - iterator := storetypes.KVStorePrefixIterator(store, types.DelegationKey) +func (k Keeper) IterateAllDelegations(ctx context.Context, cb func(delegation types.Delegation) (stop bool)) error { + store := k.storeService.OpenKVStore(ctx) + iterator, err := store.Iterator(types.DelegationKey, storetypes.PrefixEndBytes(types.DelegationKey)) + if err != nil { + return err + } defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -43,84 +50,102 @@ func (k Keeper) IterateAllDelegations(ctx sdk.Context, cb func(delegation types. break } } + + return nil } // GetAllDelegations returns all delegations used during genesis dump. -func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegation) { - k.IterateAllDelegations(ctx, func(delegation types.Delegation) bool { +func (k Keeper) GetAllDelegations(ctx context.Context) (delegations []types.Delegation, err error) { + err = k.IterateAllDelegations(ctx, func(delegation types.Delegation) bool { delegations = append(delegations, delegation) return false }) - return delegations + return delegations, err } // GetValidatorDelegations returns all delegations to a specific validator. // Useful for querier. -func (k Keeper) GetValidatorDelegations(ctx sdk.Context, valAddr sdk.ValAddress) (delegations []types.Delegation) { - store := ctx.KVStore(k.storeKey) - - iterator := storetypes.KVStorePrefixIterator(store, types.GetDelegationsByValPrefixKey(valAddr)) +func (k Keeper) GetValidatorDelegations(ctx context.Context, valAddr sdk.ValAddress) (delegations []types.Delegation, err error) { + store := k.storeService.OpenKVStore(ctx) + prefix := types.GetDelegationsByValPrefixKey(valAddr) + iterator, err := store.Iterator(prefix, storetypes.PrefixEndBytes(prefix)) + if err != nil { + return delegations, err + } defer iterator.Close() for ; iterator.Valid(); iterator.Next() { var delegation types.Delegation valAddr, delAddr, err := types.ParseDelegationsByValKey(iterator.Key()) if err != nil { - panic(err) + return delegations, err + } + + bz, err := store.Get(types.GetDelegationKey(delAddr, valAddr)) + if err != nil { + return delegations, err } - bz := store.Get(types.GetDelegationKey(delAddr, valAddr)) if err := k.cdc.Unmarshal(bz, &delegation); err != nil { - panic(err) + return delegations, err } delegations = append(delegations, delegation) } - return delegations + return delegations, nil } // GetDelegatorDelegations returns a given amount of all the delegations from a // delegator. -func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve uint16) (delegations []types.Delegation) { +func (k Keeper) GetDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) (delegations []types.Delegation, err error) { delegations = make([]types.Delegation, maxRetrieve) - store := ctx.KVStore(k.storeKey) + store := k.storeService.OpenKVStore(ctx) delegatorPrefixKey := types.GetDelegationsKey(delegator) - iterator := storetypes.KVStorePrefixIterator(store, delegatorPrefixKey) + iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) + if err != nil { + return delegations, err + } defer iterator.Close() i := 0 for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() { - delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value()) + delegation, err := types.UnmarshalDelegation(k.cdc, iterator.Value()) + if err != nil { + return delegations, err + } delegations[i] = delegation i++ } - return delegations[:i] // trim if the array length < maxRetrieve + return delegations[:i], nil // trim if the array length < maxRetrieve } // SetDelegation sets a delegation. -func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) { +func (k Keeper) SetDelegation(ctx context.Context, delegation types.Delegation) error { delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(delegation.DelegatorAddress) if err != nil { - panic(err) + return err } - store := ctx.KVStore(k.storeKey) + store := k.storeService.OpenKVStore(ctx) b := types.MustMarshalDelegation(k.cdc, delegation) - store.Set(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr()), b) + err = store.Set(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr()), b) + if err != nil { + return err + } // set the delegation in validator delegator index - store.Set(types.GetDelegationsByValKey(delegation.GetValidatorAddr(), delegatorAddress), []byte{}) + return store.Set(types.GetDelegationsByValKey(delegation.GetValidatorAddr(), delegatorAddress), []byte{}) } // RemoveDelegation removes a delegation -func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) error { +func (k Keeper) RemoveDelegation(ctx context.Context, delegation types.Delegation) error { delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(delegation.DelegatorAddress) if err != nil { - panic(err) + return err } // TODO: Consider calling hooks outside of the store wrapper functions, it's unobvious. @@ -128,233 +153,301 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) e return err } - store := ctx.KVStore(k.storeKey) - store.Delete(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr())) - store.Delete(types.GetDelegationsByValKey(delegation.GetValidatorAddr(), delegatorAddress)) + store := k.storeService.OpenKVStore(ctx) + err = store.Delete(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr())) + if err != nil { + return err + } - return nil + return store.Delete(types.GetDelegationsByValKey(delegation.GetValidatorAddr(), delegatorAddress)) } // GetUnbondingDelegations returns a given amount of all the delegator unbonding-delegations. -func (k Keeper) GetUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve uint16) (unbondingDelegations []types.UnbondingDelegation) { +func (k Keeper) GetUnbondingDelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) (unbondingDelegations []types.UnbondingDelegation, err error) { unbondingDelegations = make([]types.UnbondingDelegation, maxRetrieve) - store := ctx.KVStore(k.storeKey) + store := k.storeService.OpenKVStore(ctx) delegatorPrefixKey := types.GetUBDsKey(delegator) - iterator := storetypes.KVStorePrefixIterator(store, delegatorPrefixKey) + iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) + if err != nil { + return unbondingDelegations, err + } defer iterator.Close() i := 0 for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() { - unbondingDelegation := types.MustUnmarshalUBD(k.cdc, iterator.Value()) + unbondingDelegation, err := types.UnmarshalUBD(k.cdc, iterator.Value()) + if err != nil { + return unbondingDelegations, err + } unbondingDelegations[i] = unbondingDelegation i++ } - return unbondingDelegations[:i] // trim if the array length < maxRetrieve + return unbondingDelegations[:i], nil // trim if the array length < maxRetrieve } // GetUnbondingDelegation returns a unbonding delegation. -func (k Keeper) GetUnbondingDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (ubd types.UnbondingDelegation, found bool) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) GetUnbondingDelegation(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (ubd types.UnbondingDelegation, err error) { + store := k.storeService.OpenKVStore(ctx) key := types.GetUBDKey(delAddr, valAddr) - value := store.Get(key) + value, err := store.Get(key) + if err != nil { + return ubd, err + } if value == nil { - return ubd, false + return ubd, types.ErrNoUnbondingDelegation } - ubd = types.MustUnmarshalUBD(k.cdc, value) - - return ubd, true + return types.UnmarshalUBD(k.cdc, value) } // GetUnbondingDelegationsFromValidator returns all unbonding delegations from a // particular validator. -func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sdk.ValAddress) (ubds []types.UnbondingDelegation) { - store := ctx.KVStore(k.storeKey) - - iterator := storetypes.KVStorePrefixIterator(store, types.GetUBDsByValIndexKey(valAddr)) +func (k Keeper) GetUnbondingDelegationsFromValidator(ctx context.Context, valAddr sdk.ValAddress) (ubds []types.UnbondingDelegation, err error) { + store := k.storeService.OpenKVStore(ctx) + prefix := types.GetUBDsByValIndexKey(valAddr) + iterator, err := store.Iterator(prefix, storetypes.PrefixEndBytes(prefix)) + if err != nil { + return ubds, err + } defer iterator.Close() for ; iterator.Valid(); iterator.Next() { key := types.GetUBDKeyFromValIndexKey(iterator.Key()) - value := store.Get(key) - ubd := types.MustUnmarshalUBD(k.cdc, value) + value, err := store.Get(key) + if err != nil { + return ubds, err + } + ubd, err := types.UnmarshalUBD(k.cdc, value) + if err != nil { + return ubds, err + } ubds = append(ubds, ubd) } - return ubds + return ubds, nil } // IterateUnbondingDelegations iterates through all of the unbonding delegations. -func (k Keeper) IterateUnbondingDelegations(ctx sdk.Context, fn func(index int64, ubd types.UnbondingDelegation) (stop bool)) { - store := ctx.KVStore(k.storeKey) - - iterator := storetypes.KVStorePrefixIterator(store, types.UnbondingDelegationKey) +func (k Keeper) IterateUnbondingDelegations(ctx context.Context, fn func(index int64, ubd types.UnbondingDelegation) (stop bool)) error { + store := k.storeService.OpenKVStore(ctx) + prefix := types.UnbondingDelegationKey + iterator, err := store.Iterator(prefix, storetypes.PrefixEndBytes(prefix)) + if err != nil { + return err + } defer iterator.Close() for i := int64(0); iterator.Valid(); iterator.Next() { - ubd := types.MustUnmarshalUBD(k.cdc, iterator.Value()) + ubd, err := types.UnmarshalUBD(k.cdc, iterator.Value()) + if err != nil { + return err + } if stop := fn(i, ubd); stop { break } i++ } + + return nil } // GetDelegatorUnbonding returns the total amount a delegator has unbonding. -func (k Keeper) GetDelegatorUnbonding(ctx sdk.Context, delegator sdk.AccAddress) math.Int { +func (k Keeper) GetDelegatorUnbonding(ctx context.Context, delegator sdk.AccAddress) (math.Int, error) { unbonding := math.ZeroInt() - k.IterateDelegatorUnbondingDelegations(ctx, delegator, func(ubd types.UnbondingDelegation) bool { + err := k.IterateDelegatorUnbondingDelegations(ctx, delegator, func(ubd types.UnbondingDelegation) bool { for _, entry := range ubd.Entries { unbonding = unbonding.Add(entry.Balance) } return false }) - return unbonding + return unbonding, err } // IterateDelegatorUnbondingDelegations iterates through a delegator's unbonding delegations. -func (k Keeper) IterateDelegatorUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, cb func(ubd types.UnbondingDelegation) (stop bool)) { - store := ctx.KVStore(k.storeKey) - - iterator := storetypes.KVStorePrefixIterator(store, types.GetUBDsKey(delegator)) +func (k Keeper) IterateDelegatorUnbondingDelegations(ctx context.Context, delegator sdk.AccAddress, cb func(ubd types.UnbondingDelegation) (stop bool)) error { + store := k.storeService.OpenKVStore(ctx) + prefix := types.GetUBDsKey(delegator) + iterator, err := store.Iterator(prefix, storetypes.PrefixEndBytes(prefix)) + if err != nil { + return err + } defer iterator.Close() for ; iterator.Valid(); iterator.Next() { - ubd := types.MustUnmarshalUBD(k.cdc, iterator.Value()) + ubd, err := types.UnmarshalUBD(k.cdc, iterator.Value()) + if err != nil { + return err + } if cb(ubd) { break } } + + return nil } // GetDelegatorBonded returs the total amount a delegator has bonded. -func (k Keeper) GetDelegatorBonded(ctx sdk.Context, delegator sdk.AccAddress) math.Int { +func (k Keeper) GetDelegatorBonded(ctx context.Context, delegator sdk.AccAddress) (math.Int, error) { bonded := math.LegacyZeroDec() - k.IterateDelegatorDelegations(ctx, delegator, func(delegation types.Delegation) bool { + err := k.IterateDelegatorDelegations(ctx, delegator, func(delegation types.Delegation) bool { validatorAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress) if err != nil { panic(err) // shouldn't happen } - validator, found := k.GetValidator(ctx, validatorAddr) - if found { + validator, err := k.GetValidator(ctx, validatorAddr) + if err == nil { shares := delegation.Shares tokens := validator.TokensFromSharesTruncated(shares) bonded = bonded.Add(tokens) } return false }) - return bonded.RoundInt() + return bonded.RoundInt(), err } // IterateDelegatorDelegations iterates through one delegator's delegations. -func (k Keeper) IterateDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress, cb func(delegation types.Delegation) (stop bool)) { - store := ctx.KVStore(k.storeKey) - delegatorPrefixKey := types.GetDelegationsKey(delegator) - iterator := storetypes.KVStorePrefixIterator(store, delegatorPrefixKey) +func (k Keeper) IterateDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress, cb func(delegation types.Delegation) (stop bool)) error { + store := k.storeService.OpenKVStore(ctx) + prefix := types.GetDelegationsKey(delegator) + iterator, err := store.Iterator(prefix, storetypes.PrefixEndBytes(prefix)) + if err != nil { + return 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 err + } if cb(delegation) { break } } + return nil } // IterateDelegatorRedelegations iterates through one delegator's redelegations. -func (k Keeper) IterateDelegatorRedelegations(ctx sdk.Context, delegator sdk.AccAddress, cb func(red types.Redelegation) (stop bool)) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) IterateDelegatorRedelegations(ctx context.Context, delegator sdk.AccAddress, cb func(red types.Redelegation) (stop bool)) error { + store := k.storeService.OpenKVStore(ctx) delegatorPrefixKey := types.GetREDsKey(delegator) - - iterator := storetypes.KVStorePrefixIterator(store, delegatorPrefixKey) - defer iterator.Close() + iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) + if err != nil { + return err + } for ; iterator.Valid(); iterator.Next() { - red := types.MustUnmarshalRED(k.cdc, iterator.Value()) + red, err := types.UnmarshalRED(k.cdc, iterator.Value()) + if err != nil { + return err + } if cb(red) { break } } + return nil } // HasMaxUnbondingDelegationEntries - check if unbonding delegation has maximum number of entries. -func (k Keeper) HasMaxUnbondingDelegationEntries(ctx sdk.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) bool { - ubd, found := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) - if !found { - return false +func (k Keeper) HasMaxUnbondingDelegationEntries(ctx context.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) (bool, error) { + ubd, err := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) + if err != nil && !errors.Is(err, types.ErrNoUnbondingDelegation) { + return false, err } - return len(ubd.Entries) >= int(k.MaxEntries(ctx)) + maxEntries, err := k.MaxEntries(ctx) + if err != nil { + return false, err + } + return len(ubd.Entries) >= int(maxEntries), nil } // SetUnbondingDelegation sets the unbonding delegation and associated index. -func (k Keeper) SetUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) { +func (k Keeper) SetUnbondingDelegation(ctx context.Context, ubd types.UnbondingDelegation) error { delAddr, err := k.authKeeper.AddressCodec().StringToBytes(ubd.DelegatorAddress) if err != nil { - panic(err) + return err } - store := ctx.KVStore(k.storeKey) + store := k.storeService.OpenKVStore(ctx) bz := types.MustMarshalUBD(k.cdc, ubd) valAddr, err := sdk.ValAddressFromBech32(ubd.ValidatorAddress) if err != nil { - panic(err) + return err } key := types.GetUBDKey(delAddr, valAddr) - store.Set(key, bz) - store.Set(types.GetUBDByValIndexKey(delAddr, valAddr), []byte{}) // index, store empty bytes + err = store.Set(key, bz) + if err != nil { + return err + } + + return store.Set(types.GetUBDByValIndexKey(delAddr, valAddr), []byte{}) // index, store empty bytes } // RemoveUnbondingDelegation removes the unbonding delegation object and associated index. -func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) { +func (k Keeper) RemoveUnbondingDelegation(ctx context.Context, ubd types.UnbondingDelegation) error { delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(ubd.DelegatorAddress) if err != nil { - panic(err) + return err } - store := ctx.KVStore(k.storeKey) + store := k.storeService.OpenKVStore(ctx) addr, err := sdk.ValAddressFromBech32(ubd.ValidatorAddress) if err != nil { - panic(err) + return err } key := types.GetUBDKey(delegatorAddress, addr) - store.Delete(key) - store.Delete(types.GetUBDByValIndexKey(delegatorAddress, addr)) + err = store.Delete(key) + if err != nil { + return err + } + + return store.Delete(types.GetUBDByValIndexKey(delegatorAddress, addr)) } // SetUnbondingDelegationEntry adds an entry to the unbonding delegation at // the given addresses. It creates the unbonding delegation if it does not exist. func (k Keeper) SetUnbondingDelegationEntry( - ctx sdk.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress, + ctx context.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress, creationHeight int64, minTime time.Time, balance math.Int, -) types.UnbondingDelegation { - ubd, found := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) - id := k.IncrementUnbondingID(ctx) +) (types.UnbondingDelegation, error) { + id, err := k.IncrementUnbondingID(ctx) + if err != nil { + return types.UnbondingDelegation{}, err + } + isNewUbdEntry := true - if found { + ubd, err := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) + if err == nil { isNewUbdEntry = ubd.AddEntry(creationHeight, minTime, balance, id) - } else { + } else if errors.Is(err, types.ErrNoUnbondingDelegation) { ubd = types.NewUnbondingDelegation(delegatorAddr, validatorAddr, creationHeight, minTime, balance, id) + } else { + return ubd, err } - k.SetUnbondingDelegation(ctx, ubd) + if err = k.SetUnbondingDelegation(ctx, ubd); err != nil { + return ubd, err + } // only call the hook for new entries since // calls to AfterUnbondingInitiated are not idempotent if isNewUbdEntry { // Add to the UBDByUnbondingOp index to look up the UBD by the UBDE ID - k.SetUnbondingDelegationByUnbondingID(ctx, ubd, id) + if err = k.SetUnbondingDelegationByUnbondingID(ctx, ubd, id); err != nil { + return ubd, err + } if err := k.Hooks().AfterUnbondingInitiated(ctx, id); err != nil { k.Logger(ctx).Error("failed to call after unbonding initiated hook", "error", err) } } - return ubd + return ubd, nil } // unbonding delegation queue timeslice operations @@ -362,232 +455,304 @@ func (k Keeper) SetUnbondingDelegationEntry( // GetUBDQueueTimeSlice gets a specific unbonding queue timeslice. A timeslice // is a slice of DVPairs corresponding to unbonding delegations that expire at a // certain time. -func (k Keeper) GetUBDQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (dvPairs []types.DVPair) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) GetUBDQueueTimeSlice(ctx context.Context, timestamp time.Time) (dvPairs []types.DVPair, err error) { + store := k.storeService.OpenKVStore(ctx) - bz := store.Get(types.GetUnbondingDelegationTimeKey(timestamp)) - if bz == nil { - return []types.DVPair{} + bz, err := store.Get(types.GetUnbondingDelegationTimeKey(timestamp)) + if bz == nil || err != nil { + return []types.DVPair{}, err } pairs := types.DVPairs{} - k.cdc.MustUnmarshal(bz, &pairs) + err = k.cdc.Unmarshal(bz, &pairs) - return pairs.Pairs + return pairs.Pairs, err } // SetUBDQueueTimeSlice sets a specific unbonding queue timeslice. -func (k Keeper) SetUBDQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []types.DVPair) { - store := ctx.KVStore(k.storeKey) - bz := k.cdc.MustMarshal(&types.DVPairs{Pairs: keys}) - store.Set(types.GetUnbondingDelegationTimeKey(timestamp), bz) +func (k Keeper) SetUBDQueueTimeSlice(ctx context.Context, timestamp time.Time, keys []types.DVPair) error { + store := k.storeService.OpenKVStore(ctx) + bz, err := k.cdc.Marshal(&types.DVPairs{Pairs: keys}) + if err != nil { + return err + } + return store.Set(types.GetUnbondingDelegationTimeKey(timestamp), bz) } // InsertUBDQueue inserts an unbonding delegation to the appropriate timeslice // in the unbonding queue. -func (k Keeper) InsertUBDQueue(ctx sdk.Context, ubd types.UnbondingDelegation, completionTime time.Time) { +func (k Keeper) InsertUBDQueue(ctx context.Context, ubd types.UnbondingDelegation, completionTime time.Time) error { dvPair := types.DVPair{DelegatorAddress: ubd.DelegatorAddress, ValidatorAddress: ubd.ValidatorAddress} - timeSlice := k.GetUBDQueueTimeSlice(ctx, completionTime) + timeSlice, err := k.GetUBDQueueTimeSlice(ctx, completionTime) + if err != nil { + return err + } + if len(timeSlice) == 0 { - k.SetUBDQueueTimeSlice(ctx, completionTime, []types.DVPair{dvPair}) - } else { - timeSlice = append(timeSlice, dvPair) - k.SetUBDQueueTimeSlice(ctx, completionTime, timeSlice) + if err = k.SetUBDQueueTimeSlice(ctx, completionTime, []types.DVPair{dvPair}); err != nil { + return err + } + return nil } + + timeSlice = append(timeSlice, dvPair) + return k.SetUBDQueueTimeSlice(ctx, completionTime, timeSlice) } // UBDQueueIterator returns all the unbonding queue timeslices from time 0 until endTime. -func (k Keeper) UBDQueueIterator(ctx sdk.Context, endTime time.Time) storetypes.Iterator { - store := ctx.KVStore(k.storeKey) +func (k Keeper) UBDQueueIterator(ctx context.Context, endTime time.Time) (corestore.Iterator, error) { + store := k.storeService.OpenKVStore(ctx) return store.Iterator(types.UnbondingQueueKey, storetypes.InclusiveEndBytes(types.GetUnbondingDelegationTimeKey(endTime))) } // DequeueAllMatureUBDQueue returns a concatenated list of all the timeslices inclusively previous to // currTime, and deletes the timeslices from the queue. -func (k Keeper) DequeueAllMatureUBDQueue(ctx sdk.Context, currTime time.Time) (matureUnbonds []types.DVPair) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) DequeueAllMatureUBDQueue(ctx context.Context, currTime time.Time) (matureUnbonds []types.DVPair, err error) { + store := k.storeService.OpenKVStore(ctx) // gets an iterator for all timeslices from time 0 until the current Blockheader time - unbondingTimesliceIterator := k.UBDQueueIterator(ctx, currTime) + unbondingTimesliceIterator, err := k.UBDQueueIterator(ctx, currTime) + if err != nil { + return matureUnbonds, err + } defer unbondingTimesliceIterator.Close() for ; unbondingTimesliceIterator.Valid(); unbondingTimesliceIterator.Next() { timeslice := types.DVPairs{} value := unbondingTimesliceIterator.Value() - k.cdc.MustUnmarshal(value, ×lice) + if err = k.cdc.Unmarshal(value, ×lice); err != nil { + return matureUnbonds, err + } matureUnbonds = append(matureUnbonds, timeslice.Pairs...) - store.Delete(unbondingTimesliceIterator.Key()) + if err = store.Delete(unbondingTimesliceIterator.Key()); err != nil { + return matureUnbonds, err + } + } - return matureUnbonds + return matureUnbonds, nil } // GetRedelegations returns a given amount of all the delegator redelegations. -func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve uint16) (redelegations []types.Redelegation) { +func (k Keeper) GetRedelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) (redelegations []types.Redelegation, err error) { redelegations = make([]types.Redelegation, maxRetrieve) - store := ctx.KVStore(k.storeKey) + store := k.storeService.OpenKVStore(ctx) delegatorPrefixKey := types.GetREDsKey(delegator) - - iterator := storetypes.KVStorePrefixIterator(store, delegatorPrefixKey) - defer iterator.Close() + iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) + if err != nil { + return nil, err + } i := 0 for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() { - redelegation := types.MustUnmarshalRED(k.cdc, iterator.Value()) + redelegation, err := types.UnmarshalRED(k.cdc, iterator.Value()) + if err != nil { + return nil, err + } redelegations[i] = redelegation i++ } - return redelegations[:i] // trim if the array length < maxRetrieve + return redelegations[:i], nil // trim if the array length < maxRetrieve } // GetRedelegation returns a redelegation. -func (k Keeper) GetRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) (red types.Redelegation, found bool) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) GetRedelegation(ctx context.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) (red types.Redelegation, err error) { + store := k.storeService.OpenKVStore(ctx) key := types.GetREDKey(delAddr, valSrcAddr, valDstAddr) - value := store.Get(key) - if value == nil { - return red, false + value, err := store.Get(key) + if err != nil { + return red, err } - red = types.MustUnmarshalRED(k.cdc, value) + if value == nil { + return red, types.ErrNoRedelegation + } - return red, true + return types.UnmarshalRED(k.cdc, value) } // GetRedelegationsFromSrcValidator returns all redelegations from a particular // validator. -func (k Keeper) GetRedelegationsFromSrcValidator(ctx sdk.Context, valAddr sdk.ValAddress) (reds []types.Redelegation) { - store := ctx.KVStore(k.storeKey) - - iterator := storetypes.KVStorePrefixIterator(store, types.GetREDsFromValSrcIndexKey(valAddr)) +func (k Keeper) GetRedelegationsFromSrcValidator(ctx context.Context, valAddr sdk.ValAddress) (reds []types.Redelegation, err error) { + store := k.storeService.OpenKVStore(ctx) + prefix := types.GetREDsFromValSrcIndexKey(valAddr) + iterator, err := store.Iterator(prefix, storetypes.PrefixEndBytes(prefix)) + if err != nil { + return nil, err + } defer iterator.Close() for ; iterator.Valid(); iterator.Next() { key := types.GetREDKeyFromValSrcIndexKey(iterator.Key()) - value := store.Get(key) - red := types.MustUnmarshalRED(k.cdc, value) + value, err := store.Get(key) + if err != nil { + return nil, err + } + red, err := types.UnmarshalRED(k.cdc, value) + if err != nil { + return nil, err + } reds = append(reds, red) } - return reds + return reds, nil } // HasReceivingRedelegation checks if validator is receiving a redelegation. -func (k Keeper) HasReceivingRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, valDstAddr sdk.ValAddress) bool { - store := ctx.KVStore(k.storeKey) +func (k Keeper) HasReceivingRedelegation(ctx context.Context, delAddr sdk.AccAddress, valDstAddr sdk.ValAddress) (bool, error) { + store := k.storeService.OpenKVStore(ctx) prefix := types.GetREDsByDelToValDstIndexKey(delAddr, valDstAddr) - - iterator := storetypes.KVStorePrefixIterator(store, prefix) + iterator, err := store.Iterator(prefix, storetypes.PrefixEndBytes(prefix)) + if err != nil { + return false, err + } defer iterator.Close() - - return iterator.Valid() + return iterator.Valid(), nil } // HasMaxRedelegationEntries checks if redelegation has maximum number of entries. -func (k Keeper) HasMaxRedelegationEntries(ctx sdk.Context, delegatorAddr sdk.AccAddress, validatorSrcAddr, validatorDstAddr sdk.ValAddress) bool { - red, found := k.GetRedelegation(ctx, delegatorAddr, validatorSrcAddr, validatorDstAddr) - if !found { - return false +func (k Keeper) HasMaxRedelegationEntries(ctx context.Context, delegatorAddr sdk.AccAddress, validatorSrcAddr, validatorDstAddr sdk.ValAddress) (bool, error) { + red, err := k.GetRedelegation(ctx, delegatorAddr, validatorSrcAddr, validatorDstAddr) + if err != nil { + if err == types.ErrNoRedelegation { + return false, nil + } + + return false, err + } + maxEntries, err := k.MaxEntries(ctx) + if err != nil { + return false, err } - return len(red.Entries) >= int(k.MaxEntries(ctx)) + return len(red.Entries) >= int(maxEntries), nil } // SetRedelegation set a redelegation and associated index. -func (k Keeper) SetRedelegation(ctx sdk.Context, red types.Redelegation) { +func (k Keeper) SetRedelegation(ctx context.Context, red types.Redelegation) error { delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(red.DelegatorAddress) if err != nil { - panic(err) + return err } - store := ctx.KVStore(k.storeKey) + store := k.storeService.OpenKVStore(ctx) bz := types.MustMarshalRED(k.cdc, red) valSrcAddr, err := sdk.ValAddressFromBech32(red.ValidatorSrcAddress) if err != nil { - panic(err) + return err } valDestAddr, err := sdk.ValAddressFromBech32(red.ValidatorDstAddress) if err != nil { - panic(err) + return err } key := types.GetREDKey(delegatorAddress, valSrcAddr, valDestAddr) - store.Set(key, bz) - store.Set(types.GetREDByValSrcIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{}) - store.Set(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{}) + if err = store.Set(key, bz); err != nil { + return err + } + + if err = store.Set(types.GetREDByValSrcIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{}); err != nil { + return err + } + + return store.Set(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{}) } // SetRedelegationEntry adds an entry to the unbonding delegation at the given // addresses. It creates the unbonding delegation if it does not exist. -func (k Keeper) SetRedelegationEntry(ctx sdk.Context, +func (k Keeper) SetRedelegationEntry(ctx context.Context, delegatorAddr sdk.AccAddress, validatorSrcAddr, validatorDstAddr sdk.ValAddress, creationHeight int64, minTime time.Time, balance math.Int, sharesSrc, sharesDst math.LegacyDec, -) types.Redelegation { - red, found := k.GetRedelegation(ctx, delegatorAddr, validatorSrcAddr, validatorDstAddr) - id := k.IncrementUnbondingID(ctx) - if found { +) (types.Redelegation, error) { + id, err := k.IncrementUnbondingID(ctx) + if err != nil { + return types.Redelegation{}, err + } + + red, err := k.GetRedelegation(ctx, delegatorAddr, validatorSrcAddr, validatorDstAddr) + if err == nil { red.AddEntry(creationHeight, minTime, balance, sharesDst, id) - } else { + } else if errors.Is(err, types.ErrNoRedelegation) { red = types.NewRedelegation(delegatorAddr, validatorSrcAddr, validatorDstAddr, creationHeight, minTime, balance, sharesDst, id) + } else { + return types.Redelegation{}, err } - k.SetRedelegation(ctx, red) + if err = k.SetRedelegation(ctx, red); err != nil { + return types.Redelegation{}, err + } // Add to the UBDByEntry index to look up the UBD by the UBDE ID - k.SetRedelegationByUnbondingID(ctx, red, id) + if err = k.SetRedelegationByUnbondingID(ctx, red, id); err != nil { + return types.Redelegation{}, err + } if err := k.Hooks().AfterUnbondingInitiated(ctx, id); err != nil { k.Logger(ctx).Error("failed to call after unbonding initiated hook", "error", err) + // TODO (Facu): Should we return here? We are ignoring this error } - return red + return red, nil } // IterateRedelegations iterates through all redelegations. -func (k Keeper) IterateRedelegations(ctx sdk.Context, fn func(index int64, red types.Redelegation) (stop bool)) { - store := ctx.KVStore(k.storeKey) - - iterator := storetypes.KVStorePrefixIterator(store, types.RedelegationKey) +func (k Keeper) IterateRedelegations(ctx context.Context, fn func(index int64, red types.Redelegation) (stop bool)) error { + store := k.storeService.OpenKVStore(ctx) + iterator, err := store.Iterator(types.RedelegationKey, storetypes.PrefixEndBytes(types.RedelegationKey)) + if err != nil { + return err + } defer iterator.Close() for i := int64(0); iterator.Valid(); iterator.Next() { - red := types.MustUnmarshalRED(k.cdc, iterator.Value()) + red, err := types.UnmarshalRED(k.cdc, iterator.Value()) + if err != nil { + return err + } if stop := fn(i, red); stop { break } i++ } + + return nil } // RemoveRedelegation removes a redelegation object and associated index. -func (k Keeper) RemoveRedelegation(ctx sdk.Context, red types.Redelegation) { +func (k Keeper) RemoveRedelegation(ctx context.Context, red types.Redelegation) error { delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(red.DelegatorAddress) if err != nil { - panic(err) + return err } - store := ctx.KVStore(k.storeKey) + store := k.storeService.OpenKVStore(ctx) valSrcAddr, err := sdk.ValAddressFromBech32(red.ValidatorSrcAddress) if err != nil { - panic(err) + return err } valDestAddr, err := sdk.ValAddressFromBech32(red.ValidatorDstAddress) if err != nil { - panic(err) + return err } redKey := types.GetREDKey(delegatorAddress, valSrcAddr, valDestAddr) - store.Delete(redKey) - store.Delete(types.GetREDByValSrcIndexKey(delegatorAddress, valSrcAddr, valDestAddr)) - store.Delete(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr)) + if err = store.Delete(redKey); err != nil { + return err + } + + if err = store.Delete(types.GetREDByValSrcIndexKey(delegatorAddress, valSrcAddr, valDestAddr)); err != nil { + return err + } + + return store.Delete(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr)) } // redelegation queue timeslice operations @@ -595,31 +760,43 @@ func (k Keeper) RemoveRedelegation(ctx sdk.Context, red types.Redelegation) { // GetRedelegationQueueTimeSlice gets a specific redelegation queue timeslice. A // timeslice is a slice of DVVTriplets corresponding to redelegations that // expire at a certain time. -func (k Keeper) GetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (dvvTriplets []types.DVVTriplet) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) GetRedelegationQueueTimeSlice(ctx context.Context, timestamp time.Time) (dvvTriplets []types.DVVTriplet, err error) { + store := k.storeService.OpenKVStore(ctx) + bz, err := store.Get(types.GetRedelegationTimeKey(timestamp)) + if err != nil { + return nil, err + } - bz := store.Get(types.GetRedelegationTimeKey(timestamp)) if bz == nil { - return []types.DVVTriplet{} + return []types.DVVTriplet{}, nil } triplets := types.DVVTriplets{} - k.cdc.MustUnmarshal(bz, &triplets) + err = k.cdc.Unmarshal(bz, &triplets) + if err != nil { + return nil, err + } - return triplets.Triplets + return triplets.Triplets, nil } // SetRedelegationQueueTimeSlice sets a specific redelegation queue timeslice. -func (k Keeper) SetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []types.DVVTriplet) { - store := ctx.KVStore(k.storeKey) - bz := k.cdc.MustMarshal(&types.DVVTriplets{Triplets: keys}) - store.Set(types.GetRedelegationTimeKey(timestamp), bz) +func (k Keeper) SetRedelegationQueueTimeSlice(ctx context.Context, timestamp time.Time, keys []types.DVVTriplet) error { + store := k.storeService.OpenKVStore(ctx) + bz, err := k.cdc.Marshal(&types.DVVTriplets{Triplets: keys}) + if err != nil { + return err + } + return store.Set(types.GetRedelegationTimeKey(timestamp), bz) } // InsertRedelegationQueue insert an redelegation delegation to the appropriate // timeslice in the redelegation queue. -func (k Keeper) InsertRedelegationQueue(ctx sdk.Context, red types.Redelegation, completionTime time.Time) { - timeSlice := k.GetRedelegationQueueTimeSlice(ctx, completionTime) +func (k Keeper) InsertRedelegationQueue(ctx context.Context, red types.Redelegation, completionTime time.Time) error { + timeSlice, err := k.GetRedelegationQueueTimeSlice(ctx, completionTime) + if err != nil { + return err + } dvvTriplet := types.DVVTriplet{ DelegatorAddress: red.DelegatorAddress, ValidatorSrcAddress: red.ValidatorSrcAddress, @@ -627,47 +804,55 @@ func (k Keeper) InsertRedelegationQueue(ctx sdk.Context, red types.Redelegation, } if len(timeSlice) == 0 { - k.SetRedelegationQueueTimeSlice(ctx, completionTime, []types.DVVTriplet{dvvTriplet}) - } else { - timeSlice = append(timeSlice, dvvTriplet) - k.SetRedelegationQueueTimeSlice(ctx, completionTime, timeSlice) + return k.SetRedelegationQueueTimeSlice(ctx, completionTime, []types.DVVTriplet{dvvTriplet}) } + + timeSlice = append(timeSlice, dvvTriplet) + return k.SetRedelegationQueueTimeSlice(ctx, completionTime, timeSlice) } // RedelegationQueueIterator returns all the redelegation queue timeslices from // time 0 until endTime. -func (k Keeper) RedelegationQueueIterator(ctx sdk.Context, endTime time.Time) storetypes.Iterator { - store := ctx.KVStore(k.storeKey) +func (k Keeper) RedelegationQueueIterator(ctx context.Context, endTime time.Time) (storetypes.Iterator, error) { + store := k.storeService.OpenKVStore(ctx) return store.Iterator(types.RedelegationQueueKey, storetypes.InclusiveEndBytes(types.GetRedelegationTimeKey(endTime))) } // DequeueAllMatureRedelegationQueue returns a concatenated list of all the // timeslices inclusively previous to currTime, and deletes the timeslices from // the queue. -func (k Keeper) DequeueAllMatureRedelegationQueue(ctx sdk.Context, currTime time.Time) (matureRedelegations []types.DVVTriplet) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) DequeueAllMatureRedelegationQueue(ctx context.Context, currTime time.Time) (matureRedelegations []types.DVVTriplet, err error) { + store := k.storeService.OpenKVStore(ctx) // gets an iterator for all timeslices from time 0 until the current Blockheader time - redelegationTimesliceIterator := k.RedelegationQueueIterator(ctx, ctx.BlockHeader().Time) + sdkCtx := sdk.UnwrapSDKContext(ctx) + redelegationTimesliceIterator, err := k.RedelegationQueueIterator(ctx, sdkCtx.HeaderInfo().Time) + if err != nil { + return nil, err + } defer redelegationTimesliceIterator.Close() for ; redelegationTimesliceIterator.Valid(); redelegationTimesliceIterator.Next() { timeslice := types.DVVTriplets{} value := redelegationTimesliceIterator.Value() - k.cdc.MustUnmarshal(value, ×lice) + if err = k.cdc.Unmarshal(value, ×lice); err != nil { + return nil, err + } matureRedelegations = append(matureRedelegations, timeslice.Triplets...) - store.Delete(redelegationTimesliceIterator.Key()) + if err = store.Delete(redelegationTimesliceIterator.Key()); err != nil { + return nil, err + } } - return matureRedelegations + return matureRedelegations, nil } // Delegate performs a delegation, set/update everything necessary within the store. // tokenSrc indicates the bond status of the incoming funds. func (k Keeper) Delegate( - ctx sdk.Context, delAddr sdk.AccAddress, bondAmt math.Int, tokenSrc types.BondStatus, + ctx context.Context, delAddr sdk.AccAddress, bondAmt math.Int, tokenSrc types.BondStatus, validator types.Validator, subtractAccount bool, ) (newShares math.LegacyDec, err error) { // In some situations, the exchange rate becomes invalid, e.g. if @@ -677,17 +862,17 @@ func (k Keeper) Delegate( return math.LegacyZeroDec(), types.ErrDelegatorShareExRateInvalid } - // Get or create the delegation object - delegation, found := k.GetDelegation(ctx, delAddr, validator.GetOperator()) - if !found { - delegation = types.NewDelegation(delAddr, validator.GetOperator(), math.LegacyZeroDec()) - } - - // call the appropriate hook if present - if found { + // Get or create the delegation object and call the appropriate hook if present + delegation, err := k.GetDelegation(ctx, delAddr, validator.GetOperator()) + if err == nil { + // found err = k.Hooks().BeforeDelegationSharesModified(ctx, delAddr, validator.GetOperator()) - } else { + } else if errors.Is(err, types.ErrNoDelegation) { + // not found + delegation = types.NewDelegation(delAddr, validator.GetOperator(), math.LegacyZeroDec()) err = k.Hooks().BeforeDelegationCreated(ctx, delAddr, validator.GetOperator()) + } else { + return math.LegacyZeroDec(), err } if err != nil { @@ -696,7 +881,7 @@ func (k Keeper) Delegate( delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(delegation.DelegatorAddress) if err != nil { - panic(err) + return math.LegacyZeroDec(), err } // if subtractAccount is true then we are @@ -718,7 +903,12 @@ func (k Keeper) Delegate( panic("invalid validator status") } - coins := sdk.NewCoins(sdk.NewCoin(k.BondDenom(ctx), bondAmt)) + bondDenom, err := k.BondDenom(ctx) + if err != nil { + return math.LegacyDec{}, err + } + + coins := sdk.NewCoins(sdk.NewCoin(bondDenom, bondAmt)) if err := k.bankKeeper.DelegateCoinsFromAccountToModule(ctx, delegatorAddress, sendName, coins); err != nil { return math.LegacyDec{}, err } @@ -731,20 +921,31 @@ func (k Keeper) Delegate( // do nothing case (tokenSrc == types.Unbonded || tokenSrc == types.Unbonding) && validator.IsBonded(): // transfer pools - k.notBondedTokensToBonded(ctx, bondAmt) + err = k.notBondedTokensToBonded(ctx, bondAmt) + if err != nil { + return math.LegacyDec{}, err + } case tokenSrc == types.Bonded && !validator.IsBonded(): // transfer pools - k.bondedTokensToNotBonded(ctx, bondAmt) + err = k.bondedTokensToNotBonded(ctx, bondAmt) + if err != nil { + return math.LegacyDec{}, err + } default: panic("unknown token source bond status") } } - _, newShares = k.AddValidatorTokensAndShares(ctx, validator, bondAmt) + _, newShares, err = k.AddValidatorTokensAndShares(ctx, validator, bondAmt) + if err != nil { + return newShares, err + } // Update delegation delegation.Shares = delegation.Shares.Add(newShares) - k.SetDelegation(ctx, delegation) + if err = k.SetDelegation(ctx, delegation); err != nil { + return newShares, err + } // Call the after-modification hook if err := k.Hooks().AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { @@ -756,12 +957,14 @@ func (k Keeper) Delegate( // Unbond unbonds a particular delegation and perform associated store operations. func (k Keeper) Unbond( - ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares math.LegacyDec, + ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares math.LegacyDec, ) (amount math.Int, err error) { // check if a delegation object exists in the store - delegation, found := k.GetDelegation(ctx, delAddr, valAddr) - if !found { + delegation, err := k.GetDelegation(ctx, delAddr, valAddr) + if errors.Is(err, types.ErrNoDelegation) { return amount, types.ErrNoDelegatorForAddress + } else if err != nil { + return amount, err } // call the before-delegation-modified hook @@ -775,9 +978,9 @@ func (k Keeper) Unbond( } // get validator - validator, found := k.GetValidator(ctx, valAddr) - if !found { - return amount, types.ErrNoValidatorFound + validator, err := k.GetValidator(ctx, valAddr) + if err != nil { + return amount, err } // subtract shares from delegation @@ -794,14 +997,19 @@ func (k Keeper) Unbond( // self-delegation below their minimum, we jail the validator. if isValidatorOperator && !validator.Jailed && validator.TokensFromShares(delegation.Shares).TruncateInt().LT(validator.MinSelfDelegation) { - k.jailValidator(ctx, validator) + err = k.jailValidator(ctx, validator) + if err != nil { + return amount, err + } validator = k.mustGetValidator(ctx, validator.GetOperator()) } if delegation.Shares.IsZero() { err = k.RemoveDelegation(ctx, delegation) } else { - k.SetDelegation(ctx, delegation) + if err = k.SetDelegation(ctx, delegation); err != nil { + return amount, err + } // call the after delegation modification hook err = k.Hooks().AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()) } @@ -812,10 +1020,16 @@ func (k Keeper) Unbond( // remove the shares and coins from the validator // NOTE that the amount is later (in keeper.Delegation) moved between staking module pools - validator, amount = k.RemoveValidatorTokensAndShares(ctx, validator, shares) + validator, amount, err = k.RemoveValidatorTokensAndShares(ctx, validator, shares) + if err != nil { + return amount, err + } + if validator.DelegatorShares.IsZero() && validator.IsUnbonded() { // if not unbonded, we must instead remove validator in EndBlocker once it finishes its unbonding period - k.RemoveValidator(ctx, validator.GetOperator()) + if err = k.RemoveValidator(ctx, validator.GetOperator()); err != nil { + return amount, err + } } return amount, nil @@ -825,24 +1039,32 @@ func (k Keeper) Unbond( // with a boolean signaling if the redelegation is complete based on the source // validator. func (k Keeper) getBeginInfo( - ctx sdk.Context, valSrcAddr sdk.ValAddress, -) (completionTime time.Time, height int64, completeNow bool) { - validator, found := k.GetValidator(ctx, valSrcAddr) + ctx context.Context, valSrcAddr sdk.ValAddress, +) (completionTime time.Time, height int64, completeNow bool, err error) { + validator, err := k.GetValidator(ctx, valSrcAddr) + if err != nil && errors.Is(err, types.ErrNoValidatorFound) { + return + } + sdkCtx := sdk.UnwrapSDKContext(ctx) + unbondingTime, err := k.UnbondingTime(ctx) + if err != nil { + return + } // TODO: When would the validator not be found? switch { - case !found || validator.IsBonded(): + case errors.Is(err, types.ErrNoValidatorFound) || validator.IsBonded(): // the longest wait - just unbonding period from now - completionTime = ctx.BlockHeader().Time.Add(k.UnbondingTime(ctx)) - height = ctx.BlockHeight() + completionTime = sdkCtx.BlockHeader().Time.Add(unbondingTime) + height = sdkCtx.BlockHeight() - return completionTime, height, false + return completionTime, height, false, nil case validator.IsUnbonded(): - return completionTime, height, true + return completionTime, height, true, nil case validator.IsUnbonding(): - return validator.UnbondingTime, validator.UnbondingHeight, false + return validator.UnbondingTime, validator.UnbondingHeight, false, nil default: panic(fmt.Sprintf("unknown validator status: %s", validator.Status)) @@ -855,14 +1077,19 @@ func (k Keeper) getBeginInfo( // an unbonding object and inserting it into the unbonding queue which will be // processed during the staking EndBlocker. func (k Keeper) Undelegate( - ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount math.LegacyDec, + ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount math.LegacyDec, ) (time.Time, math.Int, error) { - validator, found := k.GetValidator(ctx, valAddr) - if !found { - return time.Time{}, math.Int{}, types.ErrNoDelegatorForAddress + validator, err := k.GetValidator(ctx, valAddr) + if err != nil { + return time.Time{}, math.Int{}, err } - if k.HasMaxUnbondingDelegationEntries(ctx, delAddr, valAddr) { + hasMaxEntries, err := k.HasMaxUnbondingDelegationEntries(ctx, delAddr, valAddr) + if err != nil { + return time.Time{}, math.Int{}, err + } + + if hasMaxEntries { return time.Time{}, math.Int{}, types.ErrMaxUnbondingDelegationEntries } @@ -873,12 +1100,28 @@ func (k Keeper) Undelegate( // transfer the validator tokens to the not bonded pool if validator.IsBonded() { - k.bondedTokensToNotBonded(ctx, returnAmount) + err = k.bondedTokensToNotBonded(ctx, returnAmount) + if err != nil { + return time.Time{}, math.Int{}, err + } } - completionTime := ctx.BlockHeader().Time.Add(k.UnbondingTime(ctx)) - ubd := k.SetUnbondingDelegationEntry(ctx, delAddr, valAddr, ctx.BlockHeight(), completionTime, returnAmount) - k.InsertUBDQueue(ctx, ubd, completionTime) + unbondingTime, err := k.UnbondingTime(ctx) + if err != nil { + return time.Time{}, math.Int{}, err + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + completionTime := sdkCtx.BlockHeader().Time.Add(unbondingTime) + ubd, err := k.SetUnbondingDelegationEntry(ctx, delAddr, valAddr, sdkCtx.BlockHeight(), completionTime, returnAmount) + if err != nil { + return time.Time{}, math.Int{}, err + } + + err = k.InsertUBDQueue(ctx, ubd, completionTime) + if err != nil { + return time.Time{}, math.Int{}, err + } return completionTime, returnAmount, nil } @@ -886,15 +1129,20 @@ func (k Keeper) Undelegate( // CompleteUnbonding completes the unbonding of all mature entries in the // retrieved unbonding delegation object and returns the total unbonding balance // or an error upon failure. -func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (sdk.Coins, error) { - ubd, found := k.GetUnbondingDelegation(ctx, delAddr, valAddr) - if !found { - return nil, types.ErrNoUnbondingDelegation +func (k Keeper) CompleteUnbonding(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (sdk.Coins, error) { + ubd, err := k.GetUnbondingDelegation(ctx, delAddr, valAddr) + if err != nil { + return nil, err + } + + bondDenom, err := k.BondDenom(ctx) + if err != nil { + return nil, err } - bondDenom := k.GetParams(ctx).BondDenom balances := sdk.NewCoins() - ctxTime := ctx.BlockHeader().Time + sdkCtx := sdk.UnwrapSDKContext(ctx) + ctxTime := sdkCtx.BlockHeader().Time delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(ubd.DelegatorAddress) if err != nil { @@ -907,7 +1155,9 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAd if entry.IsMature(ctxTime) && !entry.OnHold() { ubd.RemoveEntry(int64(i)) i-- - k.DeleteUnbondingIndex(ctx, entry.UnbondingId) + if err = k.DeleteUnbondingIndex(ctx, entry.UnbondingId); err != nil { + return nil, err + } // track undelegation only when remaining or truncated shares are non-zero if !entry.Balance.IsZero() { @@ -925,9 +1175,13 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAd // 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) + } + + if err != nil { + return nil, err } return balances, nil @@ -936,28 +1190,42 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAd // BeginRedelegation begins unbonding / redelegation and creates a redelegation // record. func (k Keeper) BeginRedelegation( - ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount math.LegacyDec, + ctx context.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount math.LegacyDec, ) (completionTime time.Time, err error) { if bytes.Equal(valSrcAddr, valDstAddr) { return time.Time{}, types.ErrSelfRedelegation } - dstValidator, found := k.GetValidator(ctx, valDstAddr) - if !found { + dstValidator, err := k.GetValidator(ctx, valDstAddr) + if errors.Is(err, types.ErrNoValidatorFound) { return time.Time{}, types.ErrBadRedelegationDst + } else if err != nil { + return time.Time{}, err } - srcValidator, found := k.GetValidator(ctx, valSrcAddr) - if !found { - return time.Time{}, types.ErrBadRedelegationDst + srcValidator, err := k.GetValidator(ctx, valSrcAddr) + if errors.Is(err, types.ErrNoValidatorFound) { + return time.Time{}, types.ErrBadRedelegationSrc + } else if err != nil { + return time.Time{}, err } // check if this is a transitive redelegation - if k.HasReceivingRedelegation(ctx, delAddr, valSrcAddr) { + hasRecRedel, err := k.HasReceivingRedelegation(ctx, delAddr, valSrcAddr) + if err != nil { + return time.Time{}, err + } + + if hasRecRedel { return time.Time{}, types.ErrTransitiveRedelegation } - if k.HasMaxRedelegationEntries(ctx, delAddr, valSrcAddr, valDstAddr) { + hasMaxRedels, err := k.HasMaxRedelegationEntries(ctx, delAddr, valSrcAddr, valDstAddr) + if err != nil { + return time.Time{}, err + } + + if hasMaxRedels { return time.Time{}, types.ErrMaxRedelegationEntries } @@ -976,17 +1244,27 @@ func (k Keeper) BeginRedelegation( } // create the unbonding delegation - completionTime, height, completeNow := k.getBeginInfo(ctx, valSrcAddr) + completionTime, height, completeNow, err := k.getBeginInfo(ctx, valSrcAddr) + if err != nil { + return time.Time{}, err + } if completeNow { // no need to create the redelegation object return completionTime, nil } - red := k.SetRedelegationEntry( + red, err := k.SetRedelegationEntry( ctx, delAddr, valSrcAddr, valDstAddr, height, completionTime, returnAmount, sharesAmount, sharesCreated, ) - k.InsertRedelegationQueue(ctx, red, completionTime) + if err != nil { + return time.Time{}, err + } + + err = k.InsertRedelegationQueue(ctx, red, completionTime) + if err != nil { + return time.Time{}, err + } return completionTime, nil } @@ -995,16 +1273,21 @@ func (k Keeper) BeginRedelegation( // retrieved redelegation object and returns the total redelegation (initial) // balance or an error upon failure. func (k Keeper) CompleteRedelegation( - ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, + ctx context.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, ) (sdk.Coins, error) { - red, found := k.GetRedelegation(ctx, delAddr, valSrcAddr, valDstAddr) - if !found { - return nil, types.ErrNoRedelegation + red, err := k.GetRedelegation(ctx, delAddr, valSrcAddr, valDstAddr) + if err != nil { + return nil, err + } + + bondDenom, err := k.BondDenom(ctx) + if err != nil { + return nil, err } - bondDenom := k.GetParams(ctx).BondDenom balances := sdk.NewCoins() - ctxTime := ctx.BlockHeader().Time + sdkCtx := sdk.UnwrapSDKContext(ctx) + ctxTime := sdkCtx.BlockHeader().Time // loop through all the entries and complete mature redelegation entries for i := 0; i < len(red.Entries); i++ { @@ -1012,7 +1295,9 @@ func (k Keeper) CompleteRedelegation( if entry.IsMature(ctxTime) && !entry.OnHold() { red.RemoveEntry(int64(i)) i-- - k.DeleteUnbondingIndex(ctx, entry.UnbondingId) + if err = k.DeleteUnbondingIndex(ctx, entry.UnbondingId); err != nil { + return nil, err + } if !entry.InitialBalance.IsZero() { balances = balances.Add(sdk.NewCoin(bondDenom, entry.InitialBalance)) @@ -1022,9 +1307,13 @@ func (k Keeper) CompleteRedelegation( // set the redelegation or remove it if there are no more entries if len(red.Entries) == 0 { - k.RemoveRedelegation(ctx, red) + err = k.RemoveRedelegation(ctx, red) } else { - k.SetRedelegation(ctx, red) + err = k.SetRedelegation(ctx, red) + } + + if err != nil { + return nil, err } return balances, nil @@ -1034,16 +1323,16 @@ func (k Keeper) CompleteRedelegation( // valied based on upon the converted shares. If the amount is valid, the total // amount of respective shares is returned, otherwise an error is returned. func (k Keeper) ValidateUnbondAmount( - ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int, + ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int, ) (shares math.LegacyDec, err error) { - validator, found := k.GetValidator(ctx, valAddr) - if !found { - return shares, types.ErrNoValidatorFound + validator, err := k.GetValidator(ctx, valAddr) + if err != nil { + return shares, err } - del, found := k.GetDelegation(ctx, delAddr, valAddr) - if !found { - return shares, types.ErrNoDelegation + del, err := k.GetDelegation(ctx, delAddr, valAddr) + if err != nil { + return shares, err } shares, err = validator.SharesFromTokens(amt) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 53433fd95015..1836dd886961 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -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]) diff --git a/x/staking/keeper/genesis.go b/x/staking/keeper/genesis.go index 85dc5e9e9bc2..dfd3368bf426 100644 --- a/x/staking/keeper/genesis.go +++ b/x/staking/keeper/genesis.go @@ -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, diff --git a/x/staking/keeper/grpc_query.go b/x/staking/keeper/grpc_query.go index 482be95055e9..13bb3bc3f9f1 100644 --- a/x/staking/keeper/grpc_query.go +++ b/x/staking/keeper/grpc_query.go @@ -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)) diff --git a/x/staking/keeper/grpc_query_test.go b/x/staking/keeper/grpc_query_test.go index 597636a9ec02..b55539d1b538 100644 --- a/x/staking/keeper/grpc_query_test.go +++ b/x/staking/keeper/grpc_query_test.go @@ -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 diff --git a/x/staking/keeper/historical_info.go b/x/staking/keeper/historical_info.go index 47895b19f8be..eb9707d103a2 100644 --- a/x/staking/keeper/historical_info.go +++ b/x/staking/keeper/historical_info.go @@ -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) + value, err := store.Get(key) + if err != nil { + return types.HistoricalInfo{}, err + } + if value == nil { - return types.HistoricalInfo{}, false + return types.HistoricalInfo{}, types.ErrNoHistoricalInfo } - return types.MustUnmarshalHistoricalInfo(k.cdc, value), true + 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) } diff --git a/x/staking/keeper/historical_info_test.go b/x/staking/keeper/historical_info_test.go index f3b68ceec48a..d05700936689 100644 --- a/x/staking/keeper/historical_info_test.go +++ b/x/staking/keeper/historical_info_test.go @@ -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) } diff --git a/x/staking/keeper/invariants.go b/x/staking/keeper/invariants.go index 975ccc673020..c36176a6f6ec 100644 --- a/x/staking/keeper/invariants.go +++ b/x/staking/keeper/invariants.go @@ -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] diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index a9dd46b9a357..591e42b388ad 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -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 } diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index ec8d353ca40c..bc46a32bc6b8 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -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)) } diff --git a/x/staking/keeper/migrations.go b/x/staking/keeper/migrations.go index 8782f5978316..0e0e8560784e 100644 --- a/x/staking/keeper/migrations.go +++ b/x/staking/keeper/migrations.go @@ -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) } diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index e3ae767e84d3..e21ae1c595fa 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -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, err := k.GetValidator(ctx, valAddr) + if err != nil { + return nil, err + } - validator, found := k.GetValidator(ctx, valAddr) - if !found { - return nil, types.ErrNoValidatorFound + 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) + } + + if err != nil { + return nil, err } - ctx.EventManager().EmitEvent( + 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 diff --git a/x/staking/keeper/msg_server_test.go b/x/staking/keeper/msg_server_test.go index bc153ee44fd3..31202281a97c 100644 --- a/x/staking/keeper/msg_server_test.go +++ b/x/staking/keeper/msg_server_test.go @@ -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 { diff --git a/x/staking/keeper/params.go b/x/staking/keeper/params.go index 74316694d9bf..e099c0aa0293 100644 --- a/x/staking/keeper/params.go +++ b/x/staking/keeper/params.go @@ -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) +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 + } + if bz == nil { - return params + return params, nil } - k.cdc.MustUnmarshal(bz, ¶ms) - return params + err = k.cdc.Unmarshal(bz, ¶ms) + return params, err } diff --git a/x/staking/keeper/pool.go b/x/staking/keeper/pool.go index 1d0bed38d255..b8df38c2cd2e 100644 --- a/x/staking/keeper/pool.go +++ b/x/staking/keeper/pool.go @@ -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) +func (k Keeper) BondedRatio(ctx context.Context) (math.LegacyDec, error) { + stakeSupply, err := k.StakingTokenSupply(ctx) + if err != nil { + return math.LegacyZeroDec(), err + } + if stakeSupply.IsPositive() { - return math.LegacyNewDecFromInt(k.TotalBondedTokens(ctx)).QuoInt(stakeSupply) + totalBonded, err := k.TotalBondedTokens(ctx) + if err != nil { + return math.LegacyZeroDec(), err + } + return math.LegacyNewDecFromInt(totalBonded).QuoInt(stakeSupply), nil } - return math.LegacyZeroDec() + return math.LegacyZeroDec(), nil } diff --git a/x/staking/keeper/power_reduction.go b/x/staking/keeper/power_reduction.go index abed52d12f4c..b35917c58c92 100644 --- a/x/staking/keeper/power_reduction.go +++ b/x/staking/keeper/power_reduction.go @@ -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)) } diff --git a/x/staking/keeper/query_utils.go b/x/staking/keeper/query_utils.go index 6750a12bba07..75b1616dcc76 100644 --- a/x/staking/keeper/query_utils.go +++ b/x/staking/keeper/query_utils.go @@ -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 } diff --git a/x/staking/keeper/slash.go b/x/staking/keeper/slash.go index 99bfd159dc48..163456821cac 100644 --- a/x/staking/keeper/slash.go +++ b/x/staking/keeper/slash.go @@ -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 } diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index b1f6d8c873c3..204ccbe9c115 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -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) } diff --git a/x/staking/keeper/test_common.go b/x/staking/keeper/test_common.go index c0da2a4b3f97..854751c8d404 100644 --- a/x/staking/keeper/test_common.go +++ b/x/staking/keeper/test_common.go @@ -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 diff --git a/x/staking/keeper/unbonding.go b/x/staking/keeper/unbonding.go index 740531322110..2b96aebdf9a0 100644 --- a/x/staking/keeper/unbonding.go +++ b/x/staking/keeper/unbonding.go @@ -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, err := store.Get(types.GetUnbondingTypeKey(id)) + if err != nil { + return unbondingType, err + } - bz := store.Get(types.GetUnbondingTypeKey(id)) if bz == nil { - return unbondingType, false + return unbondingType, types.ErrNoUnbondingType } - return types.UnbondingType(binary.BigEndian.Uint64(bz)), true + 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) } diff --git a/x/staking/keeper/unbonding_test.go b/x/staking/keeper/unbonding_test.go index 8501afa3e8c6..aaff473a56a2 100644 --- a/x/staking/keeper/unbonding_test.go +++ b/x/staking/keeper/unbonding_test.go @@ -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)) } diff --git a/x/staking/keeper/val_state_change.go b/x/staking/keeper/val_state_change.go index d459ed6ff318..1919ccf3d81e 100644 --- a/x/staking/keeper/val_state_change.go +++ b/x/staking/keeper/val_state_change.go @@ -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() { diff --git a/x/staking/keeper/validator.go b/x/staking/keeper/validator.go index a9dd09d3c311..23ab4319ac17 100644 --- a/x/staking/keeper/validator.go +++ b/x/staking/keeper/validator.go @@ -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) +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 + } - value := store.Get(types.GetValidatorKey(addr)) if value == nil { - return validator, false + return validator, types.ErrNoValidatorFound } - validator = types.MustUnmarshalValidator(k.cdc, value) - return validator, true + 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) +) (types.Validator, error) { + if err := k.DeleteValidatorByPowerIndex(ctx, validator); err != nil { + return validator, err + } + validator = validator.RemoveTokens(tokensToRemove) - k.SetValidator(ctx, validator) - k.SetValidatorByPowerIndex(ctx, validator) + if err := k.SetValidator(ctx, validator); err != nil { + return validator, err + } - return validator + 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 } diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index 363378d96503..f9916fb7ed16 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -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()) }) - - 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) + 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 + 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 { + require.NoError(err, + "unexpected error for test case #%d with rate: %s", i, tc.newRate, + ) + tc.validator.Commission = commission - keeper.SetValidator(ctx, tc.validator) - val, found := keeper.GetValidator(ctx, tc.validator.GetOperator()) + err = keeper.SetValidator(ctx, tc.validator) + require.NoError(err) - require.True(found, - "expected to find validator for test case #%d with rate: %s", i, tc.newRate, - ) + val, err := keeper.GetValidator(ctx, tc.validator.GetOperator()) require.NoError(err, - "unexpected error for test case #%d with rate: %s", i, tc.newRate, + "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) } diff --git a/x/staking/migrations/v2/store.go b/x/staking/migrations/v2/store.go index 81872d23b26b..732eae7081c9 100644 --- a/x/staking/migrations/v2/store.go +++ b/x/staking/migrations/v2/store.go @@ -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) diff --git a/x/staking/migrations/v2/store_test.go b/x/staking/migrations/v2/store_test.go index b9416ad4f80e..20c55e5bfcbb 100644 --- a/x/staking/migrations/v2/store_test.go +++ b/x/staking/migrations/v2/store_test.go @@ -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. diff --git a/x/staking/migrations/v3/store.go b/x/staking/migrations/v3/store.go index e558a11754d5..6cb6c6263113 100644 --- a/x/staking/migrations/v3/store.go +++ b/x/staking/migrations/v3/store.go @@ -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 diff --git a/x/staking/migrations/v3/store_test.go b/x/staking/migrations/v3/store_test.go index 3bca5ba7d6b1..96d9af167638 100644 --- a/x/staking/migrations/v3/store_test.go +++ b/x/staking/migrations/v3/store_test.go @@ -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. diff --git a/x/staking/migrations/v4/migrations_test.go b/x/staking/migrations/v4/migrations_test.go index 420a24ebc304..028ff82774d2 100644 --- a/x/staking/migrations/v4/migrations_test.go +++ b/x/staking/migrations/v4/migrations_test.go @@ -69,7 +69,7 @@ func TestMigrate(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { if tc.doMigration { - require.NoError(t, v4.MigrateStore(ctx, storeKey, cdc, legacySubspace)) + require.NoError(t, v4.MigrateStore(ctx, store, cdc, legacySubspace)) } ubd := getUBD(t, accAddr, valAddr, store, cdc) diff --git a/x/staking/migrations/v4/store.go b/x/staking/migrations/v4/store.go index d9dc44f1a66c..4427ddb79675 100644 --- a/x/staking/migrations/v4/store.go +++ b/x/staking/migrations/v4/store.go @@ -12,9 +12,7 @@ import ( ) // MigrateStore performs in-place store migrations from v3 to v4. -func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec, legacySubspace exported.Subspace) error { - store := ctx.KVStore(storeKey) - +func MigrateStore(ctx sdk.Context, store storetypes.KVStore, cdc codec.BinaryCodec, legacySubspace exported.Subspace) error { // migrate params if err := migrateParams(ctx, store, cdc, legacySubspace); err != nil { return err diff --git a/x/staking/migrations/v5/migrations_test.go b/x/staking/migrations/v5/migrations_test.go index 8f477cde6158..f74948e29374 100644 --- a/x/staking/migrations/v5/migrations_test.go +++ b/x/staking/migrations/v5/migrations_test.go @@ -9,6 +9,9 @@ import ( sdkmath "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/sims" @@ -18,8 +21,6 @@ import ( v2 "github.com/cosmos/cosmos-sdk/x/staking/migrations/v2" v5 "github.com/cosmos/cosmos-sdk/x/staking/migrations/v5" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestHistoricalKeysMigration(t *testing.T) { @@ -62,7 +63,7 @@ func TestHistoricalKeysMigration(t *testing.T) { } // migrate store to new key format - require.NoErrorf(t, v5.MigrateStore(ctx, storeKey, cdc), "v5.MigrateStore failed, seed: %d", seed) + require.NoErrorf(t, v5.MigrateStore(ctx, store, cdc), "v5.MigrateStore failed, seed: %d", seed) // check results for _, tc := range testCases { @@ -97,7 +98,7 @@ func TestDelegationsByValidatorMigrations(t *testing.T) { dels := getValDelegations(ctx, cdc, storeKey, valAddrs[0]) assert.Len(t, dels, 0) - err := v5.MigrateStore(ctx, storeKey, cdc) + err := v5.MigrateStore(ctx, store, cdc) assert.NoError(t, err) // after migration the state of delegations by val index should not be empty diff --git a/x/staking/migrations/v5/store.go b/x/staking/migrations/v5/store.go index f87252da1a7e..8708dcb4f1b5 100644 --- a/x/staking/migrations/v5/store.go +++ b/x/staking/migrations/v5/store.go @@ -8,14 +8,13 @@ import ( "cosmossdk.io/store/prefix" storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func migrateDelegationsByValidatorIndex(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error { - store := ctx.KVStore(storeKey) - +func migrateDelegationsByValidatorIndex(ctx sdk.Context, store storetypes.KVStore, cdc codec.BinaryCodec) error { iterator := storetypes.KVStorePrefixIterator(store, DelegationKey) for ; iterator.Valid(); iterator.Next() { @@ -32,9 +31,8 @@ func migrateDelegationsByValidatorIndex(ctx sdk.Context, storeKey storetypes.Sto } // MigrateStore performs in-place store migrations from v4 to v5. -func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error { - store := ctx.KVStore(storeKey) - if err := migrateDelegationsByValidatorIndex(ctx, storeKey, cdc); err != nil { +func MigrateStore(ctx sdk.Context, store storetypes.KVStore, cdc codec.BinaryCodec) error { + if err := migrateDelegationsByValidatorIndex(ctx, store, cdc); err != nil { return err } return migrateHistoricalInfoKeys(store, ctx.Logger()) diff --git a/x/staking/module.go b/x/staking/module.go index 46ceca9bb6cc..ff29a80d51f4 100644 --- a/x/staking/module.go +++ b/x/staking/module.go @@ -8,8 +8,8 @@ import ( modulev1 "cosmossdk.io/api/cosmos/staking/module/v1" "cosmossdk.io/core/appmodule" + "cosmossdk.io/core/store" "cosmossdk.io/depinject" - store "cosmossdk.io/store/types" abci "github.com/cometbft/cometbft/abci/types" gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" @@ -188,10 +188,7 @@ func (AppModule) ConsensusVersion() uint64 { return consensusVersion } // BeginBlock returns the begin blocker for the staking module. func (am AppModule) BeginBlock(ctx context.Context) error { - c := sdk.UnwrapSDKContext(ctx) - - am.keeper.BeginBlocker(c) - return nil + return am.keeper.BeginBlocker(ctx) } // EndBlock returns the end blocker for the staking module. It returns no validator @@ -215,7 +212,7 @@ type ModuleInputs struct { AccountKeeper types.AccountKeeper BankKeeper types.BankKeeper Cdc codec.Codec - Key *store.KVStoreKey + StoreService store.KVStoreService // LegacySubspace is used solely for migration of x/params managed parameters LegacySubspace exported.Subspace `optional:"true"` @@ -238,7 +235,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { k := keeper.NewKeeper( in.Cdc, - in.Key, + in.StoreService, in.AccountKeeper, in.BankKeeper, authority.String(), diff --git a/x/staking/simulation/operations.go b/x/staking/simulation/operations.go index de8276d29129..f391c36beee8 100644 --- a/x/staking/simulation/operations.go +++ b/x/staking/simulation/operations.go @@ -120,12 +120,15 @@ func SimulateMsgCreateValidator( address := sdk.ValAddress(simAccount.Address) // ensure the validator doesn't exist already - _, found := k.GetValidator(ctx, address) - if found { + _, err := k.GetValidator(ctx, address) + if err == nil { return simtypes.NoOpMsg(types.ModuleName, msgType, "validator already exists"), nil, nil } - denom := k.GetParams(ctx).BondDenom + denom, err := k.BondDenom(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "bond denom not found"), nil, err + } balance := bk.GetBalance(ctx, simAccount.Address, denom).Amount if !balance.IsPositive() { @@ -200,11 +203,16 @@ func SimulateMsgEditValidator( ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { msgType := sdk.MsgTypeURL(&types.MsgEditValidator{}) - if len(k.GetAllValidators(ctx)) == 0 { + vals, err := k.GetAllValidators(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to get validators"), nil, err + } + + if len(vals) == 0 { return simtypes.NoOpMsg(types.ModuleName, msgType, "number of validators equal zero"), nil, nil } - val, ok := testutil.RandSliceElem(r, k.GetAllValidators(ctx)) + val, ok := testutil.RandSliceElem(r, vals) if !ok { return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to pick a validator"), nil, nil } @@ -264,14 +272,22 @@ func SimulateMsgDelegate( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { msgType := sdk.MsgTypeURL(&types.MsgDelegate{}) - denom := k.GetParams(ctx).BondDenom + denom, err := k.BondDenom(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "bond denom not found"), nil, err + } - if len(k.GetAllValidators(ctx)) == 0 { + vals, err := k.GetAllValidators(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to get validators"), nil, err + } + + if len(vals) == 0 { return simtypes.NoOpMsg(types.ModuleName, msgType, "number of validators equal zero"), nil, nil } simAccount, _ := simtypes.RandomAcc(r, accs) - val, ok := testutil.RandSliceElem(r, k.GetAllValidators(ctx)) + val, ok := testutil.RandSliceElem(r, vals) if !ok { return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to pick a validator"), nil, nil } @@ -285,7 +301,7 @@ func SimulateMsgDelegate( return simtypes.NoOpMsg(types.ModuleName, msgType, "balance is negative"), nil, nil } - amount, err := simtypes.RandPositiveInt(r, amount) + amount, err = simtypes.RandPositiveInt(r, amount) if err != nil { return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to generate positive amount"), nil, err } @@ -335,13 +351,26 @@ func SimulateMsgUndelegate( ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { msgType := sdk.MsgTypeURL(&types.MsgUndelegate{}) - val, ok := testutil.RandSliceElem(r, k.GetAllValidators(ctx)) + vals, err := k.GetAllValidators(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to get validators"), nil, err + } + + if len(vals) == 0 { + return simtypes.NoOpMsg(types.ModuleName, msgType, "number of validators equal zero"), nil, nil + } + + val, ok := testutil.RandSliceElem(r, vals) if !ok { return simtypes.NoOpMsg(types.ModuleName, msgType, "validator is not ok"), nil, nil } valAddr := val.GetOperator() - delegations := k.GetValidatorDelegations(ctx, val.GetOperator()) + delegations, err := k.GetValidatorDelegations(ctx, val.GetOperator()) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "error getting validator delegations"), nil, nil + } + if delegations == nil { return simtypes.NoOpMsg(types.ModuleName, msgType, "keeper does have any delegation entries"), nil, nil } @@ -350,7 +379,12 @@ func SimulateMsgUndelegate( delegation := delegations[r.Intn(len(delegations))] delAddr := delegation.GetDelegatorAddr() - if k.HasMaxUnbondingDelegationEntries(ctx, delAddr, valAddr) { + hasMaxUD, err := k.HasMaxUnbondingDelegationEntries(ctx, delAddr, valAddr) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "error getting max unbonding delegation entries"), nil, err + } + + if hasMaxUD { return simtypes.NoOpMsg(types.ModuleName, msgType, "keeper does have a max unbonding delegation entries"), nil, nil } @@ -368,8 +402,13 @@ func SimulateMsgUndelegate( return simtypes.NoOpMsg(types.ModuleName, msgType, "unbond amount is zero"), nil, nil } + bondDenom, err := k.BondDenom(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "bond denom not found"), nil, err + } + msg := types.NewMsgUndelegate( - delAddr, valAddr, sdk.NewCoin(k.BondDenom(ctx), unbondAmt), + delAddr, valAddr, sdk.NewCoin(bondDenom, unbondAmt), ) // need to retrieve the simulation account associated with delegation to retrieve PrivKey @@ -419,11 +458,17 @@ func SimulateMsgCancelUnbondingDelegate( ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { msgType := sdk.MsgTypeURL(&types.MsgCancelUnbondingDelegation{}) - if len(k.GetAllValidators(ctx)) == 0 { + vals, err := k.GetAllValidators(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to get validators"), nil, err + } + + if len(vals) == 0 { return simtypes.NoOpMsg(types.ModuleName, msgType, "number of validators equal zero"), nil, nil } + simAccount, _ := simtypes.RandomAcc(r, accs) - val, ok := testutil.RandSliceElem(r, k.GetAllValidators(ctx)) + val, ok := testutil.RandSliceElem(r, vals) if !ok { return simtypes.NoOpMsg(types.ModuleName, msgType, "validator is not ok"), nil, nil } @@ -433,8 +478,8 @@ func SimulateMsgCancelUnbondingDelegate( } valAddr := val.GetOperator() - unbondingDelegation, found := k.GetUnbondingDelegation(ctx, simAccount.Address, valAddr) - if !found { + unbondingDelegation, err := k.GetUnbondingDelegation(ctx, simAccount.Address, valAddr) + if err != nil { return simtypes.NoOpMsg(types.ModuleName, msgType, "account does have any unbonding delegation"), nil, nil } @@ -469,8 +514,13 @@ func SimulateMsgCancelUnbondingDelegate( return simtypes.NoOpMsg(types.ModuleName, msgType, "cancelBondAmt amount is zero"), nil, nil } + bondDenom, err := k.BondDenom(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "bond denom not found"), nil, err + } + msg := types.NewMsgCancelUnbondingDelegation( - simAccount.Address, valAddr, unbondingDelegationEntry.CreationHeight, sdk.NewCoin(k.BondDenom(ctx), cancelBondAmt), + simAccount.Address, valAddr, unbondingDelegationEntry.CreationHeight, sdk.NewCoin(bondDenom, cancelBondAmt), ) spendable := bk.SpendableCoins(ctx, simAccount.Address) @@ -505,14 +555,26 @@ func SimulateMsgBeginRedelegate( ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { msgType := sdk.MsgTypeURL(&types.MsgBeginRedelegate{}) - allVals := k.GetAllValidators(ctx) + allVals, err := k.GetAllValidators(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to get validators"), nil, err + } + + if len(allVals) == 0 { + return simtypes.NoOpMsg(types.ModuleName, msgType, "number of validators equal zero"), nil, nil + } + srcVal, ok := testutil.RandSliceElem(r, allVals) if !ok { return simtypes.NoOpMsg(types.ModuleName, msgType, "unable to pick validator"), nil, nil } srcAddr := srcVal.GetOperator() - delegations := k.GetValidatorDelegations(ctx, srcAddr) + delegations, err := k.GetValidatorDelegations(ctx, srcAddr) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "error getting validator delegations"), nil, nil + } + if delegations == nil { return simtypes.NoOpMsg(types.ModuleName, msgType, "keeper does have any delegation entries"), nil, nil } @@ -521,7 +583,12 @@ func SimulateMsgBeginRedelegate( delegation := delegations[r.Intn(len(delegations))] delAddr := delegation.GetDelegatorAddr() - if k.HasReceivingRedelegation(ctx, delAddr, srcAddr) { + hasRecRedel, err := k.HasReceivingRedelegation(ctx, delAddr, srcAddr) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "error getting receiving redelegation"), nil, err + } + + if hasRecRedel { return simtypes.NoOpMsg(types.ModuleName, msgType, "receveing redelegation is not allowed"), nil, nil // skip } @@ -532,7 +599,12 @@ func SimulateMsgBeginRedelegate( } destAddr := destVal.GetOperator() - if srcAddr.Equals(destAddr) || destVal.InvalidExRate() || k.HasMaxRedelegationEntries(ctx, delAddr, srcAddr, destAddr) { + hasMaxRedel, err := k.HasMaxRedelegationEntries(ctx, delAddr, srcAddr, destAddr) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "error getting max redelegation entries"), nil, err + } + + if srcAddr.Equals(destAddr) || destVal.InvalidExRate() || hasMaxRedel { return simtypes.NoOpMsg(types.ModuleName, msgType, "checks failed"), nil, nil } @@ -578,9 +650,14 @@ func SimulateMsgBeginRedelegate( account := ak.GetAccount(ctx, delAddr) spendable := bk.SpendableCoins(ctx, account.GetAddress()) + bondDenom, err := k.BondDenom(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "bond denom not found"), nil, err + } + msg := types.NewMsgBeginRedelegate( delAddr, srcAddr, destAddr, - sdk.NewCoin(k.BondDenom(ctx), redAmt), + sdk.NewCoin(bondDenom, redAmt), ) txCtx := simulation.OperationInput{ diff --git a/x/staking/testutil/expected_keepers_mocks.go b/x/staking/testutil/expected_keepers_mocks.go index 3123d781fbdc..e66027edd2e7 100644 --- a/x/staking/testutil/expected_keepers_mocks.go +++ b/x/staking/testutil/expected_keepers_mocks.go @@ -342,11 +342,12 @@ func (m *MockValidatorSet) EXPECT() *MockValidatorSetMockRecorder { } // Delegation mocks base method. -func (m *MockValidatorSet) Delegation(arg0 types.Context, arg1 types.AccAddress, arg2 types.ValAddress) types0.DelegationI { +func (m *MockValidatorSet) 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. @@ -356,9 +357,11 @@ func (mr *MockValidatorSetMockRecorder) Delegation(arg0, arg1, arg2 interface{}) } // IterateBondedValidatorsByPower mocks base method. -func (m *MockValidatorSet) IterateBondedValidatorsByPower(arg0 types.Context, arg1 func(int64, types0.ValidatorI) bool) { +func (m *MockValidatorSet) IterateBondedValidatorsByPower(arg0 context.Context, arg1 func(int64, types0.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. @@ -368,9 +371,11 @@ func (mr *MockValidatorSetMockRecorder) IterateBondedValidatorsByPower(arg0, arg } // IterateLastValidators mocks base method. -func (m *MockValidatorSet) IterateLastValidators(arg0 types.Context, arg1 func(int64, types0.ValidatorI) bool) { +func (m *MockValidatorSet) IterateLastValidators(arg0 context.Context, arg1 func(int64, types0.ValidatorI) bool) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "IterateLastValidators", arg0, arg1) + ret := m.ctrl.Call(m, "IterateLastValidators", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 } // IterateLastValidators indicates an expected call of IterateLastValidators. @@ -380,9 +385,11 @@ func (mr *MockValidatorSetMockRecorder) IterateLastValidators(arg0, arg1 interfa } // IterateValidators mocks base method. -func (m *MockValidatorSet) IterateValidators(arg0 types.Context, arg1 func(int64, types0.ValidatorI) bool) { +func (m *MockValidatorSet) 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. @@ -392,9 +399,11 @@ func (mr *MockValidatorSetMockRecorder) IterateValidators(arg0, arg1 interface{} } // Jail mocks base method. -func (m *MockValidatorSet) Jail(arg0 types.Context, arg1 types.ConsAddress) { +func (m *MockValidatorSet) 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. @@ -404,11 +413,12 @@ func (mr *MockValidatorSetMockRecorder) Jail(arg0, arg1 interface{}) *gomock.Cal } // MaxValidators mocks base method. -func (m *MockValidatorSet) MaxValidators(arg0 types.Context) uint32 { +func (m *MockValidatorSet) 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. @@ -418,11 +428,12 @@ func (mr *MockValidatorSetMockRecorder) MaxValidators(arg0 interface{}) *gomock. } // Slash mocks base method. -func (m *MockValidatorSet) Slash(arg0 types.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec) math.Int { +func (m *MockValidatorSet) 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. @@ -432,11 +443,12 @@ func (mr *MockValidatorSetMockRecorder) Slash(arg0, arg1, arg2, arg3, arg4 inter } // SlashWithInfractionReason mocks base method. -func (m *MockValidatorSet) SlashWithInfractionReason(arg0 types.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec, arg5 types0.Infraction) math.Int { +func (m *MockValidatorSet) SlashWithInfractionReason(arg0 context.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec, arg5 types0.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. @@ -446,11 +458,12 @@ func (mr *MockValidatorSetMockRecorder) SlashWithInfractionReason(arg0, arg1, ar } // StakingTokenSupply mocks base method. -func (m *MockValidatorSet) StakingTokenSupply(arg0 types.Context) math.Int { +func (m *MockValidatorSet) StakingTokenSupply(arg0 context.Context) (math.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StakingTokenSupply", arg0) ret0, _ := ret[0].(math.Int) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // StakingTokenSupply indicates an expected call of StakingTokenSupply. @@ -460,11 +473,12 @@ func (mr *MockValidatorSetMockRecorder) StakingTokenSupply(arg0 interface{}) *go } // TotalBondedTokens mocks base method. -func (m *MockValidatorSet) TotalBondedTokens(arg0 types.Context) math.Int { +func (m *MockValidatorSet) 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. @@ -474,9 +488,11 @@ func (mr *MockValidatorSetMockRecorder) TotalBondedTokens(arg0 interface{}) *gom } // Unjail mocks base method. -func (m *MockValidatorSet) Unjail(arg0 types.Context, arg1 types.ConsAddress) { +func (m *MockValidatorSet) 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. @@ -486,11 +502,12 @@ func (mr *MockValidatorSetMockRecorder) Unjail(arg0, arg1 interface{}) *gomock.C } // Validator mocks base method. -func (m *MockValidatorSet) Validator(arg0 types.Context, arg1 types.ValAddress) types0.ValidatorI { +func (m *MockValidatorSet) 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. @@ -500,11 +517,12 @@ func (mr *MockValidatorSetMockRecorder) Validator(arg0, arg1 interface{}) *gomoc } // ValidatorByConsAddr mocks base method. -func (m *MockValidatorSet) ValidatorByConsAddr(arg0 types.Context, arg1 types.ConsAddress) types0.ValidatorI { +func (m *MockValidatorSet) 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. @@ -551,9 +569,11 @@ func (mr *MockDelegationSetMockRecorder) GetValidatorSet() *gomock.Call { } // IterateDelegations mocks base method. -func (m *MockDelegationSet) IterateDelegations(ctx types.Context, delegator types.AccAddress, fn func(int64, types0.DelegationI) bool) { +func (m *MockDelegationSet) 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. @@ -586,7 +606,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) @@ -600,7 +620,7 @@ func (mr *MockStakingHooksMockRecorder) AfterDelegationModified(ctx, delAddr, va } // AfterUnbondingInitiated mocks base method. -func (m *MockStakingHooks) AfterUnbondingInitiated(ctx types.Context, id uint64) error { +func (m *MockStakingHooks) AfterUnbondingInitiated(ctx context.Context, id uint64) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AfterUnbondingInitiated", ctx, id) ret0, _ := ret[0].(error) @@ -614,7 +634,7 @@ func (mr *MockStakingHooksMockRecorder) AfterUnbondingInitiated(ctx, id interfac } // 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) @@ -628,7 +648,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) @@ -642,7 +662,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) @@ -656,7 +676,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) @@ -670,7 +690,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) @@ -684,7 +704,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) @@ -698,7 +718,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) @@ -712,7 +732,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) @@ -726,7 +746,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) diff --git a/x/staking/testutil/helpers.go b/x/staking/testutil/helpers.go index a7a2298d039b..dfd5595abf01 100644 --- a/x/staking/testutil/helpers.go +++ b/x/staking/testutil/helpers.go @@ -108,8 +108,8 @@ func (sh *Helper) Undelegate(delegator sdk.AccAddress, val sdk.ValAddress, amoun // CheckValidator asserts that a validor exists and has a given status (if status!="") // and if has a right jailed flag. func (sh *Helper) CheckValidator(addr sdk.ValAddress, status stakingtypes.BondStatus, jailed bool) stakingtypes.Validator { - v, ok := sh.k.GetValidator(sh.Ctx, addr) - require.True(sh.t, ok) + v, err := sh.k.GetValidator(sh.Ctx, addr) + require.NoError(sh.t, err) require.Equal(sh.t, jailed, v.Jailed, "wrong Jalied status") if status >= 0 { require.Equal(sh.t, status, v.Status) @@ -126,7 +126,8 @@ func (sh *Helper) CheckDelegator(delegator sdk.AccAddress, val sdk.ValAddress, f // TurnBlock calls EndBlocker and updates the block time func (sh *Helper) TurnBlock(newTime time.Time) sdk.Context { sh.Ctx = sh.Ctx.WithBlockTime(newTime) - sh.k.EndBlocker(sh.Ctx) + _, err := sh.k.EndBlocker(sh.Ctx) + require.NoError(sh.t, err) return sh.Ctx } @@ -134,7 +135,8 @@ func (sh *Helper) TurnBlock(newTime time.Time) sdk.Context { // duration to the current block time func (sh *Helper) TurnBlockTimeDiff(diff time.Duration) sdk.Context { sh.Ctx = sh.Ctx.WithBlockTime(sh.Ctx.BlockHeader().Time.Add(diff)) - sh.k.EndBlocker(sh.Ctx) + _, err := sh.k.EndBlocker(sh.Ctx) + require.NoError(sh.t, err) return sh.Ctx } diff --git a/x/staking/types/errors.go b/x/staking/types/errors.go index 480a121a2390..00441564352a 100644 --- a/x/staking/types/errors.go +++ b/x/staking/types/errors.go @@ -3,11 +3,6 @@ package types import "cosmossdk.io/errors" // x/staking module sentinel errors -// -// TODO: Many of these errors are redundant. They should be removed and replaced -// by sdkerrors.ErrInvalidRequest. -// -// REF: https://github.com/cosmos/cosmos-sdk/issues/5450 var ( ErrEmptyValidatorAddr = errors.Register(ModuleName, 2, "empty validator address") ErrNoValidatorFound = errors.Register(ModuleName, 3, "validator does not exist") @@ -51,4 +46,6 @@ var ( ErrUnbondingNotFound = errors.Register(ModuleName, 41, "unbonding operation not found") ErrUnbondingOnHoldRefCountNegative = errors.Register(ModuleName, 42, "cannot un-hold unbonding operation that is not on hold") ErrInvalidSigner = errors.Register(ModuleName, 43, "expected authority account as only signer for proposal message") + ErrBadRedelegationSrc = errors.Register(ModuleName, 44, "redelegation source validator not found") + ErrNoUnbondingType = errors.Register(ModuleName, 45, "unbonding type not found") ) diff --git a/x/staking/types/expected_keepers.go b/x/staking/types/expected_keepers.go index a7ef4ab37ce5..9ab221103179 100644 --- a/x/staking/types/expected_keepers.go +++ b/x/staking/types/expected_keepers.go @@ -48,34 +48,34 @@ type BankKeeper interface { // ValidatorSet expected properties for the set of all validators (noalias) type ValidatorSet interface { // iterate through validators by operator address, execute func for each validator - IterateValidators(sdk.Context, - func(index int64, validator ValidatorI) (stop bool)) + IterateValidators(context.Context, + func(index int64, validator ValidatorI) (stop bool)) error // iterate through bonded validators by operator address, execute func for each validator - IterateBondedValidatorsByPower(sdk.Context, - func(index int64, validator ValidatorI) (stop bool)) + IterateBondedValidatorsByPower(context.Context, + func(index int64, validator ValidatorI) (stop bool)) error // iterate through the consensus validator set of the last block by operator address, execute func for each validator - IterateLastValidators(sdk.Context, - func(index int64, validator ValidatorI) (stop bool)) + IterateLastValidators(context.Context, + func(index int64, validator ValidatorI) (stop bool)) error - Validator(sdk.Context, sdk.ValAddress) ValidatorI // get a particular validator by operator address - ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) ValidatorI // get a particular validator by consensus address - TotalBondedTokens(sdk.Context) math.Int // total bonded tokens within the validator set - StakingTokenSupply(sdk.Context) math.Int // total staking token supply + Validator(context.Context, sdk.ValAddress) (ValidatorI, error) // get a particular validator by operator address + ValidatorByConsAddr(context.Context, sdk.ConsAddress) (ValidatorI, error) // get a particular validator by consensus address + TotalBondedTokens(context.Context) (math.Int, error) // total bonded tokens within the validator set + StakingTokenSupply(context.Context) (math.Int, error) // total staking token supply // 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, 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, 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) DelegationI + Delegation(context.Context, sdk.AccAddress, sdk.ValAddress) (DelegationI, error) // MaxValidators returns the maximum amount of bonded validators - MaxValidators(sdk.Context) uint32 + MaxValidators(context.Context) (uint32, error) } // DelegationSet expected properties for the set of all delegations for a particular (noalias) @@ -84,8 +84,8 @@ type DelegationSet interface { // iterate through all delegations from one delegator by validator-AccAddress, // execute func for each validator - IterateDelegations(ctx sdk.Context, delegator sdk.AccAddress, - fn func(index int64, delegation DelegationI) (stop bool)) + IterateDelegations(ctx context.Context, delegator sdk.AccAddress, + fn func(index int64, delegation DelegationI) (stop bool)) error } // Event Hooks @@ -96,19 +96,19 @@ type DelegationSet interface { // 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 - - 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 - - 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 - AfterUnbondingInitiated(ctx sdk.Context, id uint64) error + 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 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 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 + AfterUnbondingInitiated(ctx context.Context, id uint64) error } // StakingHooksWrapper is a wrapper for modules to inject StakingHooks using depinject. diff --git a/x/staking/types/hooks.go b/x/staking/types/hooks.go index bdc1ffd7776c..8a052d9514a1 100644 --- a/x/staking/types/hooks.go +++ b/x/staking/types/hooks.go @@ -1,6 +1,8 @@ package types import ( + context "context" + sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" @@ -15,7 +17,7 @@ func NewMultiStakingHooks(hooks ...StakingHooks) MultiStakingHooks { return hooks } -func (h MultiStakingHooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { +func (h MultiStakingHooks) AfterValidatorCreated(ctx context.Context, valAddr sdk.ValAddress) error { for i := range h { if err := h[i].AfterValidatorCreated(ctx, valAddr); err != nil { return err @@ -25,7 +27,7 @@ func (h MultiStakingHooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.Va return nil } -func (h MultiStakingHooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) error { +func (h MultiStakingHooks) BeforeValidatorModified(ctx context.Context, valAddr sdk.ValAddress) error { for i := range h { if err := h[i].BeforeValidatorModified(ctx, valAddr); err != nil { return err @@ -34,7 +36,7 @@ func (h MultiStakingHooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk. return nil } -func (h MultiStakingHooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { +func (h MultiStakingHooks) AfterValidatorRemoved(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { for i := range h { if err := h[i].AfterValidatorRemoved(ctx, consAddr, valAddr); err != nil { return err @@ -43,7 +45,7 @@ func (h MultiStakingHooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.C return nil } -func (h MultiStakingHooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { +func (h MultiStakingHooks) AfterValidatorBonded(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { for i := range h { if err := h[i].AfterValidatorBonded(ctx, consAddr, valAddr); err != nil { return err @@ -52,7 +54,7 @@ func (h MultiStakingHooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.Co return nil } -func (h MultiStakingHooks) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { +func (h MultiStakingHooks) AfterValidatorBeginUnbonding(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { for i := range h { if err := h[i].AfterValidatorBeginUnbonding(ctx, consAddr, valAddr); err != nil { return err @@ -61,7 +63,7 @@ func (h MultiStakingHooks) AfterValidatorBeginUnbonding(ctx sdk.Context, consAdd return nil } -func (h MultiStakingHooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { +func (h MultiStakingHooks) BeforeDelegationCreated(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { for i := range h { if err := h[i].BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil { return err @@ -70,7 +72,7 @@ func (h MultiStakingHooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk. return nil } -func (h MultiStakingHooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { +func (h MultiStakingHooks) BeforeDelegationSharesModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { for i := range h { if err := h[i].BeforeDelegationSharesModified(ctx, delAddr, valAddr); err != nil { return err @@ -79,7 +81,7 @@ func (h MultiStakingHooks) BeforeDelegationSharesModified(ctx sdk.Context, delAd return nil } -func (h MultiStakingHooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { +func (h MultiStakingHooks) BeforeDelegationRemoved(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { for i := range h { if err := h[i].BeforeDelegationRemoved(ctx, delAddr, valAddr); err != nil { return err @@ -88,7 +90,7 @@ func (h MultiStakingHooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk. return nil } -func (h MultiStakingHooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { +func (h MultiStakingHooks) AfterDelegationModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { for i := range h { if err := h[i].AfterDelegationModified(ctx, delAddr, valAddr); err != nil { return err @@ -97,7 +99,7 @@ func (h MultiStakingHooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk. return nil } -func (h MultiStakingHooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdkmath.LegacyDec) error { +func (h MultiStakingHooks) BeforeValidatorSlashed(ctx context.Context, valAddr sdk.ValAddress, fraction sdkmath.LegacyDec) error { for i := range h { if err := h[i].BeforeValidatorSlashed(ctx, valAddr, fraction); err != nil { return err @@ -106,7 +108,7 @@ func (h MultiStakingHooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.V return nil } -func (h MultiStakingHooks) AfterUnbondingInitiated(ctx sdk.Context, id uint64) error { +func (h MultiStakingHooks) AfterUnbondingInitiated(ctx context.Context, id uint64) error { for i := range h { if err := h[i].AfterUnbondingInitiated(ctx, id); err != nil { return err