From 7ff1e9a2beb4cdc3c179c6a491f72f9c1c8bd88c Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 22 May 2025 17:17:09 +0300 Subject: [PATCH 1/2] filters: add address limit to filters --- eth/filters/api.go | 10 ++++++++++ eth/filters/api_test.go | 12 ++++++++++++ eth/filters/filter_system.go | 3 +++ eth/filters/filter_system_test.go | 2 ++ 4 files changed, 27 insertions(+) diff --git a/eth/filters/api.go b/eth/filters/api.go index 864dfd3746d0..657f01ebd137 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -40,6 +40,7 @@ var ( errInvalidBlockRange = errors.New("invalid block range params") errPendingLogsUnsupported = errors.New("pending logs are not supported") errExceedMaxTopics = errors.New("exceed max topics") + errExceedMaxAddresses = errors.New("exceed max addresses") ) // The maximum number of topic criteria allowed, vm.LOG4 - vm.LOG0 @@ -48,6 +49,9 @@ const maxTopics = 4 // The maximum number of allowed topics within a topic criteria const maxSubTopics = 1000 +// The maximum number of addresses allowed in a filter criteria +const maxAddresses = 100 + // filter is a helper struct that holds meta information over the filter type // and associated subscription in the event system. type filter struct { @@ -341,6 +345,9 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type if len(crit.Topics) > maxTopics { return nil, errExceedMaxTopics } + if len(crit.Addresses) > maxAddresses { + return nil, errExceedMaxAddresses + } var filter *Filter if crit.BlockHash != nil { // Block filter requested, construct a single-shot filter @@ -530,6 +537,9 @@ func (args *FilterCriteria) UnmarshalJSON(data []byte) error { // raw.Address can contain a single address or an array of addresses switch rawAddr := raw.Addresses.(type) { case []interface{}: + if len(rawAddr) > maxAddresses { + return errExceedMaxAddresses + } for i, addr := range rawAddr { if strAddr, ok := addr.(string); ok { addr, err := decodeAddress(strAddr) diff --git a/eth/filters/api_test.go b/eth/filters/api_test.go index 822bc826f6b0..2eb3ee97b35a 100644 --- a/eth/filters/api_test.go +++ b/eth/filters/api_test.go @@ -19,6 +19,7 @@ package filters import ( "encoding/json" "fmt" + "strings" "testing" "github.com/ethereum/go-ethereum/common" @@ -182,4 +183,15 @@ func TestUnmarshalJSONNewFilterArgs(t *testing.T) { if len(test7.Topics[2]) != 0 { t.Fatalf("expected 0 topics, got %d topics", len(test7.Topics[2])) } + + // multiple address exceeding max + var test8 FilterCriteria + addresses := make([]string, maxAddresses+1) + for i := 0; i < maxAddresses+1; i++ { + addresses[i] = fmt.Sprintf(`"%s"`, common.HexToAddress(fmt.Sprintf("0x%x", i)).Hex()) + } + vector = fmt.Sprintf(`{"address": [%s]}`, strings.Join(addresses, ", ")) + if err := json.Unmarshal([]byte(vector), &test8); err != errExceedMaxAddresses { + t.Fatal("expected errExceedMaxAddresses, got", err) + } } diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 10e433f09bc7..787a3859ff62 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -290,6 +290,9 @@ func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*typ if len(crit.Topics) > maxTopics { return nil, errExceedMaxTopics } + if len(crit.Addresses) > maxAddresses { + return nil, errExceedMaxAddresses + } var from, to rpc.BlockNumber if crit.FromBlock == nil { from = rpc.LatestBlockNumber diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 85d4a3391317..0839312b7072 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -435,6 +435,7 @@ func TestInvalidLogFilterCreation(t *testing.T) { 1: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)}, 2: {FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(100)}, 3: {Topics: [][]common.Hash{{}, {}, {}, {}, {}}}, + 4: {Addresses: make([]common.Address, maxAddresses+1)}, } for i, test := range testCases { @@ -461,6 +462,7 @@ func TestInvalidGetLogsRequest(t *testing.T) { 1: {BlockHash: &blockHash, ToBlock: big.NewInt(500)}, 2: {BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, 3: {BlockHash: &blockHash, Topics: [][]common.Hash{{}, {}, {}, {}, {}}}, + 4: {BlockHash: &blockHash, Addresses: make([]common.Address, maxAddresses+1)}, } for i, test := range testCases { From 64d7c42c0b4848595f494398d4d9cebfd5a15cfc Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Tue, 1 Jul 2025 08:05:39 +0200 Subject: [PATCH 2/2] eth/filters: raise maxAddresses to 1000 --- eth/filters/api.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/eth/filters/api.go b/eth/filters/api.go index 657f01ebd137..f91c347b512c 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -43,14 +43,14 @@ var ( errExceedMaxAddresses = errors.New("exceed max addresses") ) -// The maximum number of topic criteria allowed, vm.LOG4 - vm.LOG0 -const maxTopics = 4 - -// The maximum number of allowed topics within a topic criteria -const maxSubTopics = 1000 - -// The maximum number of addresses allowed in a filter criteria -const maxAddresses = 100 +const ( + // The maximum number of addresses allowed in a filter criteria + maxAddresses = 1000 + // The maximum number of topic criteria allowed, vm.LOG4 - vm.LOG0 + maxTopics = 4 + // The maximum number of allowed topics within a topic criteria + maxSubTopics = 1000 +) // filter is a helper struct that holds meta information over the filter type // and associated subscription in the event system.