filters: add address limit to filters

This commit is contained in:
Ceyhun Onur 2025-05-22 17:17:09 +03:00
parent 20ad4f500e
commit 7ff1e9a2be
No known key found for this signature in database
GPG key ID: 60D53BEEE37F6422
4 changed files with 27 additions and 0 deletions

View file

@ -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)

View file

@ -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)
}
}

View file

@ -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

View file

@ -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 {