mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
feat: add eth_getLogs block range limit (#576)
* update cmd/geth/main.go * update `eth/ethconfig` package * update `eth/filters` package * update cmd/utils/flags.go * fix cmd/utils/flags.go * fix eth/filters/filter.go
This commit is contained in:
parent
fccf142288
commit
fc8e8622d3
6 changed files with 57 additions and 14 deletions
|
|
@ -176,6 +176,7 @@ var (
|
|||
utils.AllowUnprotectedTxs,
|
||||
utils.BatchRequestLimit,
|
||||
utils.BatchResponseMaxSize,
|
||||
utils.MaxBlockRangeFlag,
|
||||
}
|
||||
|
||||
metricsFlags = []cli.Flag{
|
||||
|
|
|
|||
|
|
@ -944,6 +944,13 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
|
|||
Value: metrics.DefaultConfig.InfluxDBOrganization,
|
||||
Category: flags.MetricsCategory,
|
||||
}
|
||||
|
||||
|
||||
// Max block range for `eth_getLogs` method
|
||||
MaxBlockRangeFlag = &cli.Int64Flag{
|
||||
Name: "rpc.getlogs.maxrange",
|
||||
Usage: "Limit max fetched block range for `eth_getLogs` method",
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -1605,6 +1612,14 @@ func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) {
|
|||
}
|
||||
}
|
||||
|
||||
func setMaxBlockRange(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||
if ctx.IsSet(MaxBlockRangeFlag.Name) {
|
||||
cfg.MaxBlockRange = ctx.Int64(MaxBlockRangeFlag.Name)
|
||||
} else {
|
||||
cfg.MaxBlockRange = -1
|
||||
}
|
||||
}
|
||||
|
||||
// CheckExclusive verifies that only a single instance of the provided flags was
|
||||
// set by the user. Each flag might optionally be followed by a string type to
|
||||
// specialize it further.
|
||||
|
|
@ -1660,6 +1675,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||
setMiner(ctx, &cfg.Miner)
|
||||
setRequiredBlocks(ctx, cfg)
|
||||
setLes(ctx, cfg)
|
||||
setMaxBlockRange(ctx, cfg)
|
||||
|
||||
// Cap the cache allowance and tune the garbage collector
|
||||
mem, err := gopsutil.VirtualMemory()
|
||||
|
|
@ -1956,7 +1972,7 @@ func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconf
|
|||
})
|
||||
stack.RegisterAPIs([]rpc.API{{
|
||||
Namespace: "eth",
|
||||
Service: filters.NewFilterAPI(filterSystem, isLightClient),
|
||||
Service: filters.NewFilterAPI(filterSystem, isLightClient, ethcfg.MaxBlockRange),
|
||||
}})
|
||||
return filterSystem
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ var Defaults = Config{
|
|||
RPCGasCap: 50000000,
|
||||
RPCEVMTimeout: 5 * time.Second,
|
||||
GPO: FullNodeGPO,
|
||||
RPCTxFeeCap: 1, // 1 ether
|
||||
RPCTxFeeCap: 1, // 1 ether
|
||||
MaxBlockRange: -1, // Default unconfigured value: no block range limit for backward compatibility
|
||||
}
|
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type Config -formats toml -out gen_config.go
|
||||
|
|
@ -168,6 +169,9 @@ type Config struct {
|
|||
|
||||
// OverrideVerkle (TODO: remove after the fork)
|
||||
OverrideVerkle *uint64 `toml:",omitempty"`
|
||||
|
||||
// Max block range for eth_getLogs api method
|
||||
MaxBlockRange int64
|
||||
}
|
||||
|
||||
// CreateConsensusEngine creates a consensus engine for the given chain config.
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
|||
RPCTxFeeCap float64
|
||||
OverrideCancun *uint64 `toml:",omitempty"`
|
||||
OverrideVerkle *uint64 `toml:",omitempty"`
|
||||
MaxBlockRange int64
|
||||
}
|
||||
var enc Config
|
||||
enc.Genesis = c.Genesis
|
||||
|
|
@ -97,6 +98,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
|||
enc.RPCTxFeeCap = c.RPCTxFeeCap
|
||||
enc.OverrideCancun = c.OverrideCancun
|
||||
enc.OverrideVerkle = c.OverrideVerkle
|
||||
enc.MaxBlockRange = c.MaxBlockRange
|
||||
return &enc, nil
|
||||
}
|
||||
|
||||
|
|
@ -142,6 +144,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
|||
RPCTxFeeCap *float64
|
||||
OverrideCancun *uint64 `toml:",omitempty"`
|
||||
OverrideVerkle *uint64 `toml:",omitempty"`
|
||||
MaxBlockRange *int64
|
||||
}
|
||||
var dec Config
|
||||
if err := unmarshal(&dec); err != nil {
|
||||
|
|
@ -264,5 +267,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
|||
if dec.OverrideVerkle != nil {
|
||||
c.OverrideVerkle = dec.OverrideVerkle
|
||||
}
|
||||
if dec.MaxBlockRange != nil {
|
||||
c.MaxBlockRange = *dec.MaxBlockRange
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,20 +54,22 @@ type filter struct {
|
|||
// FilterAPI offers support to create and manage filters. This will allow external clients to retrieve various
|
||||
// information related to the Ethereum protocol such as blocks, transactions and logs.
|
||||
type FilterAPI struct {
|
||||
sys *FilterSystem
|
||||
events *EventSystem
|
||||
filtersMu sync.Mutex
|
||||
filters map[rpc.ID]*filter
|
||||
timeout time.Duration
|
||||
sys *FilterSystem
|
||||
events *EventSystem
|
||||
filtersMu sync.Mutex
|
||||
filters map[rpc.ID]*filter
|
||||
timeout time.Duration
|
||||
maxBlockRange int64
|
||||
}
|
||||
|
||||
// NewFilterAPI returns a new FilterAPI instance.
|
||||
func NewFilterAPI(system *FilterSystem, lightMode bool) *FilterAPI {
|
||||
func NewFilterAPI(system *FilterSystem, lightMode bool, maxBlockRange int64) *FilterAPI {
|
||||
api := &FilterAPI{
|
||||
sys: system,
|
||||
events: NewEventSystem(system, lightMode),
|
||||
filters: make(map[rpc.ID]*filter),
|
||||
timeout: system.cfg.Timeout,
|
||||
sys: system,
|
||||
events: NewEventSystem(system, lightMode),
|
||||
filters: make(map[rpc.ID]*filter),
|
||||
timeout: system.cfg.Timeout,
|
||||
maxBlockRange: maxBlockRange,
|
||||
}
|
||||
go api.timeoutLoop(system.cfg.Timeout)
|
||||
|
||||
|
|
@ -348,7 +350,7 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type
|
|||
end = crit.ToBlock.Int64()
|
||||
}
|
||||
// Construct the range filter
|
||||
filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics)
|
||||
filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics, api.maxBlockRange)
|
||||
}
|
||||
// Run the filter and return all the logs
|
||||
logs, err := filter.Logs(ctx)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package filters
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -38,11 +39,13 @@ type Filter struct {
|
|||
begin, end int64 // Range interval if filtering multiple blocks
|
||||
|
||||
matcher *bloombits.Matcher
|
||||
|
||||
maxBlockRange int64
|
||||
}
|
||||
|
||||
// NewRangeFilter creates a new filter which uses a bloom filter on blocks to
|
||||
// figure out whether a particular block is interesting or not.
|
||||
func (sys *FilterSystem) NewRangeFilter(begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter {
|
||||
func (sys *FilterSystem) NewRangeFilter(begin, end int64, addresses []common.Address, topics [][]common.Hash, maxBlockRange ...int64) *Filter {
|
||||
// Flatten the address and topic filter clauses into a single bloombits filter
|
||||
// system. Since the bloombits are not positional, nil topics are permitted,
|
||||
// which get flattened into a nil byte slice.
|
||||
|
|
@ -70,6 +73,12 @@ func (sys *FilterSystem) NewRangeFilter(begin, end int64, addresses []common.Add
|
|||
filter.begin = begin
|
||||
filter.end = end
|
||||
|
||||
if len(maxBlockRange) > 0 {
|
||||
filter.maxBlockRange = maxBlockRange[0]
|
||||
} else {
|
||||
filter.maxBlockRange = -1
|
||||
}
|
||||
|
||||
return filter
|
||||
}
|
||||
|
||||
|
|
@ -157,6 +166,11 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// if maxBlockRange configured then check for it
|
||||
if f.maxBlockRange != -1 && f.end-f.begin+1 > f.maxBlockRange {
|
||||
return nil, fmt.Errorf("block range is larger than max block range, block range = %d, max block range = %d", f.end-f.begin+1, f.maxBlockRange)
|
||||
}
|
||||
|
||||
logChan, errChan := f.rangeLogsAsync(ctx)
|
||||
var logs []*types.Log
|
||||
for {
|
||||
|
|
|
|||
Loading…
Reference in a new issue