Skip to content

Commit

Permalink
fix(x/feegrant)!: limit expired feegrant pruning to 200 per block
Browse files Browse the repository at this point in the history
This is a partial backport of cosmos#18047.
Txs were not migrated.

EndBlocker behaviour was not changed since v47 x/feegrant::EndBlocker cannot produce an error during operation.
  • Loading branch information
MSalopek committed Feb 1, 2024
1 parent 42a86ea commit 50c6502
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 8 deletions.
10 changes: 9 additions & 1 deletion x/feegrant/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,17 +323,25 @@ func (k Keeper) addToFeeAllowanceQueue(ctx sdk.Context, grantKey []byte, exp *ti
store.Set(feegrant.FeeAllowancePrefixQueue(exp, grantKey), []byte{})
}

// NOTE: backport from v50
// RemoveExpiredAllowances iterates grantsByExpiryQueue and deletes the expired grants.
func (k Keeper) RemoveExpiredAllowances(ctx sdk.Context) {
func (k Keeper) RemoveExpiredAllowances(ctx sdk.Context, limit int) {
exp := ctx.BlockTime()
store := ctx.KVStore(k.storeKey)
iterator := store.Iterator(feegrant.FeeAllowanceQueueKeyPrefix, sdk.InclusiveEndBytes(feegrant.AllowanceByExpTimeKey(&exp)))
defer iterator.Close()

count := 0
for ; iterator.Valid(); iterator.Next() {
store.Delete(iterator.Key())

granter, grantee := feegrant.ParseAddressesFromFeeAllowanceQueueKey(iterator.Key())
store.Delete(feegrant.FeeAllowanceKey(granter, grantee))

// limit the amount of iterations to avoid taking too much time
count++
if count == limit {
break
}
}
}
11 changes: 5 additions & 6 deletions x/feegrant/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,17 @@ func TestKeeperTestSuite(t *testing.T) {
}

func (suite *KeeperTestSuite) SetupTest() {
suite.addrs = simtestutil.CreateIncrementalAccounts(4)
suite.addrs = simtestutil.CreateIncrementalAccounts(20)
key := sdk.NewKVStoreKey(feegrant.StoreKey)
testCtx := testutil.DefaultContextWithDB(suite.T(), key, sdk.NewTransientStoreKey("transient_test"))
encCfg := moduletestutil.MakeTestEncodingConfig(module.AppModuleBasic{})

// setup gomock and initialize some globally expected executions
ctrl := gomock.NewController(suite.T())
suite.accountKeeper = feegranttestutil.NewMockAccountKeeper(ctrl)
suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), suite.addrs[0]).Return(authtypes.NewBaseAccountWithAddress(suite.addrs[0])).AnyTimes()
suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), suite.addrs[1]).Return(authtypes.NewBaseAccountWithAddress(suite.addrs[1])).AnyTimes()
suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), suite.addrs[2]).Return(authtypes.NewBaseAccountWithAddress(suite.addrs[2])).AnyTimes()
suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), suite.addrs[3]).Return(authtypes.NewBaseAccountWithAddress(suite.addrs[3])).AnyTimes()
for i := 0; i < len(suite.addrs); i++ {
suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), suite.addrs[i]).Return(authtypes.NewBaseAccountWithAddress(suite.addrs[i])).AnyTimes()
}

suite.feegrantKeeper = keeper.NewKeeper(encCfg.Codec, key, suite.accountKeeper)
suite.ctx = testCtx.Ctx
Expand Down Expand Up @@ -447,7 +446,7 @@ func (suite *KeeperTestSuite) TestPruneGrants() {
}
err := suite.feegrantKeeper.GrantAllowance(suite.ctx, tc.granter, tc.grantee, tc.allowance)
suite.NoError(err)
suite.feegrantKeeper.RemoveExpiredAllowances(tc.ctx)
suite.feegrantKeeper.RemoveExpiredAllowances(tc.ctx, 5)
grant, err := suite.feegrantKeeper.GetAllowance(tc.ctx, tc.granter, tc.grantee)
if tc.expErrMsg != "" {
suite.Error(err)
Expand Down
2 changes: 1 addition & 1 deletion x/feegrant/module/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ import (
)

func EndBlocker(ctx sdk.Context, k keeper.Keeper) {
k.RemoveExpiredAllowances(ctx)
k.RemoveExpiredAllowances(ctx, 200)
}

0 comments on commit 50c6502

Please sign in to comment.