Skip to content
Merged
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
30 changes: 30 additions & 0 deletions evmrpc/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ type Config struct {

// IPRateLimitBurst is the maximum per-IP burst size.
IPRateLimitBurst int `mapstructure:"ip_rate_limit_burst"`

// BatchRequestLimit is the maximum number of requests allowed in a single
// JSON-RPC batch (HTTP and WebSocket). Set to 0 to disable the limit.
BatchRequestLimit int `mapstructure:"batch_request_limit"`

// BatchResponseMaxSize is the maximum number of bytes returned from a
// batched JSON-RPC call (HTTP and WebSocket). Set to 0 to disable the limit.
BatchResponseMaxSize int `mapstructure:"batch_response_max_size"`
}

var DefaultConfig = Config{
Expand Down Expand Up @@ -217,6 +225,8 @@ var DefaultConfig = Config{
TraceBakeSnapshotWindow: 64,
IPRateLimitRPS: 200,
IPRateLimitBurst: 400,
BatchRequestLimit: 1000,
BatchResponseMaxSize: 25 * 1000 * 1000, // 25MB
}

const (
Expand Down Expand Up @@ -261,6 +271,8 @@ const (
flagTraceBakeSnapshotWindow = "evm.trace_bake_snapshot_window"
flagIPRateLimitRPS = "evm.ip_rate_limit_rps"
flagIPRateLimitBurst = "evm.ip_rate_limit_burst"
flagBatchRequestLimit = "evm.batch_request_limit"
flagBatchResponseMaxSize = "evm.batch_response_max_size"
)

func ReadConfig(opts servertypes.AppOptions) (Config, error) {
Expand Down Expand Up @@ -471,6 +483,16 @@ func ReadConfig(opts servertypes.AppOptions) (Config, error) {
return cfg, err
}
}
if v := opts.Get(flagBatchRequestLimit); v != nil {
if cfg.BatchRequestLimit, err = cast.ToIntE(v); err != nil {
return cfg, err
}
}
if v := opts.Get(flagBatchResponseMaxSize); v != nil {
if cfg.BatchResponseMaxSize, err = cast.ToIntE(v); err != nil {
return cfg, err
}
}
return cfg, nil
}

Expand Down Expand Up @@ -670,4 +692,12 @@ ip_rate_limit_rps = {{ .EVM.IPRateLimitRPS }}
# ip_rate_limit_burst is the maximum per-IP burst above the sustained rate.
ip_rate_limit_burst = {{ .EVM.IPRateLimitBurst }}

# batch_request_limit is the maximum number of requests allowed in a single
# JSON-RPC batch (HTTP and WebSocket). Set to 0 to disable the limit.
batch_request_limit = {{ .EVM.BatchRequestLimit }}

# batch_response_max_size is the maximum number of bytes returned from a
# batched JSON-RPC call (HTTP and WebSocket). Set to 0 to disable the limit.
batch_response_max_size = {{ .EVM.BatchResponseMaxSize }}

`
38 changes: 38 additions & 0 deletions evmrpc/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ type opts struct {
workerQueueSize interface{}
ipRateLimitRPS interface{}
ipRateLimitBurst interface{}
batchRequestLimit interface{}
batchResponseMaxSize interface{}
}

func (o *opts) Get(k string) interface{} {
Expand Down Expand Up @@ -160,6 +162,12 @@ func (o *opts) Get(k string) interface{} {
if k == "evm.ip_rate_limit_burst" {
return o.ipRateLimitBurst
}
if k == "evm.batch_request_limit" {
return o.batchRequestLimit
}
if k == "evm.batch_response_max_size" {
return o.batchResponseMaxSize
}
panic("unknown key")
}

Expand Down Expand Up @@ -200,6 +208,8 @@ func getDefaultOpts() opts {
1000,
200.0,
400,
1000,
25 * 1000 * 1000,
}
}

Expand Down Expand Up @@ -326,6 +336,17 @@ func TestReadConfig(t *testing.T) {
_, err = config.ReadConfig(&badOpts)
require.NotNil(t, err)

// Test bad types for batch limit config
badOpts = goodOpts
badOpts.batchRequestLimit = "bad"
_, err = config.ReadConfig(&badOpts)
require.NotNil(t, err)

badOpts = goodOpts
badOpts.batchResponseMaxSize = "bad"
_, err = config.ReadConfig(&badOpts)
require.NotNil(t, err)

}

// Test worker pool configuration values
Expand Down Expand Up @@ -385,6 +406,23 @@ func TestReadConfigWorkerPool(t *testing.T) {
}
}

func TestReadConfigBatchLimits(t *testing.T) {
// Defaults flow through when not overridden.
cfg, err := config.ReadConfig(&opts{})
require.NoError(t, err)
require.Equal(t, config.DefaultConfig.BatchRequestLimit, cfg.BatchRequestLimit)
require.Equal(t, config.DefaultConfig.BatchResponseMaxSize, cfg.BatchResponseMaxSize)

// Custom values (including 0 to disable) flow through.
o := getDefaultOpts()
o.batchRequestLimit = 50
o.batchResponseMaxSize = 0
cfg, err = config.ReadConfig(&o)
require.NoError(t, err)
require.Equal(t, 50, cfg.BatchRequestLimit)
require.Equal(t, 0, cfg.BatchResponseMaxSize)
}

func TestReadConfigEnableParallelizedBlockTrace(t *testing.T) {
opts := getDefaultOpts()
opts.enableParallelizedBlockTrace = true
Expand Down
9 changes: 7 additions & 2 deletions evmrpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,15 @@ func NewEVMHTTPServer(
logger.Info("Disabling Test EVM APIs", "liveChainID", evmCfg.IsLiveChainID(ctx), "enableTestAPI", config.EnableTestAPI)
}

if err := httpServer.EnableRPC(apis, HTTPConfig{
httpConfig := HTTPConfig{
CorsAllowedOrigins: strings.Split(config.CORSOrigins, ","),
Vhosts: []string{"*"},
DenyList: config.DenyList,
SeiLegacyAllowlist: seiLegacyAllowlist,
}); err != nil {
}
httpConfig.batchItemLimit = config.BatchRequestLimit
httpConfig.batchResponseSizeLimit = config.BatchResponseMaxSize
if err := httpServer.EnableRPC(apis, httpConfig); err != nil {
return nil, err
}

Expand Down Expand Up @@ -329,6 +332,8 @@ func NewEVMWebSocketServer(

wsConfig := WsConfig{Origins: strings.Split(config.WSOrigins, ",")}
wsConfig.readLimit = DefaultWebsocketMaxMessageSize
wsConfig.batchItemLimit = config.BatchRequestLimit
wsConfig.batchResponseSizeLimit = config.BatchResponseMaxSize
if err := httpServer.EnableWS(apis, wsConfig); err != nil {
return nil, err
}
Expand Down
Loading