Skip to content

Commit

Permalink
Merge pull request #184 from notional-labs/dang/add-ibc-ratelinit
Browse files Browse the repository at this point in the history
Add IBC Ratelimit module
  • Loading branch information
vuong177 authored Jul 19, 2023
2 parents 8f78ea0 + 4ec456f commit 3f51ec3
Show file tree
Hide file tree
Showing 46 changed files with 10,467 additions and 10 deletions.
9 changes: 9 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ import (
transfermiddleware "github.com/notional-labs/centauri/v3/x/transfermiddleware"
transfermiddlewaretypes "github.com/notional-labs/centauri/v3/x/transfermiddleware/types"

ratelimitmodule "github.com/notional-labs/centauri/v3/x/ratelimit"
ratelimitmoduletypes "github.com/notional-labs/centauri/v3/x/ratelimit/types"

consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types"

"github.com/notional-labs/centauri/v3/x/mint"
Expand Down Expand Up @@ -196,6 +199,7 @@ var (
router.AppModuleBasic{},
ibc_hooks.AppModuleBasic{},
transfermiddleware.AppModuleBasic{},
ratelimitmodule.AppModuleBasic{},
consensus.AppModuleBasic{},
alliancemodule.AppModuleBasic{},
// this line is used by starport scaffolding # stargate/app/moduleBasic
Expand Down Expand Up @@ -308,6 +312,7 @@ func NewCentauriApp(
transferModule := transfer.NewAppModule(app.TransferKeeper)
routerModule := router.NewAppModule(app.RouterKeeper)
transfermiddlewareModule := transfermiddleware.NewAppModule(&app.TransferMiddlewareKeeper)
ratelimitModule := ratelimitmodule.NewAppModule(&app.RatelimitKeeper)
icqModule := icq.NewAppModule(app.ICQKeeper)
ibcHooksModule := ibc_hooks.NewAppModule()
/**** Module Options ****/
Expand Down Expand Up @@ -348,6 +353,7 @@ func NewCentauriApp(
wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)),
routerModule,
transfermiddlewareModule,
ratelimitModule,
alliancemodule.NewAppModule(appCodec, app.AllianceKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
// this line is used by starport scaffolding # stargate/app/appModule
)
Expand All @@ -369,6 +375,7 @@ func NewCentauriApp(
ibctransfertypes.ModuleName,
routertypes.ModuleName,
transfermiddlewaretypes.ModuleName,
ratelimitmoduletypes.ModuleName,
ibchookstypes.ModuleName,
icqtypes.ModuleName,
authtypes.ModuleName,
Expand Down Expand Up @@ -406,6 +413,7 @@ func NewCentauriApp(
ibchost.ModuleName,
routertypes.ModuleName,
transfermiddlewaretypes.ModuleName,
ratelimitmoduletypes.ModuleName,
ibchookstypes.ModuleName,
ibctransfertypes.ModuleName,
icqtypes.ModuleName,
Expand Down Expand Up @@ -440,6 +448,7 @@ func NewCentauriApp(
icqtypes.ModuleName,
routertypes.ModuleName,
transfermiddlewaretypes.ModuleName,
ratelimitmoduletypes.ModuleName,
ibchookstypes.ModuleName,
feegrant.ModuleName,
group.ModuleName,
Expand Down
7 changes: 6 additions & 1 deletion app/ibctesting/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import (
ibctestingtypes "github.com/cosmos/ibc-go/v7/testing/types"
centauri "github.com/notional-labs/centauri/v3/app"
"github.com/notional-labs/centauri/v3/app/ibctesting/simapp"
ratelimit "github.com/notional-labs/centauri/v3/x/ratelimit/keeper"
routerKeeper "github.com/notional-labs/centauri/v3/x/transfermiddleware/keeper"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -122,7 +123,7 @@ func NewTestChain(t *testing.T, coord *Coordinator, chainID string) *TestChain {
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)),
}

app := NewTestingAppDecorator(t, centauri.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance))
app := NewTestingAppDecorator(t, centauri.SetupWithGenesisValSet(t, coord.CurrentTime.UTC(), valSet, []authtypes.GenesisAccount{acc}, balance))

// create current header and call begin block
header := tmproto.Header{
Expand Down Expand Up @@ -616,6 +617,10 @@ func (chain *TestChain) TransferMiddleware() routerKeeper.Keeper {
return chain.GetTestSupport().TransferMiddleware()
}

func (chain *TestChain) RateLimit() ratelimit.Keeper {
return chain.GetTestSupport().RateLimit()
}

func (chain *TestChain) Balance(acc sdk.AccAddress, denom string) sdk.Coin {
return chain.GetTestSupport().BankKeeper().GetBalance(chain.GetContext(), acc, denom)
}
Expand Down
32 changes: 28 additions & 4 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ import (
transfermiddlewarekeeper "github.com/notional-labs/centauri/v3/x/transfermiddleware/keeper"
transfermiddlewaretypes "github.com/notional-labs/centauri/v3/x/transfermiddleware/types"

ratelimitmodule "github.com/notional-labs/centauri/v3/x/ratelimit"
ratelimitmodulekeeper "github.com/notional-labs/centauri/v3/x/ratelimit/keeper"
ratelimitmoduletypes "github.com/notional-labs/centauri/v3/x/ratelimit/types"

consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types"

Expand Down Expand Up @@ -132,10 +136,12 @@ type AppKeepers struct {
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
ScopedTransferKeeper capabilitykeeper.ScopedKeeper
ScopedWasmKeeper capabilitykeeper.ScopedKeeper
ScopedRateLimitKeeper capabilitykeeper.ScopedKeeper
ConsensusParamsKeeper consensusparamkeeper.Keeper
// this line is used by starport scaffolding # stargate/app/keeperDeclaration
TransferMiddlewareKeeper transfermiddlewarekeeper.Keeper
RouterKeeper *routerkeeper.Keeper
RatelimitKeeper ratelimitmodulekeeper.Keeper
AllianceKeeper alliancemodulekeeper.Keeper
}

Expand Down Expand Up @@ -224,6 +230,11 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
appKeepers.Wasm08Keeper = wasm08Keeper.NewKeeper(appCodec, appKeepers.keys[wasmtypes.StoreKey], authorityAddress, homePath)

// Create Transfer Keepers
// * SendPacket. Originates from the transferKeeper and goes up the stack:
// transferKeeper.SendPacket -> transfermiddleware.SendPacket -> ibc_rate_limit.SendPacket -> ibc_hooks.SendPacket -> channel.SendPacket
// * RecvPacket, message that originates from core IBC and goes down to app, the flow is the other way
// channel.RecvPacket -> ibc_hooks.OnRecvPacket -> ibc_rate_limit.OnRecvPacket -> forward.OnRecvPacket -> transfermiddleware_OnRecvPacket -> transfer.OnRecvPacket
//
hooksKeeper := ibchookskeeper.NewKeeper(
appKeepers.keys[ibchookstypes.StoreKey],
)
Expand All @@ -241,7 +252,7 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
appKeepers.keys[transfermiddlewaretypes.StoreKey],
appKeepers.GetSubspace(transfermiddlewaretypes.ModuleName),
appCodec,
&appKeepers.HooksICS4Wrapper,
&appKeepers.RatelimitKeeper,
&appKeepers.TransferKeeper,
appKeepers.BankKeeper,
authorityAddress,
Expand Down Expand Up @@ -270,8 +281,19 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
appKeepers.IBCKeeper.ChannelKeeper,
)

transferIBCModule := transfer.NewIBCModule(appKeepers.TransferKeeper)
appKeepers.RatelimitKeeper = *ratelimitmodulekeeper.NewKeeper(
appCodec,
appKeepers.keys[ratelimitmoduletypes.StoreKey],
appKeepers.GetSubspace(ratelimitmoduletypes.ModuleName),
appKeepers.BankKeeper,
appKeepers.IBCKeeper.ChannelKeeper,
// TODO: Implement ICS4Wrapper in Records and pass records keeper here
&appKeepers.HooksICS4Wrapper, // ICS4Wrapper
appKeepers.TransferMiddlewareKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

transferIBCModule := transfer.NewIBCModule(appKeepers.TransferKeeper)
scopedICQKeeper := appKeepers.CapabilityKeeper.ScopeToModule(icqtypes.ModuleName)

appKeepers.ICQKeeper = icqkeeper.NewKeeper(
Expand All @@ -293,8 +315,8 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
routerkeeper.DefaultForwardTransferPacketTimeoutTimestamp,
routerkeeper.DefaultRefundTransferPacketTimeoutTimestamp,
)

hooksTransferMiddleware := ibc_hooks.NewIBCMiddleware(ibcMiddlewareStack, &appKeepers.HooksICS4Wrapper)
ratelimitMiddlewareStack := ratelimitmodule.NewIBCMiddleware(appKeepers.RatelimitKeeper, ibcMiddlewareStack)
hooksTransferMiddleware := ibc_hooks.NewIBCMiddleware(ratelimitMiddlewareStack, &appKeepers.HooksICS4Wrapper)

// Create evidence Keeper for to register the IBC light client misbehaviour evidence route
evidenceKeeper := evidencekeeper.NewKeeper(
Expand Down Expand Up @@ -392,6 +414,7 @@ func (appKeepers *AppKeepers) InitSpecialKeepers(
appKeepers.ScopedIBCKeeper = appKeepers.CapabilityKeeper.ScopeToModule(ibchost.ModuleName)
appKeepers.ScopedTransferKeeper = appKeepers.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
appKeepers.ScopedWasmKeeper = appKeepers.CapabilityKeeper.ScopeToModule(wasm.ModuleName)
appKeepers.ScopedRateLimitKeeper = appKeepers.CapabilityKeeper.ScopeToModule(ratelimitmoduletypes.ModuleName)

appKeepers.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, appKeepers.keys[upgradetypes.StoreKey], appCodec, homePath, bApp, authtypes.NewModuleAddress(govtypes.ModuleName).String())
}
Expand All @@ -410,6 +433,7 @@ func (appKeepers *AppKeepers) initParamsKeeper(appCodec codec.BinaryCodec, legac
paramsKeeper.Subspace(minttypes.ModuleName).WithKeyTable(minttypes.ParamKeyTable())
paramsKeeper.Subspace(crisistypes.ModuleName)
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
paramsKeeper.Subspace(ratelimitmoduletypes.ModuleName)
paramsKeeper.Subspace(icqtypes.ModuleName)
paramsKeeper.Subspace(ibchost.ModuleName)
paramsKeeper.Subspace(alliancemoduletypes.ModuleName)
Expand Down
2 changes: 2 additions & 0 deletions app/keepers/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (

storetypes "github.com/cosmos/cosmos-sdk/store/types"
minttypes "github.com/notional-labs/centauri/v3/x/mint/types"
ratelimitmoduletypes "github.com/notional-labs/centauri/v3/x/ratelimit/types"

"github.com/CosmWasm/wasmd/x/wasm"
wasm08types "github.com/cosmos/ibc-go/v7/modules/light-clients/08-wasm/types"
Expand All @@ -47,6 +48,7 @@ func (appKeepers *AppKeepers) GenerateKeys() {
govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
evidencetypes.StoreKey, ibctransfertypes.StoreKey, icqtypes.StoreKey, capabilitytypes.StoreKey, consensusparamtypes.StoreKey, wasm08types.StoreKey,
crisistypes.StoreKey, routertypes.StoreKey, transfermiddlewaretypes.StoreKey, group.StoreKey, minttypes.StoreKey, alliancemoduletypes.StoreKey, wasm.StoreKey, ibchookstypes.StoreKey,
ratelimitmoduletypes.StoreKey,
)

// Define transient store keys
Expand Down
9 changes: 7 additions & 2 deletions app/test_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import (
ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper"
ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper"
wasm08 "github.com/cosmos/ibc-go/v7/modules/light-clients/08-wasm/keeper"
routerKeeper "github.com/notional-labs/centauri/v3/x/transfermiddleware/keeper"
ratelimitKeeper "github.com/notional-labs/centauri/v3/x/ratelimit/keeper"
tfmdKeeper "github.com/notional-labs/centauri/v3/x/transfermiddleware/keeper"
)

type TestSupport struct {
Expand Down Expand Up @@ -81,6 +82,10 @@ func (s TestSupport) GetTxConfig() client.TxConfig {
return s.app.GetTxConfig()
}

func (s TestSupport) TransferMiddleware() routerKeeper.Keeper {
func (s TestSupport) TransferMiddleware() tfmdKeeper.Keeper {
return s.app.TransferMiddlewareKeeper
}

func (s TestSupport) RateLimit() ratelimitKeeper.Keeper {
return s.app.RatelimitKeeper
}
2 changes: 2 additions & 0 deletions app/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func setup(tb testing.TB, withGenesis bool, invCheckPeriod uint) (*CentauriApp,
// account. A Nop logger is set in FeeAbs.
func SetupWithGenesisValSet(
t *testing.T,
ctxTime time.Time,
valSet *tmtypes.ValidatorSet,
genAccs []authtypes.GenesisAccount,
balances ...banktypes.Balance,
Expand Down Expand Up @@ -159,6 +160,7 @@ func SetupWithGenesisValSet(
// init chain will set the validator set and initialize the genesis accounts
app.InitChain(
abci.RequestInitChain{
Time: ctxTime,
Validators: []abci.ValidatorUpdate{},
ConsensusParams: DefaultConsensusParams,
AppStateBytes: stateBytes,
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/cosmos/cosmos-sdk v0.47.3
github.com/cosmos/gogoproto v1.4.10
github.com/cosmos/ibc-go/v7 v7.0.1
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.3
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
Expand Down Expand Up @@ -44,7 +45,6 @@ require (
github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
Expand Down
65 changes: 65 additions & 0 deletions proto/centauri/ratelimit/v1beta1/epoch.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
syntax = "proto3";
package centauri.ratelimit.v1beta1;

import "gogoproto/gogo.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

option go_package = "x/ratelimit/types";

message EpochInfo {
// identifier is a unique reference to this particular timer.
string identifier = 1;
// start_time is the time at which the timer first ever ticks.
// If start_time is in the future, the epoch will not begin until the start
// time.
google.protobuf.Timestamp start_time = 2 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"start_time\""
];
// duration is the time in between epoch ticks.
// In order for intended behavior to be met, duration should
// be greater than the chains expected block time.
// Duration must be non-zero.
google.protobuf.Duration duration = 3 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.jsontag) = "duration,omitempty",
(gogoproto.moretags) = "yaml:\"duration\""
];
// current_epoch is the current epoch number, or in other words,
// how many times has the timer 'ticked'.
// The first tick (current_epoch=1) is defined as
// the first block whose blocktime is greater than the EpochInfo start_time.
int64 current_epoch = 4;
// current_epoch_start_time describes the start time of the current timer
// interval. The interval is (current_epoch_start_time,
// current_epoch_start_time + duration] When the timer ticks, this is set to
// current_epoch_start_time = last_epoch_start_time + duration only one timer
// tick for a given identifier can occur per block.
//
// NOTE! The current_epoch_start_time may diverge significantly from the
// wall-clock time the epoch began at. Wall-clock time of epoch start may be
// >> current_epoch_start_time. Suppose current_epoch_start_time = 10,
// duration = 5. Suppose the chain goes offline at t=14, and comes back online
// at t=30, and produces blocks at every successive time. (t=31, 32, etc.)
// * The t=30 block will start the epoch for (10, 15]
// * The t=31 block will start the epoch for (15, 20]
// * The t=32 block will start the epoch for (20, 25]
// * The t=33 block will start the epoch for (25, 30]
// * The t=34 block will start the epoch for (30, 35]
// * The **t=36** block will start the epoch for (35, 40]
google.protobuf.Timestamp current_epoch_start_time = 5 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"current_epoch_start_time\""
];
// epoch_counting_started is a boolean, that indicates whether this
// epoch timer has began yet.
bool epoch_counting_started = 6;
reserved 7;
// current_epoch_start_height is the block height at which the current epoch
// started. (The block height at which the timer last ticked)
int64 current_epoch_start_height = 8;
}
31 changes: 31 additions & 0 deletions proto/centauri/ratelimit/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
syntax = "proto3";
package centauri.ratelimit.v1beta1;

import "gogoproto/gogo.proto";
import "centauri/ratelimit/v1beta1/params.proto";
import "centauri/ratelimit/v1beta1/ratelimit.proto";
import "centauri/ratelimit/v1beta1/epoch.proto";

option go_package = "x/ratelimit/types";

// GenesisState defines the ratelimit module's genesis state.
message GenesisState {
Params params = 1 [
(gogoproto.moretags) = "yaml:\"params\"",
(gogoproto.nullable) = false
];

repeated RateLimit rate_limits = 2 [
(gogoproto.moretags) = "yaml:\"rate_limits\"",
(gogoproto.nullable) = false
];

repeated WhitelistedAddressPair whitelisted_address_pairs = 3 [
(gogoproto.moretags) = "yaml:\"whitelisted_address_pairs\"",
(gogoproto.nullable) = false
];

repeated string pending_send_packet_sequence_numbers = 4;

repeated EpochInfo epochs = 5 [ (gogoproto.nullable) = false ];
}
10 changes: 10 additions & 0 deletions proto/centauri/ratelimit/v1beta1/params.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
syntax = "proto3";
package centauri.ratelimit.v1beta1;

option go_package = "x/ratelimit/types";

import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";

// Params holds parameters for the mint module.
message Params {}
Loading

0 comments on commit 3f51ec3

Please sign in to comment.