diff --git a/CHANGELOG.md b/CHANGELOG.md index a180881929cb..0ba3a8f26ea9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -117,6 +117,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes +* (x/distribution) [#15948](https://github.com/cosmos/cosmos-sdk/issues/15948) `NewKeeper` now takes a `KVStoreService` instead of a `StoreKey` and methods in the `Keeper` now take a `context.Context` instead of a `sdk.Context`. Keeper methods also now return an `error`. * (x/bank) [#15891](https://github.com/cosmos/cosmos-sdk/issues/15891) `NewKeeper` now takes a `KVStoreService` instead of a `StoreKey` and methods in the `Keeper` now take a `context.Context` instead of a `sdk.Context`. Also `FundAccount` and `FundModuleAccount` from the `testutil` package accept a `context.Context` instead of a `sdk.Context`, and it's position was moved to the first place. * (x/bank) [#15818](https://github.com/cosmos/cosmos-sdk/issues/15818) `BaseViewKeeper`'s `Logger` method now doesn't require a context. `NewBaseKeeper`, `NewBaseSendKeeper` and `NewBaseViewKeeper` now also require a `log.Logger` to be passed in. * (client) [#15597](https://github.com/cosmos/cosmos-sdk/pull/15597) `RegisterNodeService` now requires a config parameter. diff --git a/UPGRADING.md b/UPGRADING.md index 5e13f10a68cc..92272976a8ba 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -73,6 +73,7 @@ The following modules `NewKeeper` function now take a `KVStoreService` instead o * `x/auth` * `x/bank` * `x/consensus` +* `x/distribution` * `x/feegrant` * `x/nft` @@ -91,6 +92,11 @@ The following modules `NewKeeper` function now also take a `log.Logger`: * `x/bank` +The following modules' `Keeper` methods now take in a `context.Context` instead of `sdk.Context`. Any module that has an interfaces for them (like "expected keepers") will need to update and re-generate mocks if needed: + +* `x/bank` +* `x/distribution` + ### depinject @@ -136,8 +142,6 @@ It is now recommended to validate message directly in the message server. When t #### `x/auth` -Methods in the `AccountKeeper` now use `context.Context` instead of `sdk.Context`. Any module that has an interface for it will need to update and re-generate mocks if needed. - For ante handler construction via `ante.NewAnteHandler`, the field `ante.HandlerOptions.SignModeHandler` has been updated to `x/tx/signing/HandlerMap` from `x/auth/signing/SignModeHandler`. Callers typically fetch this value from `client.TxConfig.SignModeHandler()` (which is also changed) so this change should be transparent to most users. #### `x/capability` diff --git a/server/grpc/gogoreflection/fix_registration.go b/server/grpc/gogoreflection/fix_registration.go index d1aa6e3c8f09..ab1a18f592e9 100644 --- a/server/grpc/gogoreflection/fix_registration.go +++ b/server/grpc/gogoreflection/fix_registration.go @@ -42,12 +42,12 @@ func getExtension(extID int32, m proto.Message) *gogoproto.ExtensionDesc { for id, desc := range proto.RegisteredExtensions(m) { //nolint:staticcheck // keep for backward compatibility if id == extID { return &gogoproto.ExtensionDesc{ - ExtendedType: desc.ExtendedType, - ExtensionType: desc.ExtensionType, - Field: desc.Field, - Name: desc.Name, - Tag: desc.Tag, - Filename: desc.Filename, + ExtendedType: desc.ExtendedType, //nolint:staticcheck // keep for backward compatibility + ExtensionType: desc.ExtensionType, //nolint:staticcheck // keep for backward compatibility + Field: desc.Field, //nolint:staticcheck // keep for backward compatibility + Name: desc.Name, //nolint:staticcheck // keep for backward compatibility + Tag: desc.Tag, //nolint:staticcheck // keep for backward compatibility + Filename: desc.Filename, //nolint:staticcheck // keep for backward compatibility } } } diff --git a/simapp/app.go b/simapp/app.go index 5fb2fc14e6ad..6b68a75cc366 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -40,6 +40,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/runtime" runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" @@ -298,7 +299,7 @@ func NewSimApp( ) app.MintKeeper = mintkeeper.NewKeeper(appCodec, keys[minttypes.StoreKey], app.StakingKeeper, app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String()) - app.DistrKeeper = distrkeeper.NewKeeper(appCodec, keys[distrtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.StakingKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + app.DistrKeeper = distrkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[distrtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String()) app.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, legacyAmino, keys[slashingtypes.StoreKey], app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), @@ -624,7 +625,7 @@ func (app *SimApp) AutoCliOpts() autocli.AppOptions { } } - return autocli.AppOptions{Modules: modules} + return autocli.AppOptions{Modules: modules, AddressCodec: address.NewBech32Codec(sdk.Bech32MainPrefix)} } // DefaultGenesis returns a default genesis from the registered AppModuleBasic's. diff --git a/simapp/export.go b/simapp/export.go index 42fc8fce1a8b..8198300e0555 100644 --- a/simapp/export.go +++ b/simapp/export.go @@ -107,10 +107,18 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [] // reinitialize all validators app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { // donate any unwithdrawn outstanding reward fraction tokens to the community pool - scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) - feePool := app.DistrKeeper.GetFeePool(ctx) + scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) + if err != nil { + panic(err) + } + feePool, err := app.DistrKeeper.GetFeePool(ctx) + if err != nil { + panic(err) + } feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) - app.DistrKeeper.SetFeePool(ctx, feePool) + if err := app.DistrKeeper.SetFeePool(ctx, feePool); err != nil { + panic(err) + } if err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()); err != nil { panic(err) diff --git a/tests/integration/distribution/keeper/grpc_query_test.go b/tests/integration/distribution/keeper/grpc_query_test.go index 1c949e8595fa..38d781806344 100644 --- a/tests/integration/distribution/keeper/grpc_query_test.go +++ b/tests/integration/distribution/keeper/grpc_query_test.go @@ -100,8 +100,11 @@ func TestGRPCValidatorOutstandingRewards(t *testing.T) { tstaking.CreateValidator(f.valAddr, valConsPk0, sdk.NewInt(initialStake), true) // set outstanding rewards - f.distrKeeper.SetValidatorOutstandingRewards(f.sdkCtx, f.valAddr, types.ValidatorOutstandingRewards{Rewards: valCommission}) - rewards := f.distrKeeper.GetValidatorOutstandingRewards(f.sdkCtx, f.valAddr) + err := f.distrKeeper.SetValidatorOutstandingRewards(f.sdkCtx, f.valAddr, types.ValidatorOutstandingRewards{Rewards: valCommission}) + assert.NilError(t, err) + + rewards, err := f.distrKeeper.GetValidatorOutstandingRewards(f.sdkCtx, f.valAddr) + assert.NilError(t, err) testCases := []struct { name string diff --git a/tests/integration/distribution/keeper/msg_server_test.go b/tests/integration/distribution/keeper/msg_server_test.go index dff0054f39ba..c024734c0db6 100644 --- a/tests/integration/distribution/keeper/msg_server_test.go +++ b/tests/integration/distribution/keeper/msg_server_test.go @@ -10,7 +10,6 @@ import ( cmtabcitypes "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/proto/tendermint/types" - "github.com/stretchr/testify/require" "gotest.tools/v3/assert" "github.com/cosmos/cosmos-sdk/codec" @@ -98,7 +97,7 @@ func initFixture(t testing.TB) *fixture { stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[stakingtypes.StoreKey], accountKeeper, bankKeeper, authority.String()) distrKeeper := distrkeeper.NewKeeper( - cdc, keys[distrtypes.StoreKey], accountKeeper, bankKeeper, stakingKeeper, distrtypes.ModuleName, authority.String(), + cdc, runtime.NewKVStoreService(keys[distrtypes.StoreKey]), accountKeeper, bankKeeper, stakingKeeper, distrtypes.ModuleName, authority.String(), ) authModule := auth.NewAppModule(cdc, accountKeeper, authsims.RandomGenesisAccounts, nil) @@ -151,7 +150,8 @@ func TestMsgWithdrawDelegatorReward(t *testing.T) { CommunityPool: sdk.NewDecCoins(sdk.DecCoin{Denom: "stake", Amount: math.LegacyNewDec(10000)}), }) f.distrKeeper.SetParams(f.sdkCtx, distrtypes.DefaultParams()) - initFeePool := f.distrKeeper.GetFeePool(f.sdkCtx) + initFeePool, err := f.distrKeeper.GetFeePool(f.sdkCtx) + assert.NilError(t, err) delAddr := sdk.AccAddress(PKS[1].Address()) valConsAddr := sdk.ConsAddress(valConsPk0.Address()) @@ -195,7 +195,8 @@ func TestMsgWithdrawDelegatorReward(t *testing.T) { currentRewards := distrtypes.NewValidatorCurrentRewards(decCoins, 3) f.distrKeeper.SetValidatorCurrentRewards(f.sdkCtx, f.valAddr, currentRewards) f.distrKeeper.SetValidatorOutstandingRewards(f.sdkCtx, f.valAddr, distrtypes.ValidatorOutstandingRewards{Rewards: valCommission}) - initOutstandingRewards := f.distrKeeper.GetValidatorOutstandingRewardsCoins(f.sdkCtx, f.valAddr) + initOutstandingRewards, err := f.distrKeeper.GetValidatorOutstandingRewardsCoins(f.sdkCtx, f.valAddr) + assert.NilError(t, err) testCases := []struct { name string @@ -258,9 +259,10 @@ func TestMsgWithdrawDelegatorReward(t *testing.T) { }, } height := f.app.LastBlockHeight() - require.Panics(t, func() { - f.distrKeeper.GetPreviousProposerConsAddr(f.sdkCtx) - }) + + _, err = f.distrKeeper.GetPreviousProposerConsAddr(f.sdkCtx) + assert.Error(t, err, "previous proposer not set") + for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { @@ -275,15 +277,6 @@ func TestMsgWithdrawDelegatorReward(t *testing.T) { panic(fmt.Errorf("expected block height to be %d, got %d", height, f.app.LastBlockHeight())) } - prevProposerConsAddr := f.distrKeeper.GetPreviousProposerConsAddr(f.sdkCtx) - assert.Assert(t, prevProposerConsAddr.Empty() == false) - assert.DeepEqual(t, prevProposerConsAddr, valConsAddr) - var previousTotalPower int64 - for _, voteInfo := range f.sdkCtx.VoteInfos() { - previousTotalPower += voteInfo.Validator.Power - } - assert.Equal(t, previousTotalPower, int64(100)) - if tc.expErr { assert.ErrorContains(t, err, tc.expErrMsg) } else { @@ -300,11 +293,21 @@ func TestMsgWithdrawDelegatorReward(t *testing.T) { assert.Assert(t, initBalance.IsAllLTE(curBalance)) // check rewards - curFeePool := f.distrKeeper.GetFeePool(f.sdkCtx) + curFeePool, _ := f.distrKeeper.GetFeePool(f.sdkCtx) rewards := curFeePool.GetCommunityPool().Sub(initFeePool.CommunityPool) - curOutstandingRewards := f.distrKeeper.GetValidatorOutstandingRewards(f.sdkCtx, f.valAddr) + curOutstandingRewards, _ := f.distrKeeper.GetValidatorOutstandingRewards(f.sdkCtx, f.valAddr) assert.DeepEqual(t, rewards, initOutstandingRewards.Sub(curOutstandingRewards.Rewards)) } + + prevProposerConsAddr, err := f.distrKeeper.GetPreviousProposerConsAddr(f.sdkCtx) + assert.NilError(t, err) + assert.Assert(t, prevProposerConsAddr.Empty() == false) + assert.DeepEqual(t, prevProposerConsAddr, valConsAddr) + var previousTotalPower int64 + for _, voteInfo := range f.sdkCtx.VoteInfos() { + previousTotalPower += voteInfo.Validator.Power + } + assert.Equal(t, previousTotalPower, int64(100)) }) } } @@ -328,7 +331,7 @@ func TestMsgSetWithdrawAddress(t *testing.T) { { name: "empty delegator address", preRun: func() { - params := f.distrKeeper.GetParams(f.sdkCtx) + params, _ := f.distrKeeper.GetParams(f.sdkCtx) params.WithdrawAddrEnabled = true assert.NilError(t, f.distrKeeper.SetParams(f.sdkCtx, params)) }, @@ -342,7 +345,7 @@ func TestMsgSetWithdrawAddress(t *testing.T) { { name: "empty withdraw address", preRun: func() { - params := f.distrKeeper.GetParams(f.sdkCtx) + params, _ := f.distrKeeper.GetParams(f.sdkCtx) params.WithdrawAddrEnabled = true assert.NilError(t, f.distrKeeper.SetParams(f.sdkCtx, params)) }, @@ -356,7 +359,7 @@ func TestMsgSetWithdrawAddress(t *testing.T) { { name: "both empty addresses", preRun: func() { - params := f.distrKeeper.GetParams(f.sdkCtx) + params, _ := f.distrKeeper.GetParams(f.sdkCtx) params.WithdrawAddrEnabled = true assert.NilError(t, f.distrKeeper.SetParams(f.sdkCtx, params)) }, @@ -370,7 +373,7 @@ func TestMsgSetWithdrawAddress(t *testing.T) { { name: "withdraw address disabled", preRun: func() { - params := f.distrKeeper.GetParams(f.sdkCtx) + params, _ := f.distrKeeper.GetParams(f.sdkCtx) params.WithdrawAddrEnabled = false assert.NilError(t, f.distrKeeper.SetParams(f.sdkCtx, params)) }, @@ -384,7 +387,7 @@ func TestMsgSetWithdrawAddress(t *testing.T) { { name: "valid msg with same delegator and withdraw address", preRun: func() { - params := f.distrKeeper.GetParams(f.sdkCtx) + params, _ := f.distrKeeper.GetParams(f.sdkCtx) params.WithdrawAddrEnabled = true assert.NilError(t, f.distrKeeper.SetParams(f.sdkCtx, params)) }, @@ -397,7 +400,7 @@ func TestMsgSetWithdrawAddress(t *testing.T) { { name: "valid msg", preRun: func() { - params := f.distrKeeper.GetParams(f.sdkCtx) + params, _ := f.distrKeeper.GetParams(f.sdkCtx) params.WithdrawAddrEnabled = true assert.NilError(t, f.distrKeeper.SetParams(f.sdkCtx, params)) }, @@ -421,7 +424,7 @@ func TestMsgSetWithdrawAddress(t *testing.T) { assert.ErrorContains(t, err, tc.expErrMsg) // query the delegator withdraw address - addr := f.distrKeeper.GetDelegatorWithdrawAddr(f.sdkCtx, delAddr) + addr, _ := f.distrKeeper.GetDelegatorWithdrawAddr(f.sdkCtx, delAddr) assert.DeepEqual(t, addr, delAddr) } else { assert.NilError(t, err) @@ -433,7 +436,7 @@ func TestMsgSetWithdrawAddress(t *testing.T) { assert.NilError(t, err) // query the delegator withdraw address - addr := f.distrKeeper.GetDelegatorWithdrawAddr(f.sdkCtx, delAddr) + addr, _ := f.distrKeeper.GetDelegatorWithdrawAddr(f.sdkCtx, delAddr) assert.DeepEqual(t, addr.String(), tc.msg.WithdrawAddress) } }) @@ -529,11 +532,11 @@ func TestMsgWithdrawValidatorCommission(t *testing.T) { ), balance) // check remainder - remainder := f.distrKeeper.GetValidatorAccumulatedCommission(f.sdkCtx, f.valAddr).Commission + remainder, _ := f.distrKeeper.GetValidatorAccumulatedCommission(f.sdkCtx, f.valAddr) assert.DeepEqual(t, sdk.DecCoins{ sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(1).Quo(math.LegacyNewDec(4))), sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(1).Quo(math.LegacyNewDec(2))), - }, remainder) + }, remainder.Commission) } }) @@ -546,7 +549,7 @@ func TestMsgFundCommunityPool(t *testing.T) { // reset fee pool f.distrKeeper.SetFeePool(f.sdkCtx, distrtypes.InitialFeePool()) - initPool := f.distrKeeper.GetFeePool(f.sdkCtx) + initPool, _ := f.distrKeeper.GetFeePool(f.sdkCtx) assert.Assert(t, initPool.CommunityPool.Empty()) initTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, int64(100)) @@ -624,7 +627,8 @@ func TestMsgFundCommunityPool(t *testing.T) { assert.NilError(t, err) // query the community pool funds - assert.DeepEqual(t, initPool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(amount...)...), f.distrKeeper.GetFeePool(f.sdkCtx).CommunityPool) + feePool, _ := f.distrKeeper.GetFeePool(f.sdkCtx) + assert.DeepEqual(t, initPool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(amount...)...), feePool.CommunityPool) assert.Assert(t, f.bankKeeper.GetAllBalances(f.sdkCtx, addr).Empty()) } }) @@ -750,7 +754,7 @@ func TestMsgUpdateParams(t *testing.T) { assert.NilError(t, err) // query the params and verify it has been updated - params := f.distrKeeper.GetParams(f.sdkCtx) + params, _ := f.distrKeeper.GetParams(f.sdkCtx) assert.DeepEqual(t, distrtypes.DefaultParams(), params) } }) @@ -765,7 +769,7 @@ func TestMsgCommunityPoolSpend(t *testing.T) { f.distrKeeper.SetFeePool(f.sdkCtx, distrtypes.FeePool{ CommunityPool: sdk.NewDecCoins(sdk.DecCoin{Denom: "stake", Amount: math.LegacyNewDec(10000)}), }) - initialFeePool := f.distrKeeper.GetFeePool(f.sdkCtx) + initialFeePool, _ := f.distrKeeper.GetFeePool(f.sdkCtx) initTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, int64(100)) f.bankKeeper.MintCoins(f.sdkCtx, distrtypes.ModuleName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))) @@ -828,7 +832,7 @@ func TestMsgCommunityPoolSpend(t *testing.T) { assert.NilError(t, err) // query the community pool to verify it has been updated - communityPool := f.distrKeeper.GetFeePoolCommunityCoins(f.sdkCtx) + communityPool, _ := f.distrKeeper.GetFeePoolCommunityCoins(f.sdkCtx) newPool, negative := initialFeePool.CommunityPool.SafeSub(sdk.NewDecCoinsFromCoins(tc.msg.Amount...)) assert.Assert(t, negative == false) assert.DeepEqual(t, communityPool, newPool) @@ -928,7 +932,7 @@ func TestMsgDepositValidatorRewardsPool(t *testing.T) { assert.NilError(t, err) // check validator outstanding rewards - outstandingRewards := f.distrKeeper.GetValidatorOutstandingRewards(f.sdkCtx, val) + outstandingRewards, _ := f.distrKeeper.GetValidatorOutstandingRewards(f.sdkCtx, val) for _, c := range tc.msg.Amount { x := outstandingRewards.Rewards.AmountOf(c.Denom) assert.DeepEqual(t, x, sdk.NewDecFromInt(c.Amount)) diff --git a/x/distribution/README.md b/x/distribution/README.md index f730ed379a9b..bd7153218291 100644 --- a/x/distribution/README.md +++ b/x/distribution/README.md @@ -286,7 +286,7 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/distribution/ ``` ```go -func (k Keeper) SetWithdrawAddr(ctx sdk.Context, delegatorAddr sdk.AccAddress, withdrawAddr sdk.AccAddress) error +func (k Keeper) SetWithdrawAddr(ctx context.Context, delegatorAddr sdk.AccAddress, withdrawAddr sdk.AccAddress) error if k.blockedAddrs[withdrawAddr.String()] { fail with "`{withdrawAddr}` is not allowed to receive external funds" } @@ -351,7 +351,7 @@ This message sends coins directly from the sender to the community pool. The transaction fails if the amount cannot be transferred from the sender to the distribution module account. ```go -func (k Keeper) FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error { +func (k Keeper) FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error { if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, amount); err != nil { return err } @@ -375,7 +375,7 @@ Initializing a delegation increments the validator period and keeps track of the ```go // initialize starting info for a new delegation -func (k Keeper) initializeDelegation(ctx sdk.Context, val sdk.ValAddress, del sdk.AccAddress) { +func (k Keeper) initializeDelegation(ctx context.Context, val sdk.ValAddress, del sdk.AccAddress) { // period has already been incremented - we want to store the period ended by this delegation action previousPeriod := k.GetValidatorCurrentRewards(ctx, val).Period - 1 diff --git a/x/distribution/keeper/alias_functions.go b/x/distribution/keeper/alias_functions.go index 9a5995893b91..373bae58c896 100644 --- a/x/distribution/keeper/alias_functions.go +++ b/x/distribution/keeper/alias_functions.go @@ -1,21 +1,33 @@ package keeper import ( + "context" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/distribution/types" ) // get outstanding rewards -func (k Keeper) GetValidatorOutstandingRewardsCoins(ctx sdk.Context, val sdk.ValAddress) sdk.DecCoins { - return k.GetValidatorOutstandingRewards(ctx, val).Rewards +func (k Keeper) GetValidatorOutstandingRewardsCoins(ctx context.Context, val sdk.ValAddress) (sdk.DecCoins, error) { + rewards, err := k.GetValidatorOutstandingRewards(ctx, val) + if err != nil { + return nil, err + } + + return rewards.Rewards, nil } // get the community coins -func (k Keeper) GetFeePoolCommunityCoins(ctx sdk.Context) sdk.DecCoins { - return k.GetFeePool(ctx).CommunityPool +func (k Keeper) GetFeePoolCommunityCoins(ctx context.Context) (sdk.DecCoins, error) { + feePool, err := k.GetFeePool(ctx) + if err != nil { + return nil, err + } + + return feePool.CommunityPool, nil } // GetDistributionAccount returns the distribution ModuleAccount -func (k Keeper) GetDistributionAccount(ctx sdk.Context) sdk.ModuleAccountI { +func (k Keeper) GetDistributionAccount(ctx context.Context) sdk.ModuleAccountI { return k.authKeeper.GetModuleAccount(ctx, types.ModuleName) } diff --git a/x/distribution/keeper/allocation.go b/x/distribution/keeper/allocation.go index c306f737d5de..da330c43e7a4 100644 --- a/x/distribution/keeper/allocation.go +++ b/x/distribution/keeper/allocation.go @@ -1,6 +1,8 @@ package keeper import ( + "context" + "cosmossdk.io/math" abci "github.com/cometbft/cometbft/abci/types" @@ -11,32 +13,40 @@ import ( // AllocateTokens performs reward and fee distribution to all validators based // on the F1 fee distribution specification. -func (k Keeper) AllocateTokens(ctx sdk.Context, totalPreviousPower int64, bondedVotes []abci.VoteInfo) { +func (k Keeper) AllocateTokens(ctx context.Context, totalPreviousPower int64, bondedVotes []abci.VoteInfo) error { // 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(ctx, feeCollector.GetAddress()) + feesCollectedInt := k.bankKeeper.GetAllBalances(sdkCtx, feeCollector.GetAddress()) feesCollected := sdk.NewDecCoinsFromCoins(feesCollectedInt...) // transfer collected fees to the distribution module account - err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, k.feeCollectorName, types.ModuleName, feesCollectedInt) + err := k.bankKeeper.SendCoinsFromModuleToModule(sdkCtx, k.feeCollectorName, types.ModuleName, feesCollectedInt) if err != nil { - panic(err) + return err } // temporary workaround to keep CanWithdrawInvariant happy // general discussions here: https://github.com/cosmos/cosmos-sdk/issues/2906#issuecomment-441867634 - feePool := k.GetFeePool(ctx) + feePool, err := k.GetFeePool(ctx) + if err != nil { + return err + } + if totalPreviousPower == 0 { feePool.CommunityPool = feePool.CommunityPool.Add(feesCollected...) - k.SetFeePool(ctx, feePool) - return + return k.SetFeePool(ctx, feePool) } // calculate fraction allocated to validators remaining := feesCollected - communityTax := k.GetCommunityTax(ctx) + communityTax, err := k.GetCommunityTax(ctx) + if err != nil { + return err + } + voteMultiplier := math.LegacyOneDec().Sub(communityTax) feeMultiplier := feesCollected.MulDecTruncate(voteMultiplier) @@ -46,7 +56,7 @@ func (k Keeper) AllocateTokens(ctx sdk.Context, totalPreviousPower int64, bonded // // Ref: https://github.com/cosmos/cosmos-sdk/pull/3099#discussion_r246276376 for _, vote := range bondedVotes { - validator := k.stakingKeeper.ValidatorByConsAddr(ctx, vote.Validator.Address) + validator := k.stakingKeeper.ValidatorByConsAddr(sdkCtx, vote.Validator.Address) // TODO: Consider micro-slashing for missing votes. // @@ -54,41 +64,60 @@ func (k Keeper) AllocateTokens(ctx sdk.Context, totalPreviousPower int64, bonded powerFraction := math.LegacyNewDec(vote.Validator.Power).QuoTruncate(math.LegacyNewDec(totalPreviousPower)) reward := feeMultiplier.MulDecTruncate(powerFraction) - k.AllocateTokensToValidator(ctx, validator, reward) + err := k.AllocateTokensToValidator(ctx, validator, reward) + if err != nil { + return err + } + remaining = remaining.Sub(reward) } // allocate community funding feePool.CommunityPool = feePool.CommunityPool.Add(remaining...) - k.SetFeePool(ctx, feePool) + return k.SetFeePool(ctx, feePool) } // AllocateTokensToValidator allocate tokens to a particular validator, // splitting according to commission. -func (k Keeper) AllocateTokensToValidator(ctx sdk.Context, val stakingtypes.ValidatorI, tokens sdk.DecCoins) { +func (k Keeper) AllocateTokensToValidator(ctx context.Context, val stakingtypes.ValidatorI, tokens sdk.DecCoins) error { // split tokens between validator and delegators according to commission commission := tokens.MulDec(val.GetCommission()) shared := tokens.Sub(commission) // update current commission - ctx.EventManager().EmitEvent( + sdkCtx := sdk.UnwrapSDKContext(ctx) + sdkCtx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeCommission, sdk.NewAttribute(sdk.AttributeKeyAmount, commission.String()), sdk.NewAttribute(types.AttributeKeyValidator, val.GetOperator().String()), ), ) - currentCommission := k.GetValidatorAccumulatedCommission(ctx, val.GetOperator()) + currentCommission, err := k.GetValidatorAccumulatedCommission(ctx, val.GetOperator()) + if err != nil { + return err + } + currentCommission.Commission = currentCommission.Commission.Add(commission...) - k.SetValidatorAccumulatedCommission(ctx, val.GetOperator(), currentCommission) + err = k.SetValidatorAccumulatedCommission(ctx, val.GetOperator(), currentCommission) + if err != nil { + return err + } // update current rewards - currentRewards := k.GetValidatorCurrentRewards(ctx, val.GetOperator()) + currentRewards, err := k.GetValidatorCurrentRewards(ctx, val.GetOperator()) + if err != nil { + return err + } + currentRewards.Rewards = currentRewards.Rewards.Add(shared...) - k.SetValidatorCurrentRewards(ctx, val.GetOperator(), currentRewards) + err = k.SetValidatorCurrentRewards(ctx, val.GetOperator(), currentRewards) + if err != nil { + return err + } // update outstanding rewards - ctx.EventManager().EmitEvent( + sdkCtx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeRewards, sdk.NewAttribute(sdk.AttributeKeyAmount, tokens.String()), @@ -96,7 +125,11 @@ func (k Keeper) AllocateTokensToValidator(ctx sdk.Context, val stakingtypes.Vali ), ) - outstanding := k.GetValidatorOutstandingRewards(ctx, val.GetOperator()) + outstanding, err := k.GetValidatorOutstandingRewards(ctx, val.GetOperator()) + if err != nil { + return err + } + outstanding.Rewards = outstanding.Rewards.Add(tokens...) - k.SetValidatorOutstandingRewards(ctx, val.GetOperator(), outstanding) + return k.SetValidatorOutstandingRewards(ctx, val.GetOperator(), outstanding) } diff --git a/x/distribution/keeper/allocation_test.go b/x/distribution/keeper/allocation_test.go index bcecf5b47b14..c4277ca87179 100644 --- a/x/distribution/keeper/allocation_test.go +++ b/x/distribution/keeper/allocation_test.go @@ -12,6 +12,7 @@ import ( storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" @@ -26,6 +27,7 @@ import ( func TestAllocateTokensToValidatorWithCommission(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()}) @@ -38,7 +40,7 @@ func TestAllocateTokensToValidatorWithCommission(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -62,15 +64,21 @@ func TestAllocateTokensToValidatorWithCommission(t *testing.T) { expected := sdk.DecCoins{ {Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(5)}, } - require.Equal(t, expected, distrKeeper.GetValidatorAccumulatedCommission(ctx, val.GetOperator()).Commission) + + valCommission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, val.GetOperator()) + require.NoError(t, err) + require.Equal(t, expected, valCommission.Commission) // check current rewards - require.Equal(t, expected, distrKeeper.GetValidatorCurrentRewards(ctx, val.GetOperator()).Rewards) + currentRewards, err := distrKeeper.GetValidatorCurrentRewards(ctx, val.GetOperator()) + require.NoError(t, err) + require.Equal(t, expected, currentRewards.Rewards) } func TestAllocateTokensToManyValidators(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()}) @@ -85,7 +93,7 @@ func TestAllocateTokensToManyValidators(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -121,13 +129,33 @@ func TestAllocateTokensToManyValidators(t *testing.T) { } // assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards - require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr0).Rewards.IsZero()) - require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr1).Rewards.IsZero()) - require.True(t, distrKeeper.GetFeePool(ctx).CommunityPool.IsZero()) - require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr0).Commission.IsZero()) - require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr1).Commission.IsZero()) - require.True(t, distrKeeper.GetValidatorCurrentRewards(ctx, valAddr0).Rewards.IsZero()) - require.True(t, distrKeeper.GetValidatorCurrentRewards(ctx, valAddr1).Rewards.IsZero()) + val0OutstandingRewards, err := distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr0) + require.NoError(t, err) + require.True(t, val0OutstandingRewards.Rewards.IsZero()) + + val1OutstandingRewards, err := distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr1) + require.NoError(t, err) + require.True(t, val1OutstandingRewards.Rewards.IsZero()) + + feePool, err := distrKeeper.GetFeePool(ctx) + require.NoError(t, err) + require.True(t, feePool.CommunityPool.IsZero()) + + val0Commission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr0) + require.NoError(t, err) + require.True(t, val0Commission.Commission.IsZero()) + + val1Commission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr1) + require.NoError(t, err) + require.True(t, val1Commission.Commission.IsZero()) + + val0CurrentRewards, err := distrKeeper.GetValidatorCurrentRewards(ctx, valAddr0) + require.NoError(t, err) + require.True(t, val0CurrentRewards.Rewards.IsZero()) + + val1CurrentRewards, err := distrKeeper.GetValidatorCurrentRewards(ctx, valAddr1) + require.NoError(t, err) + require.True(t, val1CurrentRewards.Rewards.IsZero()) // allocate tokens as if both had voted and second was proposer fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))) @@ -147,28 +175,44 @@ func TestAllocateTokensToManyValidators(t *testing.T) { distrKeeper.AllocateTokens(ctx, 200, votes) // 98 outstanding rewards (100 less 2 to community pool) - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecWithPrec(490, 1)}}, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr0).Rewards) - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecWithPrec(490, 1)}}, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr1).Rewards) + val0OutstandingRewards, err = distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr0) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecWithPrec(490, 1)}}, val0OutstandingRewards.Rewards) + + val1OutstandingRewards, err = distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr1) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecWithPrec(490, 1)}}, val1OutstandingRewards.Rewards) // 2 community pool coins - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(2)}}, distrKeeper.GetFeePool(ctx).CommunityPool) + feePool, err = distrKeeper.GetFeePool(ctx) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(2)}}, feePool.CommunityPool) // 50% commission for first proposer, (0.5 * 98%) * 100 / 2 = 23.25 - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecWithPrec(2450, 2)}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr0).Commission) + val0Commission, err = distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr0) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecWithPrec(2450, 2)}}, val0Commission.Commission) // zero commission for second proposer - require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr1).Commission.IsZero()) + val1Commission, err = distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr1) + require.NoError(t, err) + require.True(t, val1Commission.Commission.IsZero()) // just staking.proportional for first proposer less commission = (0.5 * 98%) * 100 / 2 = 24.50 - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecWithPrec(2450, 2)}}, distrKeeper.GetValidatorCurrentRewards(ctx, valAddr0).Rewards) + val0CurrentRewards, err = distrKeeper.GetValidatorCurrentRewards(ctx, valAddr0) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecWithPrec(2450, 2)}}, val0CurrentRewards.Rewards) // proposer reward + staking.proportional for second proposer = (0.5 * (98%)) * 100 = 49 - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecWithPrec(490, 1)}}, distrKeeper.GetValidatorCurrentRewards(ctx, valAddr1).Rewards) + val1CurrentRewards, err = distrKeeper.GetValidatorCurrentRewards(ctx, valAddr1) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecWithPrec(490, 1)}}, val1CurrentRewards.Rewards) } func TestAllocateTokensTruncation(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()}) @@ -183,7 +227,7 @@ func TestAllocateTokensTruncation(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -230,14 +274,33 @@ func TestAllocateTokensTruncation(t *testing.T) { } // assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards - require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr0).Rewards.IsZero()) - require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr1).Rewards.IsZero()) - require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr1).Rewards.IsZero()) - require.True(t, distrKeeper.GetFeePool(ctx).CommunityPool.IsZero()) - require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr0).Commission.IsZero()) - require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr1).Commission.IsZero()) - require.True(t, distrKeeper.GetValidatorCurrentRewards(ctx, valAddr0).Rewards.IsZero()) - require.True(t, distrKeeper.GetValidatorCurrentRewards(ctx, valAddr1).Rewards.IsZero()) + val0OutstandingRewards, err := distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr0) + require.NoError(t, err) + require.True(t, val0OutstandingRewards.Rewards.IsZero()) + + val1OutstandingRewards, err := distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr1) + require.NoError(t, err) + require.True(t, val1OutstandingRewards.Rewards.IsZero()) + + feePool, err := distrKeeper.GetFeePool(ctx) + require.NoError(t, err) + require.True(t, feePool.CommunityPool.IsZero()) + + val0Commission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr0) + require.NoError(t, err) + require.True(t, val0Commission.Commission.IsZero()) + + val1Commission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr1) + require.NoError(t, err) + require.True(t, val1Commission.Commission.IsZero()) + + val0CurrentRewards, err := distrKeeper.GetValidatorCurrentRewards(ctx, valAddr0) + require.NoError(t, err) + require.True(t, val0CurrentRewards.Rewards.IsZero()) + + val1CurrentRewards, err := distrKeeper.GetValidatorCurrentRewards(ctx, valAddr1) + require.NoError(t, err) + require.True(t, val1CurrentRewards.Rewards.IsZero()) // allocate tokens as if both had voted and second was proposer fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(634195840))) @@ -260,7 +323,15 @@ func TestAllocateTokensTruncation(t *testing.T) { } distrKeeper.AllocateTokens(ctx, 31, votes) - require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr0).Rewards.IsValid()) - require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr1).Rewards.IsValid()) - require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr2).Rewards.IsValid()) + val0OutstandingRewards, err = distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr0) + require.NoError(t, err) + require.True(t, val0OutstandingRewards.Rewards.IsValid()) + + val1OutstandingRewards, err = distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr1) + require.NoError(t, err) + require.True(t, val1OutstandingRewards.Rewards.IsValid()) + + val2OutstandingRewards, err := distrKeeper.GetValidatorOutstandingRewards(ctx, valAddr2) + require.NoError(t, err) + require.True(t, val2OutstandingRewards.Rewards.IsValid()) } diff --git a/x/distribution/keeper/delegation.go b/x/distribution/keeper/delegation.go index 99c6e949ad53..ae560fc2c6f1 100644 --- a/x/distribution/keeper/delegation.go +++ b/x/distribution/keeper/delegation.go @@ -1,6 +1,7 @@ package keeper import ( + "context" "fmt" "cosmossdk.io/math" @@ -11,27 +12,32 @@ import ( ) // initialize starting info for a new delegation -func (k Keeper) initializeDelegation(ctx sdk.Context, val sdk.ValAddress, del sdk.AccAddress) { +func (k Keeper) initializeDelegation(ctx context.Context, val sdk.ValAddress, del sdk.AccAddress) error { // period has already been incremented - we want to store the period ended by this delegation action - previousPeriod := k.GetValidatorCurrentRewards(ctx, val).Period - 1 + valCurrentRewards, err := k.GetValidatorCurrentRewards(ctx, val) + if err != nil { + return err + } + previousPeriod := valCurrentRewards.Period - 1 // increment reference count for the period we're going to track k.incrementReferenceCount(ctx, val, previousPeriod) - validator := k.stakingKeeper.Validator(ctx, val) - delegation := k.stakingKeeper.Delegation(ctx, del, val) + sdkCtx := sdk.UnwrapSDKContext(ctx) + validator := k.stakingKeeper.Validator(sdkCtx, val) + delegation := k.stakingKeeper.Delegation(sdkCtx, del, val) // 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()) - k.SetDelegatorStartingInfo(ctx, val, del, types.NewDelegatorStartingInfo(previousPeriod, stake, uint64(ctx.BlockHeight()))) + return k.SetDelegatorStartingInfo(ctx, val, del, types.NewDelegatorStartingInfo(previousPeriod, stake, uint64(sdkCtx.BlockHeight()))) } // calculate the rewards accrued by a delegation between two periods -func (k Keeper) calculateDelegationRewardsBetween(ctx sdk.Context, val stakingtypes.ValidatorI, +func (k Keeper) calculateDelegationRewardsBetween(ctx context.Context, val stakingtypes.ValidatorI, startingPeriod, endingPeriod uint64, stake math.LegacyDec, -) (rewards sdk.DecCoins) { +) (sdk.DecCoins, error) { // sanity check if startingPeriod > endingPeriod { panic("startingPeriod cannot be greater than endingPeriod") @@ -43,23 +49,35 @@ func (k Keeper) calculateDelegationRewardsBetween(ctx sdk.Context, val stakingty } // return staking * (ending - starting) - starting := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), startingPeriod) - ending := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), endingPeriod) + starting, err := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), startingPeriod) + if err != nil { + return sdk.DecCoins{}, err + } + + ending, err := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), endingPeriod) + if err != nil { + return sdk.DecCoins{}, err + } + difference := ending.CumulativeRewardRatio.Sub(starting.CumulativeRewardRatio) if difference.IsAnyNegative() { panic("negative rewards should not be possible") } // note: necessary to truncate so we don't allow withdrawing more rewards than owed - rewards = difference.MulDecTruncate(stake) - return + rewards := difference.MulDecTruncate(stake) + return rewards, nil } // calculate the total rewards accrued by a delegation -func (k Keeper) CalculateDelegationRewards(ctx sdk.Context, val stakingtypes.ValidatorI, del stakingtypes.DelegationI, endingPeriod uint64) (rewards sdk.DecCoins) { +func (k Keeper) CalculateDelegationRewards(ctx context.Context, val stakingtypes.ValidatorI, del stakingtypes.DelegationI, endingPeriod uint64) (rewards sdk.DecCoins, err error) { // fetch starting info for delegation - startingInfo := k.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) + startingInfo, err := k.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) + if err != nil { + return + } - if startingInfo.Height == uint64(ctx.BlockHeight()) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + if startingInfo.Height == uint64(sdkCtx.BlockHeight()) { // started this height, no rewards yet return } @@ -77,13 +95,17 @@ func (k Keeper) CalculateDelegationRewards(ctx sdk.Context, val stakingtypes.Val startingHeight := startingInfo.Height // Slashes this block happened after reward allocation, but we have to account // for them for the stake sanity check below. - endingHeight := uint64(ctx.BlockHeight()) + endingHeight := uint64(sdkCtx.BlockHeight()) if endingHeight > startingHeight { k.IterateValidatorSlashEventsBetween(ctx, del.GetValidatorAddr(), startingHeight, endingHeight, func(height uint64, event types.ValidatorSlashEvent) (stop bool) { endingPeriod := event.ValidatorPeriod if endingPeriod > startingPeriod { - rewards = rewards.Add(k.calculateDelegationRewardsBetween(ctx, val, startingPeriod, endingPeriod, stake)...) + delRewards, err := k.calculateDelegationRewardsBetween(ctx, val, startingPeriod, endingPeriod, stake) + if err != nil { + panic(err) + } + rewards = rewards.Add(delRewards...) // Note: It is necessary to truncate so we don't allow withdrawing // more rewards than owed. @@ -134,20 +156,41 @@ func (k Keeper) CalculateDelegationRewards(ctx sdk.Context, val stakingtypes.Val } // calculate rewards for final period - rewards = rewards.Add(k.calculateDelegationRewardsBetween(ctx, val, startingPeriod, endingPeriod, stake)...) - return rewards + delRewards, err := k.calculateDelegationRewardsBetween(ctx, val, startingPeriod, endingPeriod, stake) + if err != nil { + return sdk.DecCoins{}, err + } + + rewards = rewards.Add(delRewards...) + return rewards, nil } -func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val stakingtypes.ValidatorI, del stakingtypes.DelegationI) (sdk.Coins, error) { +func (k Keeper) withdrawDelegationRewards(ctx context.Context, val stakingtypes.ValidatorI, del stakingtypes.DelegationI) (sdk.Coins, error) { // check existence of delegator starting info - if !k.HasDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) { + hasInfo, err := k.HasDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) + if err != nil { + return nil, err + } + + if !hasInfo { return nil, types.ErrEmptyDelegationDistInfo } // end current period and calculate rewards - endingPeriod := k.IncrementValidatorPeriod(ctx, val) - rewardsRaw := k.CalculateDelegationRewards(ctx, val, del, endingPeriod) - outstanding := k.GetValidatorOutstandingRewardsCoins(ctx, del.GetValidatorAddr()) + endingPeriod, err := k.IncrementValidatorPeriod(ctx, val) + if err != nil { + return nil, err + } + + rewardsRaw, err := k.CalculateDelegationRewards(ctx, val, del, endingPeriod) + if err != nil { + return nil, err + } + + outstanding, err := k.GetValidatorOutstandingRewardsCoins(ctx, del.GetValidatorAddr()) + if err != nil { + return nil, err + } // defensive edge case may happen on the very final digits // of the decCoins due to operation order of the distribution mechanism. @@ -168,8 +211,12 @@ func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val stakingtypes.Vali // add coins to user account if !finalRewards.IsZero() { - withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, del.GetDelegatorAddr()) - err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, withdrawAddr, finalRewards) + withdrawAddr, err := k.GetDelegatorWithdrawAddr(ctx, del.GetDelegatorAddr()) + if err != nil { + return nil, err + } + + err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, withdrawAddr, finalRewards) if err != nil { return nil, err } @@ -177,18 +224,39 @@ func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val stakingtypes.Vali // update the outstanding rewards and the community pool only if the // transaction was successful - k.SetValidatorOutstandingRewards(ctx, del.GetValidatorAddr(), types.ValidatorOutstandingRewards{Rewards: outstanding.Sub(rewards)}) - feePool := k.GetFeePool(ctx) + err = k.SetValidatorOutstandingRewards(ctx, del.GetValidatorAddr(), types.ValidatorOutstandingRewards{Rewards: outstanding.Sub(rewards)}) + if err != nil { + return nil, err + } + + feePool, err := k.GetFeePool(ctx) + if err != nil { + return nil, err + } + feePool.CommunityPool = feePool.CommunityPool.Add(remainder...) - k.SetFeePool(ctx, feePool) + err = k.SetFeePool(ctx, feePool) + if err != nil { + return nil, err + } // decrement reference count of starting period - startingInfo := k.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) + startingInfo, err := k.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) + if err != nil { + return nil, err + } + startingPeriod := startingInfo.PreviousPeriod - k.decrementReferenceCount(ctx, del.GetValidatorAddr(), startingPeriod) + err = k.decrementReferenceCount(ctx, del.GetValidatorAddr(), startingPeriod) + if err != nil { + return nil, err + } // remove delegator starting info - k.DeleteDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) + err = k.DeleteDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) + if err != nil { + return nil, err + } if finalRewards.IsZero() { baseDenom, _ := sdk.GetBaseDenom() @@ -201,7 +269,8 @@ func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val stakingtypes.Vali finalRewards = sdk.Coins{sdk.NewCoin(baseDenom, math.ZeroInt())} } - ctx.EventManager().EmitEvent( + sdkCtx := sdk.UnwrapSDKContext(ctx) + sdkCtx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeWithdrawRewards, sdk.NewAttribute(sdk.AttributeKeyAmount, finalRewards.String()), diff --git a/x/distribution/keeper/delegation_test.go b/x/distribution/keeper/delegation_test.go index 80883c204d1e..e15828d8386b 100644 --- a/x/distribution/keeper/delegation_test.go +++ b/x/distribution/keeper/delegation_test.go @@ -10,6 +10,7 @@ import ( "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" @@ -24,6 +25,7 @@ import ( func TestCalculateRewardsBasic(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Height: 1}) @@ -36,7 +38,7 @@ func TestCalculateRewardsBasic(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -70,13 +72,14 @@ func TestCalculateRewardsBasic(t *testing.T) { require.Equal(t, uint64(2), distrKeeper.GetValidatorHistoricalReferenceCount(ctx)) // end period - endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ := distrKeeper.IncrementValidatorPeriod(ctx, val) // historical count should be 2 still require.Equal(t, uint64(2), distrKeeper.GetValidatorHistoricalReferenceCount(ctx)) // calculate delegation rewards - rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards should be zero require.True(t, rewards.IsZero()) @@ -87,21 +90,25 @@ func TestCalculateRewardsBasic(t *testing.T) { distrKeeper.AllocateTokensToValidator(ctx, val, tokens) // end period - endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ = distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards should be half the tokens require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}}, rewards) // commission should be the other half - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr).Commission) + valCommission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}}, valCommission.Commission) } func TestCalculateRewardsAfterSlash(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Height: 1}) @@ -114,7 +121,7 @@ func TestCalculateRewardsAfterSlash(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -149,10 +156,11 @@ func TestCalculateRewardsAfterSlash(t *testing.T) { ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) // end period - endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ := distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards - rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards should be zero require.True(t, rewards.IsZero()) @@ -181,22 +189,26 @@ func TestCalculateRewardsAfterSlash(t *testing.T) { distrKeeper.AllocateTokensToValidator(ctx, val, tokens) // end period - endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ = distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards should be half the tokens require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecFromInt(initial.QuoRaw(2))}}, rewards) // commission should be the other half + valCommission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr) + require.NoError(t, err) require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecFromInt(initial.QuoRaw(2))}}, - distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr).Commission) + valCommission.Commission) } func TestCalculateRewardsAfterManySlashes(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Height: 1}) @@ -209,7 +221,7 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -243,10 +255,11 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) { ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) // end period - endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ := distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards - rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards should be zero require.True(t, rewards.IsZero()) @@ -296,22 +309,26 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) { distrKeeper.AllocateTokensToValidator(ctx, val, tokens) // end period - endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ = distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards should be half the tokens require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecFromInt(initial)}}, rewards) // commission should be the other half + valCommission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr) + require.NoError(t, err) require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDecFromInt(initial)}}, - distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr).Commission) + valCommission.Commission) } func TestCalculateRewardsMultiDelegator(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Height: 1}) @@ -324,7 +341,7 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -381,27 +398,32 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) { distrKeeper.AllocateTokensToValidator(ctx, val, tokens) // end period - endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ := distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards for del1 - rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del0, endingPeriod) + rewards, err := distrKeeper.CalculateDelegationRewards(ctx, val, del0, endingPeriod) + require.NoError(t, err) // rewards for del0 should be 3/4 initial require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial * 3 / 4)}}, rewards) // calculate delegation rewards for del2 - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del1, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del1, endingPeriod) + require.NoError(t, err) // rewards for del2 should be 1/4 initial require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial * 1 / 4)}}, rewards) // commission should be equal to initial (50% twice) - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial)}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr).Commission) + valCommission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial)}}, valCommission.Commission) } func TestWithdrawDelegationRewardsBasic(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Height: 1}) @@ -414,7 +436,7 @@ func TestWithdrawDelegationRewardsBasic(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -474,6 +496,7 @@ func TestWithdrawDelegationRewardsBasic(t *testing.T) { func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Height: 1}) @@ -486,7 +509,7 @@ func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -519,10 +542,11 @@ func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) { ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) // end period - endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ := distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards - rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards should be zero require.True(t, rewards.IsZero()) @@ -566,21 +590,25 @@ func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) { distrKeeper.AllocateTokensToValidator(ctx, val, tokens) // end period - endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ = distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards should be half the tokens require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}}, rewards) // commission should be the other half - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr).Commission) + valCommission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}}, valCommission.Commission) } func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Height: 1}) @@ -593,7 +621,7 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -687,27 +715,32 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) { ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3) // end period - endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ := distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards for del1 - rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards for del1 should be 2/3 initial (half initial first period, 1/6 initial second period) require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial.QuoInt64(2).Add(initial.QuoInt64(6))}}, rewards) // calculate delegation rewards for del2 - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod) + require.NoError(t, err) // rewards for del2 should be initial / 3 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial.QuoInt64(3)}}, rewards) // commission should be equal to initial (twice 50% commission, unaffected by slashing) - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr).Commission) + valCommission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}}, valCommission.Commission) } func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Height: 1}) @@ -720,7 +753,7 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -810,22 +843,26 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { require.NoError(t, err) // end period - endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ := distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards for del1 - rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards for del1 should be zero require.True(t, rewards.IsZero()) // calculate delegation rewards for del2 - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod) + require.NoError(t, err) // rewards for del2 should be zero require.True(t, rewards.IsZero()) // commission should be zero - require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr).Commission.IsZero()) + valCommission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr) + require.NoError(t, err) + require.True(t, valCommission.Commission.IsZero()) // next block ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) @@ -840,22 +877,26 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { require.NoError(t, err) // end period - endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ = distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards for del1 - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards for del1 should be zero require.True(t, rewards.IsZero()) // calculate delegation rewards for del2 - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod) + require.NoError(t, err) // rewards for del2 should be 1/4 initial require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 4)}}, rewards) // commission should be half initial - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr).Commission) + valCommission, err = distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr) + require.NoError(t, err) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}}, valCommission.Commission) // next block ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) @@ -870,27 +911,32 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { require.NoError(t, err) // end period - endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val) + endingPeriod, _ = distrKeeper.IncrementValidatorPeriod(ctx, val) // calculate delegation rewards for del1 - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) + require.NoError(t, err) // rewards for del1 should be 1/4 initial require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 4)}}, rewards) // calculate delegation rewards for del2 - rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod) + rewards, err = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod) + require.NoError(t, err) // rewards for del2 should be 1/2 initial require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}}, rewards) // commission should be zero - require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr).Commission.IsZero()) + valCommission, err = distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr) + require.NoError(t, err) + require.True(t, valCommission.Commission.IsZero()) } func Test100PercentCommissionReward(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(disttypes.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Height: 1}) @@ -903,7 +949,7 @@ func Test100PercentCommissionReward(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, diff --git a/x/distribution/keeper/fee_pool.go b/x/distribution/keeper/fee_pool.go index a6047501355c..b8bb8bf7ee64 100644 --- a/x/distribution/keeper/fee_pool.go +++ b/x/distribution/keeper/fee_pool.go @@ -1,14 +1,19 @@ package keeper import ( + "context" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/distribution/types" ) // DistributeFromFeePool distributes funds from the distribution module account to // a receiver address while updating the community pool -func (k Keeper) DistributeFromFeePool(ctx sdk.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error { - feePool := k.GetFeePool(ctx) +func (k Keeper) DistributeFromFeePool(ctx context.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error { + feePool, err := k.GetFeePool(ctx) + if err != nil { + return err + } // NOTE the community pool isn't a module account, however its coins // are held in the distribution module account. Thus the community pool @@ -20,11 +25,10 @@ func (k Keeper) DistributeFromFeePool(ctx sdk.Context, amount sdk.Coins, receive feePool.CommunityPool = newPool - err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, receiveAddr, amount) + err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, receiveAddr, amount) if err != nil { return err } - k.SetFeePool(ctx, feePool) - return nil + return k.SetFeePool(ctx, feePool) } diff --git a/x/distribution/keeper/genesis.go b/x/distribution/keeper/genesis.go index 8c6ac54cf397..ad0024ee4bd2 100644 --- a/x/distribution/keeper/genesis.go +++ b/x/distribution/keeper/genesis.go @@ -109,8 +109,15 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data types.GenesisState) { // ExportGenesis returns a GenesisState for a given context and keeper. func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { - feePool := k.GetFeePool(ctx) - params := k.GetParams(ctx) + feePool, err := k.GetFeePool(ctx) + if err != nil { + panic(err) + } + + params, err := k.GetParams(ctx) + if err != nil { + panic(err) + } dwi := make([]types.DelegatorWithdrawInfo, 0) k.IterateDelegatorWithdrawAddrs(ctx, func(del, addr sdk.AccAddress) (stop bool) { @@ -121,7 +128,11 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { return false }) - pp := k.GetPreviousProposerConsAddr(ctx) + pp, err := k.GetPreviousProposerConsAddr(ctx) + if err != nil { + panic(err) + } + outstanding := make([]types.ValidatorOutstandingRewardsRecord, 0) k.IterateValidatorOutstandingRewards(ctx, diff --git a/x/distribution/keeper/grpc_query.go b/x/distribution/keeper/grpc_query.go index 99bc45a410ae..c780a92632b9 100644 --- a/x/distribution/keeper/grpc_query.go +++ b/x/distribution/keeper/grpc_query.go @@ -9,6 +9,7 @@ import ( "cosmossdk.io/errors" "cosmossdk.io/store/prefix" + "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/distribution/types" @@ -27,8 +28,10 @@ func NewQuerier(keeper Keeper) Querier { // Params queries params of distribution module func (k Querier) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { - ctx := sdk.UnwrapSDKContext(c) - params := k.GetParams(ctx) + params, err := k.GetParams(c) + if err != nil { + return nil, err + } return &types.QueryParamsResponse{Params: params}, nil } @@ -63,11 +66,21 @@ func (k Querier) ValidatorDistributionInfo(c context.Context, req *types.QueryVa return nil, types.ErrNoDelegationExists } - endingPeriod := k.IncrementValidatorPeriod(ctx, val) - rewards := k.CalculateDelegationRewards(ctx, val, del, endingPeriod) + endingPeriod, err := k.IncrementValidatorPeriod(ctx, val) + if err != nil { + return nil, err + } + + rewards, err := k.CalculateDelegationRewards(ctx, val, del, endingPeriod) + if err != nil { + return nil, err + } // validator's commission - validatorCommission := k.GetValidatorAccumulatedCommission(ctx, valAdr) + validatorCommission, err := k.GetValidatorAccumulatedCommission(ctx, valAdr) + if err != nil { + return nil, err + } return &types.QueryValidatorDistributionInfoResponse{ Commission: validatorCommission.Commission, @@ -97,7 +110,11 @@ func (k Querier) ValidatorOutstandingRewards(c context.Context, req *types.Query if validator == nil { return nil, errors.Wrapf(types.ErrNoValidatorExists, valAdr.String()) } - rewards := k.GetValidatorOutstandingRewards(ctx, valAdr) + + rewards, err := k.GetValidatorOutstandingRewards(ctx, valAdr) + if err != nil { + return nil, err + } return &types.QueryValidatorOutstandingRewardsResponse{Rewards: rewards}, nil } @@ -123,7 +140,10 @@ func (k Querier) ValidatorCommission(c context.Context, req *types.QueryValidato if validator == nil { return nil, errors.Wrapf(types.ErrNoValidatorExists, valAdr.String()) } - commission := k.GetValidatorAccumulatedCommission(ctx, valAdr) + commission, err := k.GetValidatorAccumulatedCommission(ctx, valAdr) + if err != nil { + return nil, err + } return &types.QueryValidatorCommissionResponse{Commission: commission}, nil } @@ -142,12 +162,12 @@ func (k Querier) ValidatorSlashes(c context.Context, req *types.QueryValidatorSl return nil, status.Errorf(codes.InvalidArgument, "starting height greater than ending height (%d > %d)", req.StartingHeight, req.EndingHeight) } - ctx := sdk.UnwrapSDKContext(c) - store := ctx.KVStore(k.storeKey) valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddress) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid validator address") } + + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(c)) 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) { @@ -206,8 +226,15 @@ func (k Querier) DelegationRewards(c context.Context, req *types.QueryDelegation return nil, types.ErrNoDelegationExists } - endingPeriod := k.IncrementValidatorPeriod(ctx, val) - rewards := k.CalculateDelegationRewards(ctx, val, del, endingPeriod) + endingPeriod, err := k.IncrementValidatorPeriod(ctx, val) + if err != nil { + return nil, err + } + + rewards, err := k.CalculateDelegationRewards(ctx, val, del, endingPeriod) + if err != nil { + return nil, err + } return &types.QueryDelegationRewardsResponse{Rewards: rewards}, nil } @@ -237,8 +264,15 @@ func (k Querier) DelegationTotalRewards(c context.Context, req *types.QueryDeleg func(_ int64, del stakingtypes.DelegationI) (stop bool) { valAddr := del.GetValidatorAddr() val := k.stakingKeeper.Validator(ctx, valAddr) - endingPeriod := k.IncrementValidatorPeriod(ctx, val) - delReward := k.CalculateDelegationRewards(ctx, val, del, endingPeriod) + endingPeriod, err := k.IncrementValidatorPeriod(ctx, val) + if err != nil { + panic(err) + } + + delReward, err := k.CalculateDelegationRewards(ctx, val, del, endingPeriod) + if err != nil { + panic(err) + } delRewards = append(delRewards, types.NewDelegationDelegatorReward(valAddr, delReward)) total = total.Add(delReward...) @@ -291,16 +325,20 @@ func (k Querier) DelegatorWithdrawAddress(c context.Context, req *types.QueryDel return nil, err } - ctx := sdk.UnwrapSDKContext(c) - withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, delAdr) + withdrawAddr, err := k.GetDelegatorWithdrawAddr(c, delAdr) + if err != nil { + return nil, err + } return &types.QueryDelegatorWithdrawAddressResponse{WithdrawAddress: withdrawAddr.String()}, nil } // CommunityPool queries the community pool coins func (k Querier) CommunityPool(c context.Context, req *types.QueryCommunityPoolRequest) (*types.QueryCommunityPoolResponse, error) { - ctx := sdk.UnwrapSDKContext(c) - pool := k.GetFeePoolCommunityCoins(ctx) + pool, err := k.GetFeePoolCommunityCoins(c) + if err != nil { + return nil, err + } return &types.QueryCommunityPoolResponse{Pool: pool}, nil } diff --git a/x/distribution/keeper/hooks.go b/x/distribution/keeper/hooks.go index 8179048dd514..e0574a250c4c 100644 --- a/x/distribution/keeper/hooks.go +++ b/x/distribution/keeper/hooks.go @@ -23,17 +23,25 @@ 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) - h.k.initializeValidator(ctx, val) - return nil + 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 { // fetch outstanding - outstanding := h.k.GetValidatorOutstandingRewardsCoins(ctx, valAddr) + outstanding, err := h.k.GetValidatorOutstandingRewardsCoins(ctx, valAddr) + if err != nil { + return err + } // force-withdraw commission - commission := h.k.GetValidatorAccumulatedCommission(ctx, valAddr).Commission + valCommission, err := h.k.GetValidatorAccumulatedCommission(ctx, valAddr) + if err != nil { + return err + } + + commission := valCommission.Commission + if !commission.IsZero() { // subtract from outstanding outstanding = outstanding.Sub(commission) @@ -42,14 +50,24 @@ func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr coins, remainder := commission.TruncateDecimal() // remainder to community pool - feePool := h.k.GetFeePool(ctx) + feePool, err := h.k.GetFeePool(ctx) + if err != nil { + return err + } + feePool.CommunityPool = feePool.CommunityPool.Add(remainder...) - h.k.SetFeePool(ctx, feePool) + err = h.k.SetFeePool(ctx, feePool) + if err != nil { + return err + } // add to validator account if !coins.IsZero() { accAddr := sdk.AccAddress(valAddr) - withdrawAddr := h.k.GetDelegatorWithdrawAddr(ctx, accAddr) + withdrawAddr, err := h.k.GetDelegatorWithdrawAddr(ctx, accAddr) + if err != nil { + return err + } if err := h.k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, withdrawAddr, coins); err != nil { return err @@ -60,15 +78,28 @@ func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr // Add outstanding to community pool // The validator is removed only after it has no more delegations. // This operation sends only the remaining dust to the community pool. - feePool := h.k.GetFeePool(ctx) + feePool, err := h.k.GetFeePool(ctx) + if err != nil { + return err + } + feePool.CommunityPool = feePool.CommunityPool.Add(outstanding...) - h.k.SetFeePool(ctx, feePool) + err = h.k.SetFeePool(ctx, feePool) + if err != nil { + return err + } // delete outstanding - h.k.DeleteValidatorOutstandingRewards(ctx, valAddr) + err = h.k.DeleteValidatorOutstandingRewards(ctx, valAddr) + if err != nil { + return err + } // remove commission record - h.k.DeleteValidatorAccumulatedCommission(ctx, valAddr) + err = h.k.DeleteValidatorAccumulatedCommission(ctx, valAddr) + if err != nil { + return err + } // clear slashes h.k.DeleteValidatorSlashEvents(ctx, valAddr) @@ -77,7 +108,10 @@ func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr h.k.DeleteValidatorHistoricalRewards(ctx, valAddr) // clear current rewards - h.k.DeleteValidatorCurrentRewards(ctx, valAddr) + err = h.k.DeleteValidatorCurrentRewards(ctx, valAddr) + if err != nil { + return err + } return nil } @@ -85,8 +119,8 @@ 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) - _ = h.k.IncrementValidatorPeriod(ctx, val) - return nil + _, err := h.k.IncrementValidatorPeriod(ctx, val) + return err } // withdraw delegation rewards (which also increments period) @@ -103,8 +137,7 @@ 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 { - h.k.initializeDelegation(ctx, valAddr, delAddr) - return nil + return h.k.initializeDelegation(ctx, valAddr, delAddr) } // record the slash event diff --git a/x/distribution/keeper/invariants.go b/x/distribution/keeper/invariants.go index 8519a4e408bd..68a79d77550d 100644 --- a/x/distribution/keeper/invariants.go +++ b/x/distribution/keeper/invariants.go @@ -88,7 +88,12 @@ func CanWithdrawInvariant(k Keeper) sdk.Invariant { } } - remaining = k.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) + var err error + remaining, err = k.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) + if err != nil { + panic(err) + } + if len(remaining) > 0 && remaining[0].Amount.IsNegative() { return true } @@ -141,7 +146,11 @@ func ModuleAccountInvariant(k Keeper) sdk.Invariant { return false }) - communityPool := k.GetFeePoolCommunityCoins(ctx) + communityPool, err := k.GetFeePoolCommunityCoins(ctx) + if err != nil { + panic(err) + } + expectedInt, _ := expectedCoins.Add(communityPool...).TruncateDecimal() macc := k.GetDistributionAccount(ctx) diff --git a/x/distribution/keeper/keeper.go b/x/distribution/keeper/keeper.go index 8969d6478de0..9bdbe8b9c704 100644 --- a/x/distribution/keeper/keeper.go +++ b/x/distribution/keeper/keeper.go @@ -1,11 +1,12 @@ package keeper import ( + "context" "fmt" + "cosmossdk.io/core/store" errorsmod "cosmossdk.io/errors" "cosmossdk.io/log" - storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -15,7 +16,7 @@ import ( // Keeper of the distribution store type Keeper struct { - storeKey storetypes.StoreKey + storeService store.KVStoreService cdc codec.BinaryCodec authKeeper types.AccountKeeper bankKeeper types.BankKeeper @@ -29,7 +30,7 @@ type Keeper struct { // NewKeeper creates a new distribution Keeper instance func NewKeeper( - cdc codec.BinaryCodec, key storetypes.StoreKey, + cdc codec.BinaryCodec, storeService store.KVStoreService, ak types.AccountKeeper, bk types.BankKeeper, sk types.StakingKeeper, feeCollectorName, authority string, ) Keeper { @@ -39,7 +40,7 @@ func NewKeeper( } return Keeper{ - storeKey: key, + storeService: storeService, cdc: cdc, authKeeper: ak, bankKeeper: bk, @@ -55,21 +56,28 @@ func (k Keeper) GetAuthority() string { } // 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(log.ModuleKey, "x/"+types.ModuleName) } // SetWithdrawAddr sets a new address that will receive the rewards upon withdrawal -func (k Keeper) SetWithdrawAddr(ctx sdk.Context, delegatorAddr, withdrawAddr sdk.AccAddress) error { +func (k Keeper) SetWithdrawAddr(ctx context.Context, delegatorAddr, withdrawAddr sdk.AccAddress) error { if k.bankKeeper.BlockedAddr(withdrawAddr) { return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive external funds", withdrawAddr) } - if !k.GetWithdrawAddrEnabled(ctx) { + withdrawAddrEnabled, err := k.GetWithdrawAddrEnabled(ctx) + if err != nil { + return err + } + + if !withdrawAddrEnabled { return types.ErrSetWithdrawAddrDisabled } - ctx.EventManager().EmitEvent( + sdkCtx := sdk.UnwrapSDKContext(ctx) + sdkCtx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeSetWithdrawAddress, sdk.NewAttribute(types.AttributeKeyWithdrawAddress, withdrawAddr.String()), @@ -81,32 +89,40 @@ func (k Keeper) SetWithdrawAddr(ctx sdk.Context, delegatorAddr, withdrawAddr sdk } // withdraw rewards from a delegation -func (k Keeper) WithdrawDelegationRewards(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (sdk.Coins, error) { - val := k.stakingKeeper.Validator(ctx, valAddr) +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) if val == nil { return nil, types.ErrNoValidatorDistInfo } - del := k.stakingKeeper.Delegation(ctx, delAddr, valAddr) + del := k.stakingKeeper.Delegation(sdkCtx, delAddr, valAddr) if del == nil { return nil, types.ErrEmptyDelegationDistInfo } // withdraw rewards - rewards, err := k.withdrawDelegationRewards(ctx, val, del) + rewards, err := k.withdrawDelegationRewards(sdkCtx, val, del) if err != nil { return nil, err } // reinitialize the delegation - k.initializeDelegation(ctx, valAddr, delAddr) + err = k.initializeDelegation(sdkCtx, valAddr, delAddr) + if err != nil { + return nil, err + } return rewards, nil } // withdraw validator commission -func (k Keeper) WithdrawValidatorCommission(ctx sdk.Context, valAddr sdk.ValAddress) (sdk.Coins, error) { +func (k Keeper) WithdrawValidatorCommission(ctx context.Context, valAddr sdk.ValAddress) (sdk.Coins, error) { // fetch validator accumulated commission - accumCommission := k.GetValidatorAccumulatedCommission(ctx, valAddr) + accumCommission, err := k.GetValidatorAccumulatedCommission(ctx, valAddr) + if err != nil { + return nil, err + } + if accumCommission.Commission.IsZero() { return nil, types.ErrNoValidatorCommission } @@ -115,19 +131,31 @@ func (k Keeper) WithdrawValidatorCommission(ctx sdk.Context, valAddr sdk.ValAddr k.SetValidatorAccumulatedCommission(ctx, valAddr, types.ValidatorAccumulatedCommission{Commission: remainder}) // leave remainder to withdraw later // update outstanding - outstanding := k.GetValidatorOutstandingRewards(ctx, valAddr).Rewards - k.SetValidatorOutstandingRewards(ctx, valAddr, types.ValidatorOutstandingRewards{Rewards: outstanding.Sub(sdk.NewDecCoinsFromCoins(commission...))}) + outstanding, err := k.GetValidatorOutstandingRewards(ctx, valAddr) + if err != nil { + return nil, err + } + + err = k.SetValidatorOutstandingRewards(ctx, valAddr, types.ValidatorOutstandingRewards{Rewards: outstanding.Rewards.Sub(sdk.NewDecCoinsFromCoins(commission...))}) + if err != nil { + return nil, err + } if !commission.IsZero() { accAddr := sdk.AccAddress(valAddr) - withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, accAddr) - err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, withdrawAddr, commission) + withdrawAddr, err := k.GetDelegatorWithdrawAddr(ctx, accAddr) + if err != nil { + return nil, err + } + + err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, withdrawAddr, commission) if err != nil { return nil, err } } - ctx.EventManager().EmitEvent( + sdkCtx := sdk.UnwrapSDKContext(ctx) + sdkCtx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeWithdrawCommission, sdk.NewAttribute(sdk.AttributeKeyAmount, commission.String()), @@ -138,7 +166,7 @@ func (k Keeper) WithdrawValidatorCommission(ctx sdk.Context, valAddr sdk.ValAddr } // GetTotalRewards returns the total amount of fee distribution rewards held in the store -func (k Keeper) GetTotalRewards(ctx sdk.Context) (totalRewards sdk.DecCoins) { +func (k Keeper) GetTotalRewards(ctx context.Context) (totalRewards sdk.DecCoins) { k.IterateValidatorOutstandingRewards(ctx, func(_ sdk.ValAddress, rewards types.ValidatorOutstandingRewards) (stop bool) { totalRewards = totalRewards.Add(rewards.Rewards...) @@ -153,14 +181,16 @@ func (k Keeper) GetTotalRewards(ctx sdk.Context) (totalRewards sdk.DecCoins) { // The amount is first added to the distribution module account and then directly // added to the pool. An error is returned if the amount cannot be sent to the // module account. -func (k Keeper) FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error { +func (k Keeper) FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error { if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, amount); err != nil { return err } - feePool := k.GetFeePool(ctx) - feePool.CommunityPool = feePool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(amount...)...) - k.SetFeePool(ctx, feePool) + feePool, err := k.GetFeePool(ctx) + if err != nil { + return err + } - return nil + feePool.CommunityPool = feePool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(amount...)...) + return k.SetFeePool(ctx, feePool) } diff --git a/x/distribution/keeper/keeper_test.go b/x/distribution/keeper/keeper_test.go index 33d28b1c56df..80496801312e 100644 --- a/x/distribution/keeper/keeper_test.go +++ b/x/distribution/keeper/keeper_test.go @@ -11,6 +11,7 @@ import ( storetypes "cosmossdk.io/store/types" + "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" @@ -25,6 +26,7 @@ import ( func TestSetWithdrawAddr(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(types.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()}) @@ -44,7 +46,7 @@ func TestSetWithdrawAddr(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -71,6 +73,7 @@ func TestSetWithdrawAddr(t *testing.T) { func TestWithdrawValidatorCommission(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(types.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()}) @@ -91,7 +94,7 @@ func TestWithdrawValidatorCommission(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -114,18 +117,19 @@ func TestWithdrawValidatorCommission(t *testing.T) { require.NoError(t, err) // check remainder - remainder := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr).Commission + remainderValCommission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr) + require.NoError(t, err) + remainder := remainderValCommission.Commission require.Equal(t, sdk.DecCoins{ sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(1).Quo(math.LegacyNewDec(4))), sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(1).Quo(math.LegacyNewDec(2))), }, remainder) - - require.True(t, true) } func TestGetTotalRewards(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(types.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()}) @@ -142,7 +146,7 @@ func TestGetTotalRewards(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -167,6 +171,7 @@ func TestGetTotalRewards(t *testing.T) { func TestFundCommunityPool(t *testing.T) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(types.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()}) @@ -180,7 +185,7 @@ func TestFundCommunityPool(t *testing.T) { distrKeeper := keeper.NewKeeper( encCfg.Codec, - key, + storeService, accountKeeper, bankKeeper, stakingKeeper, @@ -191,13 +196,16 @@ func TestFundCommunityPool(t *testing.T) { // reset fee pool distrKeeper.SetFeePool(ctx, types.InitialFeePool()) - initPool := distrKeeper.GetFeePool(ctx) + initPool, err := distrKeeper.GetFeePool(ctx) + require.NoError(t, err) require.Empty(t, initPool.CommunityPool) amount := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), addrs[0], "distribution", amount).Return(nil) - err := distrKeeper.FundCommunityPool(ctx, amount, addrs[0]) - require.Nil(t, err) + err = distrKeeper.FundCommunityPool(ctx, amount, addrs[0]) + require.NoError(t, err) - require.Equal(t, initPool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(amount...)...), distrKeeper.GetFeePool(ctx).CommunityPool) + feePool, err := distrKeeper.GetFeePool(ctx) + require.NoError(t, err) + require.Equal(t, initPool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(amount...)...), feePool.CommunityPool) } diff --git a/x/distribution/keeper/migrations.go b/x/distribution/keeper/migrations.go index c60846669f5d..bfcf8805e39f 100644 --- a/x/distribution/keeper/migrations.go +++ b/x/distribution/keeper/migrations.go @@ -20,7 +20,7 @@ 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) + return v2.MigrateStore(ctx, m.keeper.storeService) } // Migrate2to3 migrates the x/distribution module state from the consensus @@ -28,5 +28,5 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error { // and managed by the x/params module and stores them directly into the x/distribution // module state. func (m Migrator) Migrate2to3(ctx sdk.Context) error { - return v3.MigrateStore(ctx, m.keeper.storeKey, m.legacySubspace, m.keeper.cdc) + return v3.MigrateStore(ctx, m.keeper.storeService, m.legacySubspace, m.keeper.cdc) } diff --git a/x/distribution/keeper/msg_server.go b/x/distribution/keeper/msg_server.go index 4e7bbb8e24d7..7b54562e7e99 100644 --- a/x/distribution/keeper/msg_server.go +++ b/x/distribution/keeper/msg_server.go @@ -25,7 +25,7 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer { return &msgServer{Keeper: keeper} } -func (k msgServer) SetWithdrawAddress(goCtx context.Context, msg *types.MsgSetWithdrawAddress) (*types.MsgSetWithdrawAddressResponse, error) { +func (k msgServer) SetWithdrawAddress(ctx context.Context, msg *types.MsgSetWithdrawAddress) (*types.MsgSetWithdrawAddressResponse, error) { delegatorAddress, err := k.authKeeper.StringToBytes(msg.DelegatorAddress) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid delegator address: %s", err) @@ -36,7 +36,6 @@ func (k msgServer) SetWithdrawAddress(goCtx context.Context, msg *types.MsgSetWi return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid withdraw address: %s", err) } - ctx := sdk.UnwrapSDKContext(goCtx) err = k.SetWithdrawAddr(ctx, delegatorAddress, withdrawAddress) if err != nil { return nil, err @@ -45,7 +44,7 @@ func (k msgServer) SetWithdrawAddress(goCtx context.Context, msg *types.MsgSetWi return &types.MsgSetWithdrawAddressResponse{}, nil } -func (k msgServer) WithdrawDelegatorReward(goCtx context.Context, msg *types.MsgWithdrawDelegatorReward) (*types.MsgWithdrawDelegatorRewardResponse, error) { +func (k msgServer) WithdrawDelegatorReward(ctx context.Context, msg *types.MsgWithdrawDelegatorReward) (*types.MsgWithdrawDelegatorRewardResponse, error) { valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid validator address: %s", err) @@ -56,7 +55,6 @@ func (k msgServer) WithdrawDelegatorReward(goCtx context.Context, msg *types.Msg return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid delegator address: %s", err) } - ctx := sdk.UnwrapSDKContext(goCtx) amount, err := k.WithdrawDelegationRewards(ctx, delegatorAddress, valAddr) if err != nil { return nil, err @@ -77,13 +75,12 @@ func (k msgServer) WithdrawDelegatorReward(goCtx context.Context, msg *types.Msg return &types.MsgWithdrawDelegatorRewardResponse{Amount: amount}, nil } -func (k msgServer) WithdrawValidatorCommission(goCtx context.Context, msg *types.MsgWithdrawValidatorCommission) (*types.MsgWithdrawValidatorCommissionResponse, error) { +func (k msgServer) WithdrawValidatorCommission(ctx context.Context, msg *types.MsgWithdrawValidatorCommission) (*types.MsgWithdrawValidatorCommissionResponse, error) { valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid validator address: %s", err) } - ctx := sdk.UnwrapSDKContext(goCtx) amount, err := k.Keeper.WithdrawValidatorCommission(ctx, valAddr) if err != nil { return nil, err @@ -104,7 +101,7 @@ func (k msgServer) WithdrawValidatorCommission(goCtx context.Context, msg *types return &types.MsgWithdrawValidatorCommissionResponse{Amount: amount}, nil } -func (k msgServer) FundCommunityPool(goCtx context.Context, msg *types.MsgFundCommunityPool) (*types.MsgFundCommunityPoolResponse, error) { +func (k msgServer) FundCommunityPool(ctx context.Context, msg *types.MsgFundCommunityPool) (*types.MsgFundCommunityPoolResponse, error) { depositor, err := k.authKeeper.StringToBytes(msg.Depositor) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid depositor address: %s", err) @@ -114,7 +111,6 @@ func (k msgServer) FundCommunityPool(goCtx context.Context, msg *types.MsgFundCo return nil, err } - ctx := sdk.UnwrapSDKContext(goCtx) if err := k.Keeper.FundCommunityPool(ctx, msg.Amount, depositor); err != nil { return nil, err } @@ -122,7 +118,7 @@ func (k msgServer) FundCommunityPool(goCtx context.Context, msg *types.MsgFundCo return &types.MsgFundCommunityPoolResponse{}, 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 err := k.validateAuthority(msg.Authority); err != nil { return nil, err } @@ -136,7 +132,6 @@ func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParam return nil, err } - ctx := sdk.UnwrapSDKContext(goCtx) if err := k.SetParams(ctx, msg.Params); err != nil { return nil, err } @@ -144,7 +139,7 @@ func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParam return &types.MsgUpdateParamsResponse{}, nil } -func (k msgServer) CommunityPoolSpend(goCtx context.Context, msg *types.MsgCommunityPoolSpend) (*types.MsgCommunityPoolSpendResponse, error) { +func (k msgServer) CommunityPoolSpend(ctx context.Context, msg *types.MsgCommunityPoolSpend) (*types.MsgCommunityPoolSpendResponse, error) { if err := k.validateAuthority(msg.Authority); err != nil { return nil, err } @@ -162,7 +157,6 @@ func (k msgServer) CommunityPoolSpend(goCtx context.Context, msg *types.MsgCommu return nil, errors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive external funds", msg.Recipient) } - ctx := sdk.UnwrapSDKContext(goCtx) if err := k.DistributeFromFeePool(ctx, msg.Amount, recipient); err != nil { return nil, err } @@ -173,13 +167,12 @@ func (k msgServer) CommunityPoolSpend(goCtx context.Context, msg *types.MsgCommu return &types.MsgCommunityPoolSpendResponse{}, nil } -func (k msgServer) DepositValidatorRewardsPool(goCtx context.Context, msg *types.MsgDepositValidatorRewardsPool) (*types.MsgDepositValidatorRewardsPoolResponse, error) { +func (k msgServer) DepositValidatorRewardsPool(ctx context.Context, msg *types.MsgDepositValidatorRewardsPool) (*types.MsgDepositValidatorRewardsPoolResponse, error) { depositor, err := k.authKeeper.StringToBytes(msg.Depositor) if err != nil { return nil, err } - ctx := sdk.UnwrapSDKContext(goCtx) // deposit coins from depositor's account to the distribution module if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, depositor, types.ModuleName, msg.Amount); err != nil { return nil, err @@ -190,7 +183,8 @@ func (k msgServer) DepositValidatorRewardsPool(goCtx context.Context, msg *types return nil, err } - validator := k.stakingKeeper.Validator(ctx, valAddr) + sdkCtx := sdk.UnwrapSDKContext(ctx) + validator := k.stakingKeeper.Validator(sdkCtx, valAddr) if validator == nil { return nil, errors.Wrapf(types.ErrNoValidatorExists, valAddr.String()) } diff --git a/x/distribution/keeper/params.go b/x/distribution/keeper/params.go index 2ab11eb273a7..f81df2b86655 100644 --- a/x/distribution/keeper/params.go +++ b/x/distribution/keeper/params.go @@ -1,44 +1,53 @@ package keeper import ( + "context" + "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/distribution/types" ) // GetParams returns the total set of distribution parameters. -func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(types.ParamsKey) - if bz == nil { - return params +func (k Keeper) GetParams(ctx context.Context) (params types.Params, err error) { + store := k.storeService.OpenKVStore(ctx) + bz, err := store.Get(types.ParamsKey) + if bz == nil || err != nil { + return params, err } - k.cdc.MustUnmarshal(bz, ¶ms) - return params + err = k.cdc.Unmarshal(bz, ¶ms) + return params, err } // SetParams sets the distribution 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) } // GetCommunityTax returns the current distribution community tax. -func (k Keeper) GetCommunityTax(ctx sdk.Context) math.LegacyDec { - return k.GetParams(ctx).CommunityTax +func (k Keeper) GetCommunityTax(ctx context.Context) (math.LegacyDec, error) { + params, err := k.GetParams(ctx) + if err != nil { + return math.LegacyDec{}, err + } + + return params.CommunityTax, nil } // GetWithdrawAddrEnabled returns the current distribution withdraw address // enabled parameter. -func (k Keeper) GetWithdrawAddrEnabled(ctx sdk.Context) (enabled bool) { - return k.GetParams(ctx).WithdrawAddrEnabled +func (k Keeper) GetWithdrawAddrEnabled(ctx context.Context) (enabled bool, err error) { + params, err := k.GetParams(ctx) + if err != nil { + return false, err + } + + return params.WithdrawAddrEnabled, nil } diff --git a/x/distribution/keeper/store.go b/x/distribution/keeper/store.go index ae5ef44507bc..50afcf6e7520 100644 --- a/x/distribution/keeper/store.go +++ b/x/distribution/keeper/store.go @@ -1,40 +1,44 @@ package keeper import ( + "context" + "errors" + gogotypes "github.com/cosmos/gogoproto/types" storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/distribution/types" ) // get the delegator withdraw address, defaulting to the delegator address -func (k Keeper) GetDelegatorWithdrawAddr(ctx sdk.Context, delAddr sdk.AccAddress) sdk.AccAddress { - store := ctx.KVStore(k.storeKey) - b := store.Get(types.GetDelegatorWithdrawAddrKey(delAddr)) +func (k Keeper) GetDelegatorWithdrawAddr(ctx context.Context, delAddr sdk.AccAddress) (sdk.AccAddress, error) { + store := k.storeService.OpenKVStore(ctx) + b, err := store.Get(types.GetDelegatorWithdrawAddrKey(delAddr)) if b == nil { - return delAddr + return delAddr, err } - return sdk.AccAddress(b) + return sdk.AccAddress(b), nil } // set the delegator withdraw address -func (k Keeper) SetDelegatorWithdrawAddr(ctx sdk.Context, delAddr, withdrawAddr sdk.AccAddress) { - store := ctx.KVStore(k.storeKey) - store.Set(types.GetDelegatorWithdrawAddrKey(delAddr), withdrawAddr.Bytes()) +func (k Keeper) SetDelegatorWithdrawAddr(ctx context.Context, delAddr, withdrawAddr sdk.AccAddress) error { + store := k.storeService.OpenKVStore(ctx) + return store.Set(types.GetDelegatorWithdrawAddrKey(delAddr), withdrawAddr.Bytes()) } // delete a delegator withdraw addr -func (k Keeper) DeleteDelegatorWithdrawAddr(ctx sdk.Context, delAddr, withdrawAddr sdk.AccAddress) { - store := ctx.KVStore(k.storeKey) - store.Delete(types.GetDelegatorWithdrawAddrKey(delAddr)) +func (k Keeper) DeleteDelegatorWithdrawAddr(ctx context.Context, delAddr, withdrawAddr sdk.AccAddress) error { + store := k.storeService.OpenKVStore(ctx) + return store.Delete(types.GetDelegatorWithdrawAddrKey(delAddr)) } // iterate over delegator withdraw addrs -func (k Keeper) IterateDelegatorWithdrawAddrs(ctx sdk.Context, handler func(del, addr sdk.AccAddress) (stop bool)) { - store := ctx.KVStore(k.storeKey) - iter := storetypes.KVStorePrefixIterator(store, types.DelegatorWithdrawAddrPrefix) +func (k Keeper) IterateDelegatorWithdrawAddrs(ctx context.Context, handler func(del, addr sdk.AccAddress) (stop bool)) { + store := k.storeService.OpenKVStore(ctx) + iter := storetypes.KVStorePrefixIterator(runtime.KVStoreAdapter(store), types.DelegatorWithdrawAddrPrefix) defer iter.Close() for ; iter.Valid(); iter.Next() { addr := sdk.AccAddress(iter.Value()) @@ -46,74 +50,98 @@ func (k Keeper) IterateDelegatorWithdrawAddrs(ctx sdk.Context, handler func(del, } // get the global fee pool distribution info -func (k Keeper) GetFeePool(ctx sdk.Context) (feePool types.FeePool) { - store := ctx.KVStore(k.storeKey) - b := store.Get(types.FeePoolKey) +func (k Keeper) GetFeePool(ctx context.Context) (feePool types.FeePool, err error) { + store := k.storeService.OpenKVStore(ctx) + b, err := store.Get(types.FeePoolKey) + if err != nil { + return + } + if b == nil { panic("Stored fee pool should not have been nil") } - k.cdc.MustUnmarshal(b, &feePool) - return + err = k.cdc.Unmarshal(b, &feePool) + return feePool, err } // set the global fee pool distribution info -func (k Keeper) SetFeePool(ctx sdk.Context, feePool types.FeePool) { - store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshal(&feePool) - store.Set(types.FeePoolKey, b) +func (k Keeper) SetFeePool(ctx context.Context, feePool types.FeePool) error { + store := k.storeService.OpenKVStore(ctx) + b, err := k.cdc.Marshal(&feePool) + if err != nil { + return err + } + + return store.Set(types.FeePoolKey, b) } // GetPreviousProposerConsAddr returns the proposer consensus address for the // current block. -func (k Keeper) GetPreviousProposerConsAddr(ctx sdk.Context) sdk.ConsAddress { - store := ctx.KVStore(k.storeKey) - bz := store.Get(types.ProposerKey) +func (k Keeper) GetPreviousProposerConsAddr(ctx context.Context) (sdk.ConsAddress, error) { + store := k.storeService.OpenKVStore(ctx) + bz, err := store.Get(types.ProposerKey) + if err != nil { + return nil, err + } + if bz == nil { - panic("previous proposer not set") + return nil, errors.New("previous proposer not set") } addrValue := gogotypes.BytesValue{} - k.cdc.MustUnmarshal(bz, &addrValue) - return addrValue.GetValue() + err = k.cdc.Unmarshal(bz, &addrValue) + if err != nil { + return nil, err + } + + return addrValue.GetValue(), nil } // set the proposer public key for this block -func (k Keeper) SetPreviousProposerConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) SetPreviousProposerConsAddr(ctx context.Context, consAddr sdk.ConsAddress) { + store := k.storeService.OpenKVStore(ctx) bz := k.cdc.MustMarshal(&gogotypes.BytesValue{Value: consAddr}) store.Set(types.ProposerKey, bz) } // get the starting info associated with a delegator -func (k Keeper) GetDelegatorStartingInfo(ctx sdk.Context, val sdk.ValAddress, del sdk.AccAddress) (period types.DelegatorStartingInfo) { - store := ctx.KVStore(k.storeKey) - b := store.Get(types.GetDelegatorStartingInfoKey(val, del)) - k.cdc.MustUnmarshal(b, &period) - return +func (k Keeper) GetDelegatorStartingInfo(ctx context.Context, val sdk.ValAddress, del sdk.AccAddress) (period types.DelegatorStartingInfo, err error) { + store := k.storeService.OpenKVStore(ctx) + b, err := store.Get(types.GetDelegatorStartingInfoKey(val, del)) + if err != nil { + return + } + + err = k.cdc.Unmarshal(b, &period) + return period, err } // set the starting info associated with a delegator -func (k Keeper) SetDelegatorStartingInfo(ctx sdk.Context, val sdk.ValAddress, del sdk.AccAddress, period types.DelegatorStartingInfo) { - store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshal(&period) - store.Set(types.GetDelegatorStartingInfoKey(val, del), b) +func (k Keeper) SetDelegatorStartingInfo(ctx context.Context, val sdk.ValAddress, del sdk.AccAddress, period types.DelegatorStartingInfo) error { + store := k.storeService.OpenKVStore(ctx) + b, err := k.cdc.Marshal(&period) + if err != nil { + return err + } + + return store.Set(types.GetDelegatorStartingInfoKey(val, del), b) } // check existence of the starting info associated with a delegator -func (k Keeper) HasDelegatorStartingInfo(ctx sdk.Context, val sdk.ValAddress, del sdk.AccAddress) bool { - store := ctx.KVStore(k.storeKey) +func (k Keeper) HasDelegatorStartingInfo(ctx context.Context, val sdk.ValAddress, del sdk.AccAddress) (bool, error) { + store := k.storeService.OpenKVStore(ctx) return store.Has(types.GetDelegatorStartingInfoKey(val, del)) } // delete the starting info associated with a delegator -func (k Keeper) DeleteDelegatorStartingInfo(ctx sdk.Context, val sdk.ValAddress, del sdk.AccAddress) { - store := ctx.KVStore(k.storeKey) - store.Delete(types.GetDelegatorStartingInfoKey(val, del)) +func (k Keeper) DeleteDelegatorStartingInfo(ctx context.Context, val sdk.ValAddress, del sdk.AccAddress) error { + store := k.storeService.OpenKVStore(ctx) + return store.Delete(types.GetDelegatorStartingInfoKey(val, del)) } // iterate over delegator starting infos -func (k Keeper) IterateDelegatorStartingInfos(ctx sdk.Context, handler func(val sdk.ValAddress, del sdk.AccAddress, info types.DelegatorStartingInfo) (stop bool)) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) IterateDelegatorStartingInfos(ctx context.Context, handler func(val sdk.ValAddress, del sdk.AccAddress, info types.DelegatorStartingInfo) (stop bool)) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.DelegatorStartingInfoPrefix) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -127,23 +155,31 @@ func (k Keeper) IterateDelegatorStartingInfos(ctx sdk.Context, handler func(val } // get historical rewards for a particular period -func (k Keeper) GetValidatorHistoricalRewards(ctx sdk.Context, val sdk.ValAddress, period uint64) (rewards types.ValidatorHistoricalRewards) { - store := ctx.KVStore(k.storeKey) - b := store.Get(types.GetValidatorHistoricalRewardsKey(val, period)) - k.cdc.MustUnmarshal(b, &rewards) +func (k Keeper) GetValidatorHistoricalRewards(ctx context.Context, val sdk.ValAddress, period uint64) (rewards types.ValidatorHistoricalRewards, err error) { + store := k.storeService.OpenKVStore(ctx) + b, err := store.Get(types.GetValidatorHistoricalRewardsKey(val, period)) + if err != nil { + return + } + + err = k.cdc.Unmarshal(b, &rewards) return } // set historical rewards for a particular period -func (k Keeper) SetValidatorHistoricalRewards(ctx sdk.Context, val sdk.ValAddress, period uint64, rewards types.ValidatorHistoricalRewards) { - store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshal(&rewards) - store.Set(types.GetValidatorHistoricalRewardsKey(val, period), b) +func (k Keeper) SetValidatorHistoricalRewards(ctx context.Context, val sdk.ValAddress, period uint64, rewards types.ValidatorHistoricalRewards) error { + store := k.storeService.OpenKVStore(ctx) + b, err := k.cdc.Marshal(&rewards) + if err != nil { + return err + } + + return store.Set(types.GetValidatorHistoricalRewardsKey(val, period), b) } // iterate over historical rewards -func (k Keeper) IterateValidatorHistoricalRewards(ctx sdk.Context, handler func(val sdk.ValAddress, period uint64, rewards types.ValidatorHistoricalRewards) (stop bool)) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) IterateValidatorHistoricalRewards(ctx context.Context, handler func(val sdk.ValAddress, period uint64, rewards types.ValidatorHistoricalRewards) (stop bool)) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.ValidatorHistoricalRewardsPrefix) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -157,14 +193,14 @@ func (k Keeper) IterateValidatorHistoricalRewards(ctx sdk.Context, handler func( } // delete a historical reward -func (k Keeper) DeleteValidatorHistoricalReward(ctx sdk.Context, val sdk.ValAddress, period uint64) { - store := ctx.KVStore(k.storeKey) - store.Delete(types.GetValidatorHistoricalRewardsKey(val, period)) +func (k Keeper) DeleteValidatorHistoricalReward(ctx context.Context, val sdk.ValAddress, period uint64) error { + store := k.storeService.OpenKVStore(ctx) + return store.Delete(types.GetValidatorHistoricalRewardsKey(val, period)) } // delete historical rewards for a validator -func (k Keeper) DeleteValidatorHistoricalRewards(ctx sdk.Context, val sdk.ValAddress) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) DeleteValidatorHistoricalRewards(ctx context.Context, val sdk.ValAddress) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.GetValidatorHistoricalRewardsPrefix(val)) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -173,8 +209,8 @@ func (k Keeper) DeleteValidatorHistoricalRewards(ctx sdk.Context, val sdk.ValAdd } // delete all historical rewards -func (k Keeper) DeleteAllValidatorHistoricalRewards(ctx sdk.Context) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) DeleteAllValidatorHistoricalRewards(ctx context.Context) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.ValidatorHistoricalRewardsPrefix) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -183,8 +219,8 @@ func (k Keeper) DeleteAllValidatorHistoricalRewards(ctx sdk.Context) { } // historical reference count (used for testcases) -func (k Keeper) GetValidatorHistoricalReferenceCount(ctx sdk.Context) (count uint64) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) GetValidatorHistoricalReferenceCount(ctx context.Context) (count uint64) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.ValidatorHistoricalRewardsPrefix) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -196,29 +232,37 @@ func (k Keeper) GetValidatorHistoricalReferenceCount(ctx sdk.Context) (count uin } // get current rewards for a validator -func (k Keeper) GetValidatorCurrentRewards(ctx sdk.Context, val sdk.ValAddress) (rewards types.ValidatorCurrentRewards) { - store := ctx.KVStore(k.storeKey) - b := store.Get(types.GetValidatorCurrentRewardsKey(val)) - k.cdc.MustUnmarshal(b, &rewards) +func (k Keeper) GetValidatorCurrentRewards(ctx context.Context, val sdk.ValAddress) (rewards types.ValidatorCurrentRewards, err error) { + store := k.storeService.OpenKVStore(ctx) + b, err := store.Get(types.GetValidatorCurrentRewardsKey(val)) + if err != nil { + return + } + + err = k.cdc.Unmarshal(b, &rewards) return } // set current rewards for a validator -func (k Keeper) SetValidatorCurrentRewards(ctx sdk.Context, val sdk.ValAddress, rewards types.ValidatorCurrentRewards) { - store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshal(&rewards) - store.Set(types.GetValidatorCurrentRewardsKey(val), b) +func (k Keeper) SetValidatorCurrentRewards(ctx context.Context, val sdk.ValAddress, rewards types.ValidatorCurrentRewards) error { + store := k.storeService.OpenKVStore(ctx) + b, err := k.cdc.Marshal(&rewards) + if err != nil { + return err + } + + return store.Set(types.GetValidatorCurrentRewardsKey(val), b) } // delete current rewards for a validator -func (k Keeper) DeleteValidatorCurrentRewards(ctx sdk.Context, val sdk.ValAddress) { - store := ctx.KVStore(k.storeKey) - store.Delete(types.GetValidatorCurrentRewardsKey(val)) +func (k Keeper) DeleteValidatorCurrentRewards(ctx context.Context, val sdk.ValAddress) error { + store := k.storeService.OpenKVStore(ctx) + return store.Delete(types.GetValidatorCurrentRewardsKey(val)) } // iterate over current rewards -func (k Keeper) IterateValidatorCurrentRewards(ctx sdk.Context, handler func(val sdk.ValAddress, rewards types.ValidatorCurrentRewards) (stop bool)) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) IterateValidatorCurrentRewards(ctx context.Context, handler func(val sdk.ValAddress, rewards types.ValidatorCurrentRewards) (stop bool)) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.ValidatorCurrentRewardsPrefix) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -232,39 +276,54 @@ func (k Keeper) IterateValidatorCurrentRewards(ctx sdk.Context, handler func(val } // get accumulated commission for a validator -func (k Keeper) GetValidatorAccumulatedCommission(ctx sdk.Context, val sdk.ValAddress) (commission types.ValidatorAccumulatedCommission) { - store := ctx.KVStore(k.storeKey) - b := store.Get(types.GetValidatorAccumulatedCommissionKey(val)) +func (k Keeper) GetValidatorAccumulatedCommission(ctx context.Context, val sdk.ValAddress) (commission types.ValidatorAccumulatedCommission, err error) { + store := k.storeService.OpenKVStore(ctx) + b, err := store.Get(types.GetValidatorAccumulatedCommissionKey(val)) + if err != nil { + return types.ValidatorAccumulatedCommission{}, err + } + if b == nil { - return types.ValidatorAccumulatedCommission{} + return types.ValidatorAccumulatedCommission{}, nil + } + + err = k.cdc.Unmarshal(b, &commission) + if err != nil { + return types.ValidatorAccumulatedCommission{}, err } - k.cdc.MustUnmarshal(b, &commission) return } // set accumulated commission for a validator -func (k Keeper) SetValidatorAccumulatedCommission(ctx sdk.Context, val sdk.ValAddress, commission types.ValidatorAccumulatedCommission) { - var bz []byte +func (k Keeper) SetValidatorAccumulatedCommission(ctx context.Context, val sdk.ValAddress, commission types.ValidatorAccumulatedCommission) error { + var ( + bz []byte + err error + ) - store := ctx.KVStore(k.storeKey) + store := k.storeService.OpenKVStore(ctx) if commission.Commission.IsZero() { - bz = k.cdc.MustMarshal(&types.ValidatorAccumulatedCommission{}) + bz, err = k.cdc.Marshal(&types.ValidatorAccumulatedCommission{}) } else { - bz = k.cdc.MustMarshal(&commission) + bz, err = k.cdc.Marshal(&commission) + } + + if err != nil { + return err } - store.Set(types.GetValidatorAccumulatedCommissionKey(val), bz) + return store.Set(types.GetValidatorAccumulatedCommissionKey(val), bz) } // delete accumulated commission for a validator -func (k Keeper) DeleteValidatorAccumulatedCommission(ctx sdk.Context, val sdk.ValAddress) { - store := ctx.KVStore(k.storeKey) - store.Delete(types.GetValidatorAccumulatedCommissionKey(val)) +func (k Keeper) DeleteValidatorAccumulatedCommission(ctx context.Context, val sdk.ValAddress) error { + store := k.storeService.OpenKVStore(ctx) + return store.Delete(types.GetValidatorAccumulatedCommissionKey(val)) } // iterate over accumulated commissions -func (k Keeper) IterateValidatorAccumulatedCommissions(ctx sdk.Context, handler func(val sdk.ValAddress, commission types.ValidatorAccumulatedCommission) (stop bool)) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) IterateValidatorAccumulatedCommissions(ctx context.Context, handler func(val sdk.ValAddress, commission types.ValidatorAccumulatedCommission) (stop bool)) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.ValidatorAccumulatedCommissionPrefix) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -278,29 +337,35 @@ func (k Keeper) IterateValidatorAccumulatedCommissions(ctx sdk.Context, handler } // get validator outstanding rewards -func (k Keeper) GetValidatorOutstandingRewards(ctx sdk.Context, val sdk.ValAddress) (rewards types.ValidatorOutstandingRewards) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(types.GetValidatorOutstandingRewardsKey(val)) - k.cdc.MustUnmarshal(bz, &rewards) +func (k Keeper) GetValidatorOutstandingRewards(ctx context.Context, val sdk.ValAddress) (rewards types.ValidatorOutstandingRewards, err error) { + store := k.storeService.OpenKVStore(ctx) + bz, err := store.Get(types.GetValidatorOutstandingRewardsKey(val)) + if err != nil { + return + } + err = k.cdc.Unmarshal(bz, &rewards) return } // set validator outstanding rewards -func (k Keeper) SetValidatorOutstandingRewards(ctx sdk.Context, val sdk.ValAddress, rewards types.ValidatorOutstandingRewards) { - store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshal(&rewards) - store.Set(types.GetValidatorOutstandingRewardsKey(val), b) +func (k Keeper) SetValidatorOutstandingRewards(ctx context.Context, val sdk.ValAddress, rewards types.ValidatorOutstandingRewards) error { + store := k.storeService.OpenKVStore(ctx) + b, err := k.cdc.Marshal(&rewards) + if err != nil { + return err + } + return store.Set(types.GetValidatorOutstandingRewardsKey(val), b) } // delete validator outstanding rewards -func (k Keeper) DeleteValidatorOutstandingRewards(ctx sdk.Context, val sdk.ValAddress) { - store := ctx.KVStore(k.storeKey) - store.Delete(types.GetValidatorOutstandingRewardsKey(val)) +func (k Keeper) DeleteValidatorOutstandingRewards(ctx context.Context, val sdk.ValAddress) error { + store := k.storeService.OpenKVStore(ctx) + return store.Delete(types.GetValidatorOutstandingRewardsKey(val)) } // iterate validator outstanding rewards -func (k Keeper) IterateValidatorOutstandingRewards(ctx sdk.Context, handler func(val sdk.ValAddress, rewards types.ValidatorOutstandingRewards) (stop bool)) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) IterateValidatorOutstandingRewards(ctx context.Context, handler func(val sdk.ValAddress, rewards types.ValidatorOutstandingRewards) (stop bool)) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.ValidatorOutstandingRewardsPrefix) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -314,28 +379,41 @@ func (k Keeper) IterateValidatorOutstandingRewards(ctx sdk.Context, handler func } // get slash event for height -func (k Keeper) GetValidatorSlashEvent(ctx sdk.Context, val sdk.ValAddress, height, period uint64) (event types.ValidatorSlashEvent, found bool) { - store := ctx.KVStore(k.storeKey) - b := store.Get(types.GetValidatorSlashEventKey(val, height, period)) +func (k Keeper) GetValidatorSlashEvent(ctx context.Context, val sdk.ValAddress, height, period uint64) (event types.ValidatorSlashEvent, found bool, err error) { + store := k.storeService.OpenKVStore(ctx) + b, err := store.Get(types.GetValidatorSlashEventKey(val, height, period)) + if err != nil { + return types.ValidatorSlashEvent{}, false, err + } + if b == nil { - return types.ValidatorSlashEvent{}, false + return types.ValidatorSlashEvent{}, false, nil } - k.cdc.MustUnmarshal(b, &event) - return event, true + + err = k.cdc.Unmarshal(b, &event) + if err != nil { + return types.ValidatorSlashEvent{}, false, err + } + + return event, true, nil } // set slash event for height -func (k Keeper) SetValidatorSlashEvent(ctx sdk.Context, val sdk.ValAddress, height, period uint64, event types.ValidatorSlashEvent) { - store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshal(&event) - store.Set(types.GetValidatorSlashEventKey(val, height, period), b) +func (k Keeper) SetValidatorSlashEvent(ctx context.Context, val sdk.ValAddress, height, period uint64, event types.ValidatorSlashEvent) error { + store := k.storeService.OpenKVStore(ctx) + b, err := k.cdc.Marshal(&event) + if err != nil { + return err + } + + return store.Set(types.GetValidatorSlashEventKey(val, height, period), b) } // iterate over slash events between heights, inclusive -func (k Keeper) IterateValidatorSlashEventsBetween(ctx sdk.Context, val sdk.ValAddress, startingHeight, endingHeight uint64, +func (k Keeper) IterateValidatorSlashEventsBetween(ctx context.Context, val sdk.ValAddress, startingHeight, endingHeight uint64, handler func(height uint64, event types.ValidatorSlashEvent) (stop bool), ) { - store := ctx.KVStore(k.storeKey) + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := store.Iterator( types.GetValidatorSlashEventKeyPrefix(val, startingHeight), types.GetValidatorSlashEventKeyPrefix(val, endingHeight+1), @@ -352,8 +430,8 @@ func (k Keeper) IterateValidatorSlashEventsBetween(ctx sdk.Context, val sdk.ValA } // iterate over all slash events -func (k Keeper) IterateValidatorSlashEvents(ctx sdk.Context, handler func(val sdk.ValAddress, height uint64, event types.ValidatorSlashEvent) (stop bool)) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) IterateValidatorSlashEvents(ctx context.Context, handler func(val sdk.ValAddress, height uint64, event types.ValidatorSlashEvent) (stop bool)) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.ValidatorSlashEventPrefix) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -367,8 +445,8 @@ func (k Keeper) IterateValidatorSlashEvents(ctx sdk.Context, handler func(val sd } // delete slash events for a particular validator -func (k Keeper) DeleteValidatorSlashEvents(ctx sdk.Context, val sdk.ValAddress) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) DeleteValidatorSlashEvents(ctx context.Context, val sdk.ValAddress) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.GetValidatorSlashEventPrefix(val)) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -377,8 +455,8 @@ func (k Keeper) DeleteValidatorSlashEvents(ctx sdk.Context, val sdk.ValAddress) } // delete all slash events -func (k Keeper) DeleteAllValidatorSlashEvents(ctx sdk.Context) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) DeleteAllValidatorSlashEvents(ctx context.Context) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) iter := storetypes.KVStorePrefixIterator(store, types.ValidatorSlashEventPrefix) defer iter.Close() for ; iter.Valid(); iter.Next() { diff --git a/x/distribution/keeper/validator.go b/x/distribution/keeper/validator.go index 984ec1a54f48..04205a236e8b 100644 --- a/x/distribution/keeper/validator.go +++ b/x/distribution/keeper/validator.go @@ -1,9 +1,11 @@ package keeper import ( + "context" "fmt" "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/distribution/types" @@ -11,24 +13,37 @@ import ( ) // initialize rewards for a new validator -func (k Keeper) initializeValidator(ctx sdk.Context, val stakingtypes.ValidatorI) { +func (k Keeper) initializeValidator(ctx context.Context, val stakingtypes.ValidatorI) error { // set initial historical rewards (period 0) with reference count of 1 - k.SetValidatorHistoricalRewards(ctx, val.GetOperator(), 0, types.NewValidatorHistoricalRewards(sdk.DecCoins{}, 1)) + err := k.SetValidatorHistoricalRewards(ctx, val.GetOperator(), 0, types.NewValidatorHistoricalRewards(sdk.DecCoins{}, 1)) + if err != nil { + return err + } // set current rewards (starting at period 1) - k.SetValidatorCurrentRewards(ctx, val.GetOperator(), types.NewValidatorCurrentRewards(sdk.DecCoins{}, 1)) + err = k.SetValidatorCurrentRewards(ctx, val.GetOperator(), types.NewValidatorCurrentRewards(sdk.DecCoins{}, 1)) + if err != nil { + return err + } // set accumulated commission - k.SetValidatorAccumulatedCommission(ctx, val.GetOperator(), types.InitialValidatorAccumulatedCommission()) + err = k.SetValidatorAccumulatedCommission(ctx, val.GetOperator(), types.InitialValidatorAccumulatedCommission()) + if err != nil { + return err + } // set outstanding rewards - k.SetValidatorOutstandingRewards(ctx, val.GetOperator(), types.ValidatorOutstandingRewards{Rewards: sdk.DecCoins{}}) + err = k.SetValidatorOutstandingRewards(ctx, val.GetOperator(), types.ValidatorOutstandingRewards{Rewards: sdk.DecCoins{}}) + return err } // increment validator period, returning the period just ended -func (k Keeper) IncrementValidatorPeriod(ctx sdk.Context, val stakingtypes.ValidatorI) uint64 { +func (k Keeper) IncrementValidatorPeriod(ctx context.Context, val stakingtypes.ValidatorI) (uint64, error) { // fetch current rewards - rewards := k.GetValidatorCurrentRewards(ctx, val.GetOperator()) + rewards, err := k.GetValidatorCurrentRewards(ctx, val.GetOperator()) + if err != nil { + return 0, err + } // calculate current ratio var current sdk.DecCoins @@ -36,12 +51,27 @@ func (k Keeper) IncrementValidatorPeriod(ctx sdk.Context, val stakingtypes.Valid // can't calculate ratio for zero-token validators // ergo we instead add to the community pool - feePool := k.GetFeePool(ctx) - outstanding := k.GetValidatorOutstandingRewards(ctx, val.GetOperator()) + feePool, err := k.GetFeePool(ctx) + if err != nil { + return 0, err + } + + outstanding, err := k.GetValidatorOutstandingRewards(ctx, val.GetOperator()) + if err != nil { + return 0, err + } + feePool.CommunityPool = feePool.CommunityPool.Add(rewards.Rewards...) outstanding.Rewards = outstanding.GetRewards().Sub(rewards.Rewards) - k.SetFeePool(ctx, feePool) - k.SetValidatorOutstandingRewards(ctx, val.GetOperator(), outstanding) + err = k.SetFeePool(ctx, feePool) + if err != nil { + return 0, err + } + + err = k.SetValidatorOutstandingRewards(ctx, val.GetOperator(), outstanding) + if err != nil { + return 0, err + } current = sdk.DecCoins{} } else { @@ -50,59 +80,84 @@ func (k Keeper) IncrementValidatorPeriod(ctx sdk.Context, val stakingtypes.Valid } // fetch historical rewards for last period - historical := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), rewards.Period-1).CumulativeRewardRatio + historical, err := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), rewards.Period-1) + if err != nil { + return 0, err + } + + cumRewardRatio := historical.CumulativeRewardRatio // decrement reference count - k.decrementReferenceCount(ctx, val.GetOperator(), rewards.Period-1) + err = k.decrementReferenceCount(ctx, val.GetOperator(), rewards.Period-1) + if err != nil { + return 0, err + } // set new historical rewards with reference count of 1 - k.SetValidatorHistoricalRewards(ctx, val.GetOperator(), rewards.Period, types.NewValidatorHistoricalRewards(historical.Add(current...), 1)) + err = k.SetValidatorHistoricalRewards(ctx, val.GetOperator(), rewards.Period, types.NewValidatorHistoricalRewards(cumRewardRatio.Add(current...), 1)) + if err != nil { + return 0, err + } // set current rewards, incrementing period by 1 - k.SetValidatorCurrentRewards(ctx, val.GetOperator(), types.NewValidatorCurrentRewards(sdk.DecCoins{}, rewards.Period+1)) + err = k.SetValidatorCurrentRewards(ctx, val.GetOperator(), types.NewValidatorCurrentRewards(sdk.DecCoins{}, rewards.Period+1)) + if err != nil { + return 0, err + } - return rewards.Period + return rewards.Period, nil } // increment the reference count for a historical rewards value -func (k Keeper) incrementReferenceCount(ctx sdk.Context, valAddr sdk.ValAddress, period uint64) { - historical := k.GetValidatorHistoricalRewards(ctx, valAddr, period) +func (k Keeper) incrementReferenceCount(ctx context.Context, valAddr sdk.ValAddress, period uint64) error { + historical, err := k.GetValidatorHistoricalRewards(ctx, valAddr, period) + if err != nil { + return err + } if historical.ReferenceCount > 2 { panic("reference count should never exceed 2") } historical.ReferenceCount++ - k.SetValidatorHistoricalRewards(ctx, valAddr, period, historical) + return k.SetValidatorHistoricalRewards(ctx, valAddr, period, historical) } // decrement the reference count for a historical rewards value, and delete if zero references remain -func (k Keeper) decrementReferenceCount(ctx sdk.Context, valAddr sdk.ValAddress, period uint64) { - historical := k.GetValidatorHistoricalRewards(ctx, valAddr, period) +func (k Keeper) decrementReferenceCount(ctx context.Context, valAddr sdk.ValAddress, period uint64) error { + historical, err := k.GetValidatorHistoricalRewards(ctx, valAddr, period) + if err != nil { + return err + } + if historical.ReferenceCount == 0 { panic("cannot set negative reference count") } historical.ReferenceCount-- if historical.ReferenceCount == 0 { - k.DeleteValidatorHistoricalReward(ctx, valAddr, period) - } else { - k.SetValidatorHistoricalRewards(ctx, valAddr, period, historical) + return k.DeleteValidatorHistoricalReward(ctx, valAddr, period) } + + return k.SetValidatorHistoricalRewards(ctx, valAddr, period, historical) } -func (k Keeper) updateValidatorSlashFraction(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) { +func (k Keeper) updateValidatorSlashFraction(ctx context.Context, valAddr sdk.ValAddress, fraction sdk.Dec) error { if fraction.GT(math.LegacyOneDec()) || fraction.IsNegative() { panic(fmt.Sprintf("fraction must be >=0 and <=1, current fraction: %v", fraction)) } - val := k.stakingKeeper.Validator(ctx, valAddr) + sdkCtx := sdk.UnwrapSDKContext(ctx) + val := k.stakingKeeper.Validator(sdkCtx, valAddr) // increment current period - newPeriod := k.IncrementValidatorPeriod(ctx, val) + newPeriod, err := k.IncrementValidatorPeriod(ctx, val) + if err != nil { + return err + } // increment reference count on period we need to track k.incrementReferenceCount(ctx, valAddr, newPeriod) slashEvent := types.NewValidatorSlashEvent(newPeriod, fraction) - height := uint64(ctx.BlockHeight()) + height := uint64(sdkCtx.BlockHeight()) - k.SetValidatorSlashEvent(ctx, valAddr, height, newPeriod, slashEvent) + return k.SetValidatorSlashEvent(ctx, valAddr, height, newPeriod, slashEvent) } diff --git a/x/distribution/migrations/v2/store.go b/x/distribution/migrations/v2/store.go index a10a79283a78..fe6aea2a5a30 100644 --- a/x/distribution/migrations/v2/store.go +++ b/x/distribution/migrations/v2/store.go @@ -1,8 +1,9 @@ package v2 import ( - storetypes "cosmossdk.io/store/types" + "cosmossdk.io/core/store" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" v1 "github.com/cosmos/cosmos-sdk/x/distribution/migrations/v1" ) @@ -11,8 +12,8 @@ import ( // migration includes: // // - Change addresses to be length-prefixed. -func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey) error { - store := ctx.KVStore(storeKey) +func MigrateStore(ctx sdk.Context, storeService store.KVStoreService) error { + store := runtime.KVStoreAdapter(storeService.OpenKVStore(ctx)) MigratePrefixAddress(store, v1.ValidatorOutstandingRewardsPrefix) MigratePrefixAddress(store, v1.DelegatorWithdrawAddrPrefix) MigratePrefixAddressAddress(store, v1.DelegatorStartingInfoPrefix) diff --git a/x/distribution/migrations/v2/store_test.go b/x/distribution/migrations/v2/store_test.go index 159a06b0866c..ed496123eb43 100644 --- a/x/distribution/migrations/v2/store_test.go +++ b/x/distribution/migrations/v2/store_test.go @@ -8,6 +8,7 @@ import ( storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -18,6 +19,7 @@ import ( func TestStoreMigration(t *testing.T) { distributionKey := storetypes.NewKVStoreKey("distribution") + storeService := runtime.NewKVStoreService(distributionKey) ctx := testutil.DefaultContext(distributionKey, storetypes.NewTransientStoreKey("transient_test")) store := ctx.KVStore(distributionKey) @@ -85,7 +87,7 @@ func TestStoreMigration(t *testing.T) { } // Run migrations. - err := v2.MigrateStore(ctx, distributionKey) + err := v2.MigrateStore(ctx, storeService) require.NoError(t, err) // Make sure the new keys are set and old keys are deleted. diff --git a/x/distribution/migrations/v3/migrate.go b/x/distribution/migrations/v3/migrate.go index 5c6a8dd4458d..441c9fb590d0 100644 --- a/x/distribution/migrations/v3/migrate.go +++ b/x/distribution/migrations/v3/migrate.go @@ -1,7 +1,7 @@ package v3 import ( - storetypes "cosmossdk.io/store/types" + "cosmossdk.io/core/store" sdkmath "cosmossdk.io/math" @@ -21,8 +21,8 @@ var ParamsKey = []byte{0x09} // version 3. Specifically, it takes the parameters that are currently stored // and managed by the x/params module and stores them directly into the x/distribution // module state. -func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, legacySubspace exported.Subspace, cdc codec.BinaryCodec) error { - store := ctx.KVStore(storeKey) +func MigrateStore(ctx sdk.Context, storeService store.KVStoreService, legacySubspace exported.Subspace, cdc codec.BinaryCodec) error { + store := storeService.OpenKVStore(ctx) var currParams types.Params legacySubspace.GetParamSet(ctx, &currParams) @@ -39,7 +39,5 @@ func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, legacySubspace return err } - store.Set(ParamsKey, bz) - - return nil + return store.Set(ParamsKey, bz) } diff --git a/x/distribution/migrations/v3/migrate_test.go b/x/distribution/migrations/v3/migrate_test.go index 2a3d9327b1e3..495f69270f4f 100644 --- a/x/distribution/migrations/v3/migrate_test.go +++ b/x/distribution/migrations/v3/migrate_test.go @@ -7,6 +7,7 @@ import ( storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" @@ -31,12 +32,13 @@ func (ms mockSubspace) GetParamSet(ctx sdk.Context, ps exported.ParamSet) { func TestMigrate(t *testing.T) { cdc := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}).Codec storeKey := storetypes.NewKVStoreKey(v3.ModuleName) + storeService := runtime.NewKVStoreService(storeKey) tKey := storetypes.NewTransientStoreKey("transient_test") ctx := testutil.DefaultContext(storeKey, tKey) store := ctx.KVStore(storeKey) legacySubspace := newMockSubspace(types.DefaultParams()) - require.NoError(t, v3.MigrateStore(ctx, storeKey, legacySubspace, cdc)) + require.NoError(t, v3.MigrateStore(ctx, storeService, legacySubspace, cdc)) var res types.Params bz := store.Get(v3.ParamsKey) diff --git a/x/distribution/module.go b/x/distribution/module.go index 45bdb93f24f9..0712146a55f2 100644 --- a/x/distribution/module.go +++ b/x/distribution/module.go @@ -14,7 +14,7 @@ import ( "cosmossdk.io/core/appmodule" "cosmossdk.io/depinject" - store "cosmossdk.io/store/types" + "cosmossdk.io/core/store" sdkclient "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -221,9 +221,9 @@ func init() { type ModuleInputs struct { depinject.In - Config *modulev1.Module - Key *store.KVStoreKey - Cdc codec.Codec + Config *modulev1.Module + StoreService store.KVStoreService + Cdc codec.Codec AccountKeeper types.AccountKeeper BankKeeper types.BankKeeper @@ -255,7 +255,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { k := keeper.NewKeeper( in.Cdc, - in.Key, + in.StoreService, in.AccountKeeper, in.BankKeeper, in.StakingKeeper, diff --git a/x/distribution/simulation/operations.go b/x/distribution/simulation/operations.go index f39203070e87..ce6e8e510b49 100644 --- a/x/distribution/simulation/operations.go +++ b/x/distribution/simulation/operations.go @@ -91,7 +91,12 @@ func SimulateMsgSetWithdrawAddress(txConfig client.TxConfig, ak types.AccountKee return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { - if !k.GetWithdrawAddrEnabled(ctx) { + isWithdrawAddrEnabled, err := k.GetWithdrawAddrEnabled(ctx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(&types.MsgSetWithdrawAddress{}), "error getting params"), nil, err + } + + if !isWithdrawAddrEnabled { return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(&types.MsgSetWithdrawAddress{}), "withdrawal is not enabled"), nil, nil } @@ -174,7 +179,11 @@ func SimulateMsgWithdrawValidatorCommission(txConfig client.TxConfig, ak types.A return simtypes.NoOpMsg(types.ModuleName, msgType, "random validator is not ok"), nil, nil } - commission := k.GetValidatorAccumulatedCommission(ctx, validator.GetOperator()) + commission, err := k.GetValidatorAccumulatedCommission(ctx, validator.GetOperator()) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msgType, "error getting validator commission"), nil, err + } + if commission.Commission.IsZero() { return simtypes.NoOpMsg(types.ModuleName, msgType, "validator commission is zero"), nil, nil } diff --git a/x/gov/testutil/expected_keepers.go b/x/gov/testutil/expected_keepers.go index c18a77a010b2..0ac7521a2d2d 100644 --- a/x/gov/testutil/expected_keepers.go +++ b/x/gov/testutil/expected_keepers.go @@ -37,5 +37,5 @@ type StakingKeeper interface { // DistributionKeeper defines the expected distribution keeper type DistributionKeeper interface { - FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error + FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error } diff --git a/x/gov/testutil/expected_keepers_mocks.go b/x/gov/testutil/expected_keepers_mocks.go index 7ab0b07143f5..4f2377a40f4d 100644 --- a/x/gov/testutil/expected_keepers_mocks.go +++ b/x/gov/testutil/expected_keepers_mocks.go @@ -1089,7 +1089,7 @@ func (m *MockDistributionKeeper) EXPECT() *MockDistributionKeeperMockRecorder { } // FundCommunityPool mocks base method. -func (m *MockDistributionKeeper) FundCommunityPool(ctx types.Context, amount types.Coins, sender types.AccAddress) error { +func (m *MockDistributionKeeper) FundCommunityPool(ctx context.Context, amount types.Coins, sender types.AccAddress) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FundCommunityPool", ctx, amount, sender) ret0, _ := ret[0].(error) diff --git a/x/gov/types/expected_keepers.go b/x/gov/types/expected_keepers.go index fdb305dbdb1e..3588ee757a02 100644 --- a/x/gov/types/expected_keepers.go +++ b/x/gov/types/expected_keepers.go @@ -32,7 +32,7 @@ type StakingKeeper interface { // DistributionKeeper defines the expected distribution keeper (noalias) type DistributionKeeper interface { - FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error + FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error } // AccountKeeper defines the expected account keeper (noalias) diff --git a/x/slashing/testutil/expected_keepers_mocks.go b/x/slashing/testutil/expected_keepers_mocks.go index a4f56d0957fb..037343fb226f 100644 --- a/x/slashing/testutil/expected_keepers_mocks.go +++ b/x/slashing/testutil/expected_keepers_mocks.go @@ -334,7 +334,7 @@ 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 types.Dec) math.Int { +func (m *MockStakingKeeper) Slash(arg0 types.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec) math.Int { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Slash", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(math.Int) @@ -348,7 +348,7 @@ 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 types.Dec, arg5 types1.Infraction) math.Int { +func (m *MockStakingKeeper) SlashWithInfractionReason(arg0 types.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec, arg5 types1.Infraction) math.Int { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SlashWithInfractionReason", arg0, arg1, arg2, arg3, arg4, arg5) ret0, _ := ret[0].(math.Int) @@ -551,7 +551,7 @@ func (mr *MockStakingHooksMockRecorder) BeforeValidatorModified(ctx, valAddr int } // BeforeValidatorSlashed mocks base method. -func (m *MockStakingHooks) BeforeValidatorSlashed(ctx types.Context, valAddr types.ValAddress, fraction types.Dec) error { +func (m *MockStakingHooks) BeforeValidatorSlashed(ctx types.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/expected_keepers_mocks.go b/x/staking/testutil/expected_keepers_mocks.go index 2b28e31b4738..e44b9c35443f 100644 --- a/x/staking/testutil/expected_keepers_mocks.go +++ b/x/staking/testutil/expected_keepers_mocks.go @@ -38,7 +38,7 @@ func (m *MockDistributionKeeper) EXPECT() *MockDistributionKeeperMockRecorder { } // GetFeePoolCommunityCoins mocks base method. -func (m *MockDistributionKeeper) GetFeePoolCommunityCoins(ctx types.Context) types.DecCoins { +func (m *MockDistributionKeeper) GetFeePoolCommunityCoins(ctx context.Context) types.DecCoins { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetFeePoolCommunityCoins", ctx) ret0, _ := ret[0].(types.DecCoins) @@ -52,7 +52,7 @@ func (mr *MockDistributionKeeperMockRecorder) GetFeePoolCommunityCoins(ctx inter } // GetValidatorOutstandingRewardsCoins mocks base method. -func (m *MockDistributionKeeper) GetValidatorOutstandingRewardsCoins(ctx types.Context, val types.ValAddress) types.DecCoins { +func (m *MockDistributionKeeper) GetValidatorOutstandingRewardsCoins(ctx context.Context, val types.ValAddress) types.DecCoins { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetValidatorOutstandingRewardsCoins", ctx, val) ret0, _ := ret[0].(types.DecCoins) @@ -433,7 +433,7 @@ 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 types.Dec) math.Int { +func (m *MockValidatorSet) Slash(arg0 types.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec) math.Int { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Slash", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(math.Int) @@ -447,7 +447,7 @@ 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 types.Dec, arg5 types0.Infraction) math.Int { +func (m *MockValidatorSet) SlashWithInfractionReason(arg0 types.Context, arg1 types.ConsAddress, arg2, arg3 int64, arg4 math.LegacyDec, arg5 types0.Infraction) math.Int { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SlashWithInfractionReason", arg0, arg1, arg2, arg3, arg4, arg5) ret0, _ := ret[0].(math.Int) @@ -741,7 +741,7 @@ func (mr *MockStakingHooksMockRecorder) BeforeValidatorModified(ctx, valAddr int } // BeforeValidatorSlashed mocks base method. -func (m *MockStakingHooks) BeforeValidatorSlashed(ctx types.Context, valAddr types.ValAddress, fraction types.Dec) error { +func (m *MockStakingHooks) BeforeValidatorSlashed(ctx types.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/types/expected_keepers.go b/x/staking/types/expected_keepers.go index 6776e7cd2754..c6becee40674 100644 --- a/x/staking/types/expected_keepers.go +++ b/x/staking/types/expected_keepers.go @@ -11,8 +11,8 @@ import ( // DistributionKeeper expected distribution keeper (noalias) type DistributionKeeper interface { - GetFeePoolCommunityCoins(ctx sdk.Context) sdk.DecCoins - GetValidatorOutstandingRewardsCoins(ctx sdk.Context, val sdk.ValAddress) sdk.DecCoins + GetFeePoolCommunityCoins(ctx context.Context) sdk.DecCoins + GetValidatorOutstandingRewardsCoins(ctx context.Context, val sdk.ValAddress) sdk.DecCoins } // AccountKeeper defines the expected account keeper (noalias)