Skip to content

Commit

Permalink
feat!: add rate limit module (#3002)
Browse files Browse the repository at this point in the history
* wire the rate limit module

* remove provider from simulationModules

* add rate limit -- wip

* test adding rate limits

* adding the other tests for rate limit

* add changelog entries

* fix linter

* fix linter

* add gov authority as a constant

* add module to StoreUpgrades in the upgrade handler

* increase e2e timeout to 35

* fix linter

* chore: appease linter

---------

Co-authored-by: MSalopek <matija.salopek994@gmail.com>
  • Loading branch information
mpoke and MSalopek committed Mar 25, 2024
1 parent 85ce7dd commit 62cb8ae
Show file tree
Hide file tree
Showing 19 changed files with 532 additions and 21 deletions.
3 changes: 3 additions & 0 deletions .changelog/unreleased/dependencies/3002-rate-limit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Add the [IBC Rate Limit module](https://github.com/Stride-Labs/ibc-rate-limiting)
[v1.0.1](https://github.com/Stride-Labs/ibc-rate-limiting/releases/tag/v1.0.1).
([\#3002](https://github.com/cosmos/gaia/pull/3002))
2 changes: 2 additions & 0 deletions .changelog/unreleased/features/3002-rate-limit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Add the [IBC Rate Limit module](https://github.com/Stride-Labs/ibc-rate-limiting).
([\#3002](https://github.com/cosmos/gaia/pull/3002))
2 changes: 2 additions & 0 deletions .changelog/unreleased/state-breaking/3002-rate-limit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Add the [IBC Rate Limit module](https://github.com/Stride-Labs/ibc-rate-limiting).
([\#3002](https://github.com/cosmos/gaia/pull/3002))
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ test-unit-cover: ARGS=-timeout=5m -tags='norace' -coverprofile=coverage.txt -cov
test-unit-cover: TEST_PACKAGES=$(PACKAGES_UNIT)
test-race: ARGS=-timeout=5m -race
test-race: TEST_PACKAGES=$(PACKAGES_UNIT)
test-e2e: ARGS=-timeout=25m -v
test-e2e: ARGS=-timeout=35m -v
test-e2e: TEST_PACKAGES=$(PACKAGES_E2E)
$(TEST_TARGETS): run-tests

Expand Down
39 changes: 31 additions & 8 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ package keepers
import (
"os"

ratelimit "github.com/Stride-Labs/ibc-rate-limiting/ratelimit"
ratelimitkeeper "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/keeper"
ratelimittypes "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/types"

// unnamed import of statik for swagger UI support
_ "github.com/cosmos/cosmos-sdk/client/docs/statik"

Expand Down Expand Up @@ -106,11 +110,13 @@ type AppKeepers struct {
ProviderKeeper ibcproviderkeeper.Keeper

PFMRouterKeeper *pfmrouterkeeper.Keeper
RatelimitKeeper ratelimitkeeper.Keeper

// Modules
ICAModule ica.AppModule
TransferModule transfer.AppModule
PFMRouterModule pfmrouter.AppModule
RateLimitModule ratelimit.AppModule
ProviderModule ibcprovider.AppModule

// make scoped keepers public for test purposes
Expand Down Expand Up @@ -364,6 +370,19 @@ func NewAppKeeper(
bApp.MsgServiceRouter(),
)

govAuthority := authtypes.NewModuleAddress(govtypes.ModuleName).String()

// Create RateLimit keeper
appKeepers.RatelimitKeeper = *ratelimitkeeper.NewKeeper(
appCodec, // BinaryCodec
appKeepers.keys[ratelimittypes.StoreKey], // StoreKey
appKeepers.GetSubspace(ratelimittypes.ModuleName), // param Subspace
govAuthority, // authority
appKeepers.BankKeeper,
appKeepers.IBCKeeper.ChannelKeeper, // ChannelKeeper
appKeepers.IBCKeeper.ChannelKeeper, // ICS4Wrapper
)

// ICA Controller keeper
appKeepers.ICAControllerKeeper = icacontrollerkeeper.NewKeeper(
appCodec,
Expand All @@ -377,16 +396,15 @@ func NewAppKeeper(
)

// PFMRouterKeeper must be created before TransferKeeper
authority := authtypes.NewModuleAddress(govtypes.ModuleName).String()
appKeepers.PFMRouterKeeper = pfmrouterkeeper.NewKeeper(
appCodec,
appKeepers.keys[pfmroutertypes.StoreKey],
nil, // Will be zero-value here. Reference is set later on with SetTransferKeeper.
appKeepers.IBCKeeper.ChannelKeeper,
appKeepers.DistrKeeper,
appKeepers.BankKeeper,
appKeepers.IBCKeeper.ChannelKeeper,
authority,
appKeepers.RatelimitKeeper, // ICS4Wrapper
govAuthority,
)

appKeepers.TransferKeeper = ibctransferkeeper.NewKeeper(
Expand All @@ -407,21 +425,25 @@ func NewAppKeeper(
appKeepers.ICAModule = ica.NewAppModule(&appKeepers.ICAControllerKeeper, &appKeepers.ICAHostKeeper)
appKeepers.TransferModule = transfer.NewAppModule(appKeepers.TransferKeeper)
appKeepers.PFMRouterModule = pfmrouter.NewAppModule(appKeepers.PFMRouterKeeper, appKeepers.GetSubspace(pfmroutertypes.ModuleName))
appKeepers.RateLimitModule = ratelimit.NewAppModule(appCodec, appKeepers.RatelimitKeeper)

// create IBC module from bottom to top of stack
// Create Transfer Stack (from bottom to top of stack)
// - core IBC
// - ratelimit
// - pfm
// - transfer
var transferStack porttypes.IBCModule
transferStack = transfer.NewIBCModule(appKeepers.TransferKeeper)
transferStack = pfmrouter.NewIBCMiddleware(
transferStack,
appKeepers.PFMRouterKeeper,
0,
0, // retries on timeout
pfmrouterkeeper.DefaultForwardTransferPacketTimeoutTimestamp,
pfmrouterkeeper.DefaultRefundTransferPacketTimeoutTimestamp,
)
transferStack = ratelimit.NewIBCMiddleware(appKeepers.RatelimitKeeper, transferStack)

// Add transfer stack to IBC Router

// Create Interchain Accounts Host Stack
// Create ICAHost Stack
var icaHostStack porttypes.IBCModule = icahost.NewIBCModule(appKeepers.ICAHostKeeper)

// Create Interchain Accounts Controller Stack
Expand Down Expand Up @@ -466,6 +488,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
paramsKeeper.Subspace(icahosttypes.SubModuleName)
paramsKeeper.Subspace(icacontrollertypes.SubModuleName)
paramsKeeper.Subspace(pfmroutertypes.ModuleName).WithKeyTable(pfmroutertypes.ParamKeyTable())
paramsKeeper.Subspace(ratelimittypes.ModuleName)
paramsKeeper.Subspace(globalfee.ModuleName)
paramsKeeper.Subspace(providertypes.ModuleName)

Expand Down
3 changes: 3 additions & 0 deletions app/keepers/keys.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package keepers

import (
ratelimittypes "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/types"

routertypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward/types"
icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"
icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types"
Expand Down Expand Up @@ -50,6 +52,7 @@ func (appKeepers *AppKeepers) GenerateKeys() {
feegrant.StoreKey,
authzkeeper.StoreKey,
routertypes.StoreKey,
ratelimittypes.StoreKey,
providertypes.StoreKey,
consensusparamtypes.StoreKey,
)
Expand Down
10 changes: 9 additions & 1 deletion app/modules.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package gaia

import (
ratelimit "github.com/Stride-Labs/ibc-rate-limiting/ratelimit"
ratelimittypes "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/types"

pfmrouter "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward"
pfmroutertypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward/types"
ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts"
Expand Down Expand Up @@ -109,6 +112,7 @@ var ModuleBasics = module.NewBasicManager(
transfer.AppModuleBasic{},
vesting.AppModuleBasic{},
pfmrouter.AppModuleBasic{},
ratelimit.AppModuleBasic{},
ica.AppModuleBasic{},
globalfee.AppModule{},
icsprovider.AppModuleBasic{},
Expand Down Expand Up @@ -151,6 +155,8 @@ func appModules(
app.TransferModule,
app.ICAModule,
app.PFMRouterModule,
app.RateLimitModule,

app.ProviderModule,
metaprotocols.NewAppModule(),
}
Expand Down Expand Up @@ -181,7 +187,6 @@ func simulationModules(
ibc.NewAppModule(app.IBCKeeper),
app.TransferModule,
app.ICAModule,
app.ProviderModule,
}
}

Expand Down Expand Up @@ -215,6 +220,7 @@ func orderBeginBlockers() []string {
ibctransfertypes.ModuleName,
icatypes.ModuleName,
pfmroutertypes.ModuleName,
ratelimittypes.ModuleName,
genutiltypes.ModuleName,
authz.ModuleName,
feegrant.ModuleName,
Expand Down Expand Up @@ -244,6 +250,7 @@ func orderEndBlockers() []string {
ibctransfertypes.ModuleName,
icatypes.ModuleName,
pfmroutertypes.ModuleName,
ratelimittypes.ModuleName,
capabilitytypes.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
Expand Down Expand Up @@ -291,6 +298,7 @@ func orderInitBlockers() []string {
authz.ModuleName,
feegrant.ModuleName,
pfmroutertypes.ModuleName,
ratelimittypes.ModuleName,
paramstypes.ModuleName,
upgradetypes.ModuleName,
vestingtypes.ModuleName,
Expand Down
3 changes: 3 additions & 0 deletions app/upgrades/v16/constants.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package v16

import (
ratelimittypes "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/types"

icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"

store "github.com/cosmos/cosmos-sdk/store/types"
Expand All @@ -18,6 +20,7 @@ var Upgrade = upgrades.Upgrade{
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: store.StoreUpgrades{
Added: []string{
ratelimittypes.ModuleName,
icacontrollertypes.SubModuleName,
},
},
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
cosmossdk.io/math v1.3.0
cosmossdk.io/simapp v0.0.0-20230602123434-616841b9704d
cosmossdk.io/tools/rosetta v0.2.1
github.com/Stride-Labs/ibc-rate-limiting v1.0.1
github.com/cometbft/cometbft v0.37.4
github.com/cometbft/cometbft-db v0.10.0
github.com/cosmos/cosmos-sdk v0.47.10
Expand Down Expand Up @@ -107,7 +108,7 @@ require (
github.com/golang/glog v1.2.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/orderedcode v0.0.1 // indirect
Expand Down
5 changes: 4 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/Stride-Labs/ibc-rate-limiting v1.0.1 h1:MT80/HAZ+sCVqmfill5dJ7aIY/p5evGF3MslbU0PRas=
github.com/Stride-Labs/ibc-rate-limiting v1.0.1/go.mod h1:EBulHz7dKsjbydj7bHiykqraA4Vn7wRkoTXZ7tydRZM=
github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw=
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
Expand Down Expand Up @@ -642,8 +644,9 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk=
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
Expand Down
3 changes: 3 additions & 0 deletions tests/e2e/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"os"

ratelimittypes "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/types"

tmrand "github.com/cometbft/cometbft/libs/rand"

providertypes "github.com/cosmos/interchain-security/v3/x/ccv/provider/types"
Expand Down Expand Up @@ -55,6 +57,7 @@ func init() {
distribtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
providertypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
metaprotocoltypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
ratelimittypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)

cdc = encodingConfig.Marshaler
txConfig = encodingConfig.TxConfig
Expand Down
2 changes: 2 additions & 0 deletions tests/e2e/e2e_gov_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ func (s *IntegrationTestSuite) submitLegacyGovProposal(chainAAPIEndpoint, sender
// Instead, the depoist is added to the "deposit" field of the proposal JSON (usually stored as a file)
// you can use `gaiad tx gov draft-proposal` to create a proposal file that you can use
// min initial deposit of 100uatom is required in e2e tests, otherwise the proposal would be dropped
//
//nolint:unparam
func (s *IntegrationTestSuite) submitGovProposal(chainAAPIEndpoint, sender string, proposalID int, proposalType string, submitFlags []string, depositFlags []string, voteFlags []string, voteCommand string) {
s.T().Logf("Submitting Gov Proposal: %s", proposalType)
sflags := submitFlags
Expand Down
17 changes: 11 additions & 6 deletions tests/e2e/e2e_ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type PacketMetadata struct {
}

//nolint:unparam
func (s *IntegrationTestSuite) sendIBC(c *chain, valIdx int, sender, recipient, token, fees, note string) {
func (s *IntegrationTestSuite) sendIBC(c *chain, valIdx int, sender, recipient, token, fees, note string, expErr bool) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

Expand All @@ -51,8 +51,13 @@ func (s *IntegrationTestSuite) sendIBC(c *chain, valIdx int, sender, recipient,
"-y",
}
s.T().Logf("sending %s from %s (%s) to %s (%s) with memo %s", token, s.chainA.id, sender, s.chainB.id, recipient, note)
s.executeGaiaTxCommand(ctx, c, ibcCmd, valIdx, s.defaultExecValidation(c, valIdx))
s.T().Log("successfully sent IBC tokens")
if expErr {
s.executeGaiaTxCommand(ctx, c, ibcCmd, valIdx, s.expectErrExecValidation(c, valIdx, true))
s.T().Log("unsuccessfully sent IBC tokens")
} else {
s.executeGaiaTxCommand(ctx, c, ibcCmd, valIdx, s.defaultExecValidation(c, valIdx))
s.T().Log("successfully sent IBC tokens")
}
}

func (s *IntegrationTestSuite) hermesTransfer(configPath, srcChainID, dstChainID, srcChannelID, denom string, sendAmt, timeOutOffset, numMsg int) (success bool) {
Expand Down Expand Up @@ -314,7 +319,7 @@ func (s *IntegrationTestSuite) testIBCTokenTransfer() {
}

tokenAmt := 3300000000
s.sendIBC(s.chainA, 0, sender, recipient, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), "")
s.sendIBC(s.chainA, 0, sender, recipient, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), "", false)

pass := s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().True(pass)
Expand Down Expand Up @@ -407,7 +412,7 @@ func (s *IntegrationTestSuite) testMultihopIBCTokenTransfer() {
memo, err := json.Marshal(firstHopMetadata)
s.Require().NoError(err)

s.sendIBC(s.chainA, 0, sender, middlehop, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), string(memo))
s.sendIBC(s.chainA, 0, sender, middlehop, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), string(memo), false)

pass := s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().True(pass)
Expand Down Expand Up @@ -482,7 +487,7 @@ func (s *IntegrationTestSuite) testFailedMultihopIBCTokenTransfer() {
memo, err := json.Marshal(firstHopMetadata)
s.Require().NoError(err)

s.sendIBC(s.chainA, 0, sender, middlehop, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), string(memo))
s.sendIBC(s.chainA, 0, sender, middlehop, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), string(memo), false)

// Sender account should be initially decremented the full amount
s.Require().Eventually(
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/e2e_ica_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (s *IntegrationTestSuite) testICARegisterAccountAndSendTx() {
)

tokenAmount := 3300000000
s.sendIBC(s.chainA, 0, icaOwnerAccount, icaAccount, strconv.Itoa(tokenAmount)+uatomDenom, standardFees.String(), "")
s.sendIBC(s.chainA, 0, icaOwnerAccount, icaAccount, strconv.Itoa(tokenAmount)+uatomDenom, standardFees.String(), "", false)

pass := s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().True(pass)
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/e2e_lsm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (s *IntegrationTestSuite) testLSM() {
// IBC transfer LSM token
ibcTransferAmount := sdk.NewCoin(shareDenom, sdk.NewInt(100000000))
sendRecipientAddr, _ := s.chainB.validators[0].keyInfo.GetAddress()
s.sendIBC(s.chainA, 0, validatorAAddr.String(), sendRecipientAddr.String(), ibcTransferAmount.String(), standardFees.String(), "memo")
s.sendIBC(s.chainA, 0, validatorAAddr.String(), sendRecipientAddr.String(), ibcTransferAmount.String(), standardFees.String(), "memo", false)

s.Require().Eventually(
func() bool {
Expand Down
Loading

0 comments on commit 62cb8ae

Please sign in to comment.