Skip to content

feat: rate limit module #8268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions modules/apps/callbacks/types/callbacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
"strconv"
"strings"

errorsmod "cosmossdk.io/errors"

Check failure on line 8 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

other declaration of errorsmod

Check failure on line 8 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

other declaration of errorsmod

Check failure on line 8 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / unit-tests (ibc-go, .)

other declaration of errorsmod

Check failure on line 8 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

other declaration of errorsmod

Check failure on line 8 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

other declaration of errorsmod

sdk "github.com/cosmos/cosmos-sdk/types"

errorsmod "cosmossdk.io/errors"

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

errorsmod redeclared in this block

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

"cosmossdk.io/errors" imported as errorsmod and not used) (typecheck)

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

errorsmod redeclared in this block

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

"cosmossdk.io/errors" imported as errorsmod and not used) (typecheck)

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

errorsmod redeclared in this block

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / unit-tests (ibc-go, .)

"cosmossdk.io/errors" imported as errorsmod and not used

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / unit-tests (ibc-go, .)

errorsmod redeclared in this block

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

errorsmod redeclared in this block

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

"cosmossdk.io/errors" imported as errorsmod and not used) (typecheck)

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

errorsmod redeclared in this block

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

"cosmossdk.io/errors" imported as errorsmod and not used) (typecheck)

Check failure on line 12 in modules/apps/callbacks/types/callbacks.go

View workflow job for this annotation

GitHub Actions / lint (.)

errorsmod redeclared in this block

channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types"
ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported"
Expand Down
10 changes: 10 additions & 0 deletions modules/apps/packet-forward-middleware/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ func (k *Keeper) SetTransferKeeper(transferKeeper types.TransferKeeper) {
k.transferKeeper = transferKeeper
}

// SetICS4Wrapper sets the ICS4 Wrapper to pass packets downstream.
func (k *Keeper) SetICS4Wrapper(wrapper porttypes.ICS4Wrapper) {
k.ics4Wrapper = wrapper
}

// ICS4Wrapper gets the ICS4 Wrapper for PFM.
func (k *Keeper) ICS4Wrapper() porttypes.ICS4Wrapper {
return k.ics4Wrapper
}

// Logger returns a module-specific logger.
func (*Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", "x/"+ibcexported.ModuleName+"-"+types.ModuleName)
Expand Down
219 changes: 219 additions & 0 deletions modules/apps/rate-limiting/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
package cli

import (
"context"
"fmt"
"strings"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/version"

"github.com/cosmos/ibc-go/v10/modules/apps/rate-limiting/types"
)

const (
FlagDenom = "denom"
)

// GetQueryCmd returns the cli query commands for this module.
func GetQueryCmd() *cobra.Command {
// Group ratelimit queries under a subcommand
cmd := &cobra.Command{
Use: types.ModuleName,
Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName),
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}

cmd.AddCommand(
GetCmdQueryRateLimit(),
GetCmdQueryAllRateLimits(),
GetCmdQueryRateLimitsByChainID(),
GetCmdQueryAllBlacklistedDenoms(),
GetCmdQueryAllWhitelistedAddresses(),
// TODO: Add GetCmdQueryParams if needed
)
return cmd
}

// GetCmdQueryRateLimit implements a command to query rate limits by channel-id or client-id and denom
func GetCmdQueryRateLimit() *cobra.Command {
cmd := &cobra.Command{
Use: "rate-limit [channel-or-client-id]",
Short: "Query rate limits by channel-id/client-id and denom",
Long: strings.TrimSpace(
fmt.Sprintf(`Query rate limits by channel-id/client-id and denom.
If the denom flag is omitted, all rate limits for the given channel-id/client-id are returned.

Example:
$ %s query %s rate-limit [channel-or-client-id]
$ %s query %s rate-limit [channel-or-client-id] --denom=[denom]
`,
version.AppName, types.ModuleName, version.AppName, types.ModuleName,
),
),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
channelOrClientID := args[0]
denom, err := cmd.Flags().GetString(FlagDenom)
if err != nil {
return err
}

clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)

if denom == "" {
// Query all rate limits for the channel/client ID if denom is not specified
req := &types.QueryRateLimitsByChannelOrClientIDRequest{
ChannelOrClientId: channelOrClientID,
}
res, err := queryClient.RateLimitsByChannelOrClientID(context.Background(), req)
if err != nil {
return err
}
// Use PrintProto for slice types as PrintObjectLegacy might not work well
return clientCtx.PrintProto(res)
}

// Query specific rate limit if denom is provided
req := &types.QueryRateLimitRequest{
Denom: denom,
ChannelOrClientId: channelOrClientID,
}
res, err := queryClient.RateLimit(context.Background(), req)
if err != nil {
return err
}

return clientCtx.PrintProto(res.RateLimit)
},
}

cmd.Flags().String(FlagDenom, "", "The denom identifying a specific rate limit")
flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// GetCmdQueryAllRateLimits return all available rate limits.
func GetCmdQueryAllRateLimits() *cobra.Command {
cmd := &cobra.Command{
Use: "list-rate-limits",
Short: "Query all rate limits",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)

req := &types.QueryAllRateLimitsRequest{}
res, err := queryClient.AllRateLimits(context.Background(), req)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// GetCmdQueryRateLimitsByChainID return all rate limits that exist between this chain
// and the specified ChainId
func GetCmdQueryRateLimitsByChainID() *cobra.Command {
cmd := &cobra.Command{
Use: "rate-limits-by-chain [chain-id]",
Short: "Query all rate limits associated with the channels/clients connecting to the given ChainID",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
chainID := args[0]

clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)

req := &types.QueryRateLimitsByChainIDRequest{
ChainId: chainID,
}
res, err := queryClient.RateLimitsByChainID(context.Background(), req)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// GetCmdQueryAllBlacklistedDenoms returns the command to query all blacklisted denoms
func GetCmdQueryAllBlacklistedDenoms() *cobra.Command {
cmd := &cobra.Command{
Use: "list-blacklisted-denoms",
Short: "Query all blacklisted denoms",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)

req := &types.QueryAllBlacklistedDenomsRequest{}
res, err := queryClient.AllBlacklistedDenoms(context.Background(), req)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)
return cmd
}

// GetCmdQueryAllWhitelistedAddresses returns the command to query all whitelisted address pairs
func GetCmdQueryAllWhitelistedAddresses() *cobra.Command {
cmd := &cobra.Command{
Use: "list-whitelisted-addresses",
Short: "Query all whitelisted address pairs",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)

req := &types.QueryAllWhitelistedAddressesRequest{}
res, err := queryClient.AllWhitelistedAddresses(context.Background(), req)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)
return cmd
}
8 changes: 8 additions & 0 deletions modules/apps/rate-limiting/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Package rate-limiting implements a middleware to rate limit IBC transfers
between different chains to prevent excessive token flow in either direction.
This module monitors and enforces configurable rate limits on token transfers
across IBC channels to protect chains from economic attacks or unintended
token drainage.
*/
package ratelimiting
Loading
Loading