Skip to content

Commit 268c577

Browse files
lupin012claude
andauthored
[3.4] rpc: add --rpc.logs.maxresults limit on log rpc-API (#19721) (cherry-pick) (#20784)
Provided configuration parameters on logs mgt that, when properly tuned by the service provider, allow the system to avoid being OOM killed: - --rpc.blockrange.limit (default changed: 0 → 1000): maximum block range (end - begin) allowed for range queries. The flag already existed but defaulted to 0 (unlimited), leaving APIs exposed to unbounded block scans. - --rpc.logs.maxresults (default: 20000): new flag — maximum number of logs returned per call. Previously unbounded. APIs affected Both limits are enforced consistently across: - eth_getLogs - erigon_getLogs - erigon_getLatestLogs - overlay_getLogs - trace_filter (block range only) Behaviour - Exceeding --rpc.blockrange.limit with an explicit fromBlock/toBlock range returns an error (query block range exceeds server limit, narrow your filter: N). - Exceeding --rpc.logs.maxresults when a query returns too many results returns an error (query returns too many logs, narrow your filter: N). - In erigon_getLatestLogs, when the caller explicitly provides logCount or blockCount that exceed the configured limits, a distinct error is returned indicating the requested value and the maximum (requested logCount/blockCount exceeds server limit: requested N, maximum M). - Setting either flag to 0 disables the respective limit (unlimited). - In erigon_getLatestLogs, when the caller explicitly provides logCount or blockCount, the block range check on fromBlock/toBlock is skipped — the count-based limit takes precedence. - The previous hardcoded constants GetLatestLogMaxLogCount (30000) and GetLatestLogMaxBlockCount (1000) have been removed in favour of the global config parameters. --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent c8ae488 commit 268c577

25 files changed

Lines changed: 192 additions & 50 deletions

cmd/rpcdaemon/cli/config.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ func RootCommand() (*cobra.Command, *httpcfg.HttpCfg) {
179179
rootCmd.PersistentFlags().IntVar(&cfg.RpcFiltersConfig.RpcSubscriptionFiltersMaxTxs, "rpc.subscription.filters.maxtxs", rpchelper.DefaultFiltersConfig.RpcSubscriptionFiltersMaxTxs, "Maximum number of transactions to store per subscription.")
180180
rootCmd.PersistentFlags().IntVar(&cfg.RpcFiltersConfig.RpcSubscriptionFiltersMaxAddresses, "rpc.subscription.filters.maxaddresses", rpchelper.DefaultFiltersConfig.RpcSubscriptionFiltersMaxAddresses, "Maximum number of addresses per subscription to filter logs by.")
181181
rootCmd.PersistentFlags().IntVar(&cfg.RpcFiltersConfig.RpcSubscriptionFiltersMaxTopics, "rpc.subscription.filters.maxtopics", rpchelper.DefaultFiltersConfig.RpcSubscriptionFiltersMaxTopics, "Maximum number of topics per subscription to filter logs by.")
182-
rootCmd.PersistentFlags().IntVar(&cfg.RangeLimit, utils.RpcBlockRangeLimit.Name, utils.RpcBlockRangeLimit.Value, utils.RpcBlockRangeLimit.Usage)
182+
rootCmd.PersistentFlags().IntVar(&cfg.BlockRangeLimit, utils.RpcBlockRangeLimit.Name, utils.RpcBlockRangeLimit.Value, utils.RpcBlockRangeLimit.Usage)
183+
rootCmd.PersistentFlags().IntVar(&cfg.GetLogsMaxResults, utils.RpcGetLogsMaxResults.Name, utils.RpcGetLogsMaxResults.Value, utils.RpcGetLogsMaxResults.Usage)
183184
rootCmd.PersistentFlags().IntVar(&cfg.BatchLimit, utils.RpcBatchLimit.Name, utils.RpcBatchLimit.Value, utils.RpcBatchLimit.Usage)
184185
rootCmd.PersistentFlags().IntVar(&cfg.ReturnDataLimit, utils.RpcReturnDataLimit.Name, utils.RpcReturnDataLimit.Value, utils.RpcReturnDataLimit.Usage)
185186
rootCmd.PersistentFlags().BoolVar(&cfg.AllowUnprotectedTxs, utils.AllowUnprotectedTxs.Name, utils.AllowUnprotectedTxs.Value, utils.AllowUnprotectedTxs.Usage)
@@ -721,6 +722,8 @@ func startRegularRpcServer(ctx context.Context, cfg *httpcfg.HttpCfg, rpcAPI []r
721722
"grpc", cfg.GRPCServerEnabled,
722723
"http", cfg.HttpServerEnabled,
723724
"ws", cfg.WebsocketEnabled,
725+
"rpc.blockrange.limit", cfg.BlockRangeLimit,
726+
"rpc.logs.maxresults", cfg.GetLogsMaxResults,
724727
}
725728

726729
if cfg.SocketServerEnabled {

cmd/rpcdaemon/cli/httpcfg/http_cfg.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ type HttpCfg struct {
5959

6060
API []string
6161
Gascap uint64
62-
RangeLimit int
62+
BlockRangeLimit int
63+
GetLogsMaxResults int
6364
Feecap float64
6465
MaxTraces uint64
6566
WebsocketPort int

cmd/utils/flags.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,12 @@ var (
407407
RpcBlockRangeLimit = cli.IntFlag{
408408
Name: "rpc.blockrange.limit",
409409
Usage: "Maximum block range (end - begin) allowed for range queries (0 = unlimited)",
410-
Value: 0,
410+
Value: 1_000,
411+
}
412+
RpcGetLogsMaxResults = cli.IntFlag{
413+
Name: "rpc.logs.maxresults",
414+
Usage: "Maximum number of logs returned by eth_getLogs, erigon_getLogs, erigon_getLatestLogs (0 = unlimited)",
415+
Value: 20_000,
411416
}
412417
RpcTraceCompatFlag = cli.BoolFlag{
413418
Name: "trace.compat",

execution/engineapi/engine_server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (e *EngineServer) Start(
140140
return nil
141141
})
142142
}
143-
base := jsonrpc.NewBaseApi(filters, stateCache, blockReader, httpConfig.WithDatadir, httpConfig.EvmCallTimeout, engineReader, httpConfig.Dirs, nil, httpConfig.RangeLimit)
143+
base := jsonrpc.NewBaseApi(filters, stateCache, blockReader, httpConfig.WithDatadir, httpConfig.EvmCallTimeout, engineReader, httpConfig.Dirs, nil, httpConfig.BlockRangeLimit, httpConfig.GetLogsMaxResults)
144144
ethImpl := jsonrpc.NewEthAPI(base, db, eth, e.txpool, mining, jsonrpc.NewEthApiConfig(httpConfig), e.logger)
145145

146146
apiList := []rpc.API{

execution/engineapi/engine_server_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func oneBlockStep(mockSentry *execmoduletester.ExecModuleTester, require *requir
6767

6868
func newBaseApiForTest(m *execmoduletester.ExecModuleTester) *jsonrpc.BaseAPI {
6969
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
70-
return jsonrpc.NewBaseApi(nil, stateCache, m.BlockReader, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs, nil, 0)
70+
return jsonrpc.NewBaseApi(nil, stateCache, m.BlockReader, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs, nil, 0, 0)
7171
}
7272

7373
func newEthApiForTest(base *jsonrpc.BaseAPI, db kv.TemporalRoDB, txPool txpoolproto.TxpoolClient) *jsonrpc.APIImpl {

node/cli/flags.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,8 @@ func setEmbeddedRpcDaemon(ctx *cli.Context, cfg *nodecfg.Config, logger log.Logg
457457
RpcSubscriptionFiltersMaxTopics: ctx.Int(RpcSubscriptionFiltersMaxTopicsFlag.Name),
458458
},
459459
Gascap: ctx.Uint64(utils.RpcGasCapFlag.Name),
460-
RangeLimit: ctx.Int(utils.RpcBlockRangeLimit.Name),
460+
BlockRangeLimit: ctx.Int(utils.RpcBlockRangeLimit.Name),
461+
GetLogsMaxResults: ctx.Int(utils.RpcGetLogsMaxResults.Name),
461462
Feecap: ctx.Float64(utils.RPCGlobalTxFeeCapFlag.Name),
462463
MaxTraces: ctx.Uint64(utils.TraceMaxtracesFlag.Name),
463464
TraceCompatibility: ctx.Bool(utils.RpcTraceCompatFlag.Name),

node/eth/backend.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,8 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
831831
backend.engine,
832832
httpRpcCfg.Dirs,
833833
backend.polygonBridge,
834-
httpRpcCfg.RangeLimit,
834+
httpRpcCfg.BlockRangeLimit,
835+
httpRpcCfg.GetLogsMaxResults,
835836
)
836837
ethApiConfig := &jsonrpc.EthApiConfig{
837838
GasCap: httpRpcCfg.Gascap,

rpc/gasprice/feehistory_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func TestFeeHistory(t *testing.T) {
8080
m := newTestBackend(t) //, big.NewInt(16), c.pending)
8181
defer m.Close()
8282

83-
baseApi := jsonrpc.NewBaseApi(nil, kvcache.NewDummy(), m.BlockReader, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs, nil, 0)
83+
baseApi := jsonrpc.NewBaseApi(nil, kvcache.NewDummy(), m.BlockReader, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs, nil, 0, 0)
8484
tx, err := m.DB.BeginTemporalRo(m.Ctx)
8585
require.NoError(t, err)
8686
defer tx.Rollback()

rpc/gasprice/gasprice_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func TestSuggestPrice(t *testing.T) {
8787
}
8888

8989
m := newTestBackend(t) //, big.NewInt(16), c.pending)
90-
baseApi := jsonrpc.NewBaseApi(nil, kvcache.NewDummy(), m.BlockReader, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs, nil, 0)
90+
baseApi := jsonrpc.NewBaseApi(nil, kvcache.NewDummy(), m.BlockReader, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs, nil, 0, 0)
9191

9292
tx, err := m.DB.BeginTemporalRo(m.Ctx)
9393
require.NoError(t, err)

rpc/jsonrpc/daemon.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func APIList(db kv.TemporalRoDB, eth rpchelper.ApiBackend, txPool txpoolproto.Tx
4949
blockReader services.FullBlockReader, cfg *httpcfg.HttpCfg, engine rules.EngineReader,
5050
logger log.Logger, bridgeReader bridgeReader, spanProducersReader spanProducersReader,
5151
) (list []rpc.API) {
52-
base := NewBaseApi(filters, stateCache, blockReader, cfg.WithDatadir, cfg.EvmCallTimeout, engine, cfg.Dirs, bridgeReader, cfg.RangeLimit)
52+
base := NewBaseApi(filters, stateCache, blockReader, cfg.WithDatadir, cfg.EvmCallTimeout, engine, cfg.Dirs, bridgeReader, cfg.BlockRangeLimit, cfg.GetLogsMaxResults)
5353
ethImpl := NewEthAPI(base, db, eth, txPool, mining, NewEthApiConfig(cfg), logger)
5454
erigonImpl := NewErigonAPI(base, db, eth)
5555
txpoolImpl := NewTxPoolAPI(base, db, txPool)

0 commit comments

Comments
 (0)