mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 01:13:45 +00:00
core/bloombits, eth/filters: handle null sub-topics on parse
This commit is contained in:
parent
b4b1f6f002
commit
87af6aeb58
8 changed files with 57 additions and 64 deletions
|
|
@ -97,6 +97,9 @@ func NewMatcher(sectionSize uint64, filters [][][]byte) *Matcher {
|
||||||
|
|
||||||
for _, filter := range filters {
|
for _, filter := range filters {
|
||||||
// Gather the bit indexes of the filter rule, special casing the nil filter
|
// Gather the bit indexes of the filter rule, special casing the nil filter
|
||||||
|
if len(filter) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
bloomBits := make([]bloomIndexes, len(filter))
|
bloomBits := make([]bloomIndexes, len(filter))
|
||||||
for i, clause := range filter {
|
for i, clause := range filter {
|
||||||
if clause == nil {
|
if clause == nil {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,9 @@ func TestMatcherWildcards(t *testing.T) {
|
||||||
[][]byte{common.Hash{0x01}.Bytes()}, // Plain rule, sanity check
|
[][]byte{common.Hash{0x01}.Bytes()}, // Plain rule, sanity check
|
||||||
[][]byte{common.Hash{0x01}.Bytes(), nil}, // Wildcard suffix, drop rule
|
[][]byte{common.Hash{0x01}.Bytes(), nil}, // Wildcard suffix, drop rule
|
||||||
[][]byte{nil, common.Hash{0x01}.Bytes()}, // Wildcard prefix, drop rule
|
[][]byte{nil, common.Hash{0x01}.Bytes()}, // Wildcard prefix, drop rule
|
||||||
[][]byte{nil, nil}, // Wildcard rule, drop rule
|
[][]byte{nil, nil}, // Wildcard combo, drop rule
|
||||||
|
[][]byte{}, // Inited wildcard rule, drop rule
|
||||||
|
nil, // Proper wildcard rule, drop rule
|
||||||
})
|
})
|
||||||
if len(matcher.filters) != 3 {
|
if len(matcher.filters) != 3 {
|
||||||
t.Fatalf("filter system size mismatch: have %d, want %d", len(matcher.filters), 3)
|
t.Fatalf("filter system size mismatch: have %d, want %d", len(matcher.filters), 3)
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ type FilterCriteria struct {
|
||||||
FromBlock *big.Int
|
FromBlock *big.Int
|
||||||
ToBlock *big.Int
|
ToBlock *big.Int
|
||||||
Addresses []common.Address
|
Addresses []common.Address
|
||||||
Topics [][]*common.Hash
|
Topics [][]common.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFilter creates a new filter and returns the filter id. It can be
|
// NewFilter creates a new filter and returns the filter id. It can be
|
||||||
|
|
@ -493,12 +493,11 @@ func (args *FilterCriteria) UnmarshalJSON(data []byte) error {
|
||||||
// topics is an array consisting of strings and/or arrays of strings.
|
// topics is an array consisting of strings and/or arrays of strings.
|
||||||
// JSON null values are converted to common.Hash{} and ignored by the filter manager.
|
// JSON null values are converted to common.Hash{} and ignored by the filter manager.
|
||||||
if len(raw.Topics) > 0 {
|
if len(raw.Topics) > 0 {
|
||||||
args.Topics = make([][]*common.Hash, len(raw.Topics))
|
args.Topics = make([][]common.Hash, len(raw.Topics))
|
||||||
for i, t := range raw.Topics {
|
for i, t := range raw.Topics {
|
||||||
switch topic := t.(type) {
|
switch topic := t.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
// ignore topic when matching logs
|
// ignore topic when matching logs
|
||||||
args.Topics[i] = []*common.Hash{nil}
|
|
||||||
|
|
||||||
case string:
|
case string:
|
||||||
// match specific topic
|
// match specific topic
|
||||||
|
|
@ -506,19 +505,22 @@ func (args *FilterCriteria) UnmarshalJSON(data []byte) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
args.Topics[i] = []*common.Hash{&top}
|
args.Topics[i] = []common.Hash{top}
|
||||||
|
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
// or case e.g. [null, "topic0", "topic1"]
|
// or case e.g. [null, "topic0", "topic1"]
|
||||||
for _, rawTopic := range topic {
|
for _, rawTopic := range topic {
|
||||||
if rawTopic == nil {
|
if rawTopic == nil {
|
||||||
args.Topics[i] = append(args.Topics[i], nil)
|
// null component, match all
|
||||||
} else if topic, ok := rawTopic.(string); ok {
|
args.Topics[i] = nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if topic, ok := rawTopic.(string); ok {
|
||||||
parsed, err := decodeTopic(topic)
|
parsed, err := decodeTopic(topic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
args.Topics[i] = append(args.Topics[i], &parsed)
|
args.Topics[i] = append(args.Topics[i], parsed)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("invalid topic(s)")
|
return fmt.Errorf("invalid topic(s)")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ func TestUnmarshalJSONNewFilterArgs(t *testing.T) {
|
||||||
if len(test4.Topics[0]) != 1 {
|
if len(test4.Topics[0]) != 1 {
|
||||||
t.Fatalf("expected len(topics[0]) to be 1, got %d", len(test4.Topics[0]))
|
t.Fatalf("expected len(topics[0]) to be 1, got %d", len(test4.Topics[0]))
|
||||||
}
|
}
|
||||||
if *test4.Topics[0][0] != topic0 {
|
if test4.Topics[0][0] != topic0 {
|
||||||
t.Fatalf("got %x, expected %x", test4.Topics[0][0], topic0)
|
t.Fatalf("got %x, expected %x", test4.Topics[0][0], topic0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,13 +124,13 @@ func TestUnmarshalJSONNewFilterArgs(t *testing.T) {
|
||||||
if len(test5.Topics[0]) != 1 {
|
if len(test5.Topics[0]) != 1 {
|
||||||
t.Fatalf("expected 1 topic, got %d", len(test5.Topics[0]))
|
t.Fatalf("expected 1 topic, got %d", len(test5.Topics[0]))
|
||||||
}
|
}
|
||||||
if *test5.Topics[0][0] != topic0 {
|
if test5.Topics[0][0] != topic0 {
|
||||||
t.Fatalf("got %x, expected %x", test5.Topics[0][0], topic0)
|
t.Fatalf("got %x, expected %x", test5.Topics[0][0], topic0)
|
||||||
}
|
}
|
||||||
if len(test5.Topics[1]) != 1 {
|
if len(test5.Topics[1]) != 1 {
|
||||||
t.Fatalf("expected 1 topic, got %d", len(test5.Topics[1]))
|
t.Fatalf("expected 1 topic, got %d", len(test5.Topics[1]))
|
||||||
}
|
}
|
||||||
if *test5.Topics[1][0] != topic1 {
|
if test5.Topics[1][0] != topic1 {
|
||||||
t.Fatalf("got %x, expected %x", test5.Topics[1][0], topic1)
|
t.Fatalf("got %x, expected %x", test5.Topics[1][0], topic1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,19 +146,16 @@ func TestUnmarshalJSONNewFilterArgs(t *testing.T) {
|
||||||
if len(test6.Topics[0]) != 1 {
|
if len(test6.Topics[0]) != 1 {
|
||||||
t.Fatalf("expected 1 topic, got %d", len(test6.Topics[0]))
|
t.Fatalf("expected 1 topic, got %d", len(test6.Topics[0]))
|
||||||
}
|
}
|
||||||
if *test6.Topics[0][0] != topic0 {
|
if test6.Topics[0][0] != topic0 {
|
||||||
t.Fatalf("got %x, expected %x", test6.Topics[0][0], topic0)
|
t.Fatalf("got %x, expected %x", test6.Topics[0][0], topic0)
|
||||||
}
|
}
|
||||||
if len(test6.Topics[1]) != 1 {
|
if len(test6.Topics[1]) != 0 {
|
||||||
t.Fatalf("expected 1 topic, got %d", len(test6.Topics[1]))
|
t.Fatalf("expected 0 topic, got %d", len(test6.Topics[1]))
|
||||||
}
|
|
||||||
if test6.Topics[1][0] != nil {
|
|
||||||
t.Fatalf("got %x, expected empty hash", test6.Topics[1][0])
|
|
||||||
}
|
}
|
||||||
if len(test6.Topics[2]) != 1 {
|
if len(test6.Topics[2]) != 1 {
|
||||||
t.Fatalf("expected 1 topic, got %d", len(test6.Topics[2]))
|
t.Fatalf("expected 1 topic, got %d", len(test6.Topics[2]))
|
||||||
}
|
}
|
||||||
if *test6.Topics[2][0] != topic2 {
|
if test6.Topics[2][0] != topic2 {
|
||||||
t.Fatalf("got %x, expected %x", test6.Topics[2][0], topic2)
|
t.Fatalf("got %x, expected %x", test6.Topics[2][0], topic2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,23 +171,15 @@ func TestUnmarshalJSONNewFilterArgs(t *testing.T) {
|
||||||
if len(test7.Topics[0]) != 2 {
|
if len(test7.Topics[0]) != 2 {
|
||||||
t.Fatalf("expected 2 topics, got %d topics", len(test7.Topics[0]))
|
t.Fatalf("expected 2 topics, got %d topics", len(test7.Topics[0]))
|
||||||
}
|
}
|
||||||
if *test7.Topics[0][0] != topic0 || *test7.Topics[0][1] != topic1 {
|
if test7.Topics[0][0] != topic0 || test7.Topics[0][1] != topic1 {
|
||||||
t.Fatalf("invalid topics expected [%x,%x], got [%x,%x]",
|
t.Fatalf("invalid topics expected [%x,%x], got [%x,%x]",
|
||||||
topic0, topic1, test7.Topics[0][0], test7.Topics[0][1],
|
topic0, topic1, test7.Topics[0][0], test7.Topics[0][1],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if len(test7.Topics[1]) != 1 {
|
if len(test7.Topics[1]) != 0 {
|
||||||
t.Fatalf("expected 1 topic, got %d topics", len(test7.Topics[1]))
|
t.Fatalf("expected 0 topic, got %d topics", len(test7.Topics[1]))
|
||||||
}
|
}
|
||||||
if test7.Topics[1][0] != nil {
|
if len(test7.Topics[2]) != 0 {
|
||||||
t.Fatalf("expected empty hash, got %x", test7.Topics[1][0])
|
t.Fatalf("expected 0 topics, got %d topics", len(test7.Topics[2]))
|
||||||
}
|
|
||||||
if len(test7.Topics[2]) != 2 {
|
|
||||||
t.Fatalf("expected 2 topics, got %d topics", len(test7.Topics[2]))
|
|
||||||
}
|
|
||||||
if *test7.Topics[2][0] != topic2 || test7.Topics[2][1] != nil {
|
|
||||||
t.Fatalf("invalid topics expected [%x,nil], got [%x,%x]",
|
|
||||||
topic2, test7.Topics[2][0], test7.Topics[2][1],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,14 +52,14 @@ type Filter struct {
|
||||||
db ethdb.Database
|
db ethdb.Database
|
||||||
begin, end int64
|
begin, end int64
|
||||||
addresses []common.Address
|
addresses []common.Address
|
||||||
topics [][]*common.Hash
|
topics [][]common.Hash
|
||||||
|
|
||||||
matcher *bloombits.Matcher
|
matcher *bloombits.Matcher
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new filter which uses a bloom filter on blocks to figure out whether
|
// New creates a new filter which uses a bloom filter on blocks to figure out whether
|
||||||
// a particular block is interesting or not.
|
// a particular block is interesting or not.
|
||||||
func New(backend Backend, begin, end int64, addresses []common.Address, topics [][]*common.Hash) *Filter {
|
func New(backend Backend, begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter {
|
||||||
// Flatten the address and topic filter clauses into a single bloombits filter
|
// Flatten the address and topic filter clauses into a single bloombits filter
|
||||||
// system. Since the bloombits are not positional, nil topics are permitted,
|
// system. Since the bloombits are not positional, nil topics are permitted,
|
||||||
// which get flattened into a nil byte slice.
|
// which get flattened into a nil byte slice.
|
||||||
|
|
@ -74,9 +74,7 @@ func New(backend Backend, begin, end int64, addresses []common.Address, topics [
|
||||||
for _, topicList := range topics {
|
for _, topicList := range topics {
|
||||||
filter := make([][]byte, len(topicList))
|
filter := make([][]byte, len(topicList))
|
||||||
for i, topic := range topicList {
|
for i, topic := range topicList {
|
||||||
if topic != nil {
|
filter[i] = topic.Bytes()
|
||||||
filter[i] = topic.Bytes()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
filters = append(filters, filter)
|
filters = append(filters, filter)
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +223,7 @@ func includes(addresses []common.Address, a common.Address) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// filterLogs creates a slice of logs matching the given criteria.
|
// filterLogs creates a slice of logs matching the given criteria.
|
||||||
func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]*common.Hash) []*types.Log {
|
func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*types.Log {
|
||||||
var ret []*types.Log
|
var ret []*types.Log
|
||||||
Logs:
|
Logs:
|
||||||
for _, log := range logs {
|
for _, log := range logs {
|
||||||
|
|
@ -243,11 +241,10 @@ Logs:
|
||||||
if len(topics) > len(log.Topics) {
|
if len(topics) > len(log.Topics) {
|
||||||
continue Logs
|
continue Logs
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, topics := range topics {
|
for i, topics := range topics {
|
||||||
var match bool
|
match := len(topics) == 0 // empty rule set == wildcard
|
||||||
for _, topic := range topics {
|
for _, topic := range topics {
|
||||||
if topic == nil || log.Topics[i] == *topic { // nil topic is a match all (wildcard)
|
if log.Topics[i] == topic {
|
||||||
match = true
|
match = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -261,7 +258,7 @@ Logs:
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func bloomFilter(bloom types.Bloom, addresses []common.Address, topics [][]*common.Hash) bool {
|
func bloomFilter(bloom types.Bloom, addresses []common.Address, topics [][]common.Hash) bool {
|
||||||
if len(addresses) > 0 {
|
if len(addresses) > 0 {
|
||||||
var included bool
|
var included bool
|
||||||
for _, addr := range addresses {
|
for _, addr := range addresses {
|
||||||
|
|
@ -276,9 +273,9 @@ func bloomFilter(bloom types.Bloom, addresses []common.Address, topics [][]*comm
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, sub := range topics {
|
for _, sub := range topics {
|
||||||
var included bool
|
included := len(sub) == 0 // empty rule set == wildcard
|
||||||
for _, topic := range sub {
|
for _, topic := range sub {
|
||||||
if topic == nil || types.BloomLookup(bloom, *topic) { // nil topic is a match all (wildcard)
|
if types.BloomLookup(bloom, topic) {
|
||||||
included = true
|
included = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -369,7 +369,7 @@ func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter logs of a single header in light client mode
|
// filter logs of a single header in light client mode
|
||||||
func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common.Address, topics [][]*common.Hash, remove bool) []*types.Log {
|
func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common.Address, topics [][]common.Hash, remove bool) []*types.Log {
|
||||||
if bloomFilter(header.Bloom, addresses, topics) {
|
if bloomFilter(header.Bloom, addresses, topics) {
|
||||||
// Get the logs of the block
|
// Get the logs of the block
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
|
|
|
||||||
|
|
@ -363,15 +363,15 @@ func TestLogFilter(t *testing.T) {
|
||||||
// match all
|
// match all
|
||||||
0: {FilterCriteria{}, allLogs, ""},
|
0: {FilterCriteria{}, allLogs, ""},
|
||||||
// match none due to no matching addresses
|
// match none due to no matching addresses
|
||||||
1: {FilterCriteria{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]*common.Hash{nil}}, []*types.Log{}, ""},
|
1: {FilterCriteria{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}}, []*types.Log{}, ""},
|
||||||
// match logs based on addresses, ignore topics
|
// match logs based on addresses, ignore topics
|
||||||
2: {FilterCriteria{Addresses: []common.Address{firstAddr}}, allLogs[:2], ""},
|
2: {FilterCriteria{Addresses: []common.Address{firstAddr}}, allLogs[:2], ""},
|
||||||
// match none due to no matching topics (match with address)
|
// match none due to no matching topics (match with address)
|
||||||
3: {FilterCriteria{Addresses: []common.Address{secondAddr}, Topics: [][]*common.Hash{{¬UsedTopic}}}, []*types.Log{}, ""},
|
3: {FilterCriteria{Addresses: []common.Address{secondAddr}, Topics: [][]common.Hash{{notUsedTopic}}}, []*types.Log{}, ""},
|
||||||
// match logs based on addresses and topics
|
// match logs based on addresses and topics
|
||||||
4: {FilterCriteria{Addresses: []common.Address{thirdAddress}, Topics: [][]*common.Hash{{&firstTopic, &secondTopic}}}, allLogs[3:5], ""},
|
4: {FilterCriteria{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, allLogs[3:5], ""},
|
||||||
// match logs based on multiple addresses and "or" topics
|
// match logs based on multiple addresses and "or" topics
|
||||||
5: {FilterCriteria{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]*common.Hash{{&firstTopic, &secondTopic}}}, allLogs[2:5], ""},
|
5: {FilterCriteria{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, allLogs[2:5], ""},
|
||||||
// logs in the pending block
|
// logs in the pending block
|
||||||
6: {FilterCriteria{Addresses: []common.Address{firstAddr}, FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, allLogs[:2], ""},
|
6: {FilterCriteria{Addresses: []common.Address{firstAddr}, FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, allLogs[:2], ""},
|
||||||
// mined logs with block num >= 2 or pending logs
|
// mined logs with block num >= 2 or pending logs
|
||||||
|
|
@ -381,11 +381,11 @@ func TestLogFilter(t *testing.T) {
|
||||||
// all "mined" logs
|
// all "mined" logs
|
||||||
9: {FilterCriteria{ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, allLogs, ""},
|
9: {FilterCriteria{ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, allLogs, ""},
|
||||||
// all "mined" logs with 1>= block num <=2 and topic secondTopic
|
// all "mined" logs with 1>= block num <=2 and topic secondTopic
|
||||||
10: {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2), Topics: [][]*common.Hash{{&secondTopic}}}, allLogs[3:4], ""},
|
10: {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2), Topics: [][]common.Hash{{secondTopic}}}, allLogs[3:4], ""},
|
||||||
// all "mined" and pending logs with topic firstTopic
|
// all "mined" and pending logs with topic firstTopic
|
||||||
11: {FilterCriteria{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), Topics: [][]*common.Hash{{&firstTopic}}}, expectedCase11, ""},
|
11: {FilterCriteria{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), Topics: [][]common.Hash{{firstTopic}}}, expectedCase11, ""},
|
||||||
// match all logs due to wildcard topic
|
// match all logs due to wildcard topic
|
||||||
12: {FilterCriteria{Topics: [][]*common.Hash{{nil}}}, allLogs[1:], ""},
|
12: {FilterCriteria{Topics: [][]common.Hash{nil}}, allLogs[1:], ""},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -461,7 +461,7 @@ func TestPendingLogsSubscription(t *testing.T) {
|
||||||
firstTopic = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
|
firstTopic = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
|
||||||
secondTopic = common.HexToHash("0x2222222222222222222222222222222222222222222222222222222222222222")
|
secondTopic = common.HexToHash("0x2222222222222222222222222222222222222222222222222222222222222222")
|
||||||
thirdTopic = common.HexToHash("0x3333333333333333333333333333333333333333333333333333333333333333")
|
thirdTopic = common.HexToHash("0x3333333333333333333333333333333333333333333333333333333333333333")
|
||||||
forthTopic = common.HexToHash("0x4444444444444444444444444444444444444444444444444444444444444444")
|
fourthTopic = common.HexToHash("0x4444444444444444444444444444444444444444444444444444444444444444")
|
||||||
notUsedTopic = common.HexToHash("0x9999999999999999999999999999999999999999999999999999999999999999")
|
notUsedTopic = common.HexToHash("0x9999999999999999999999999999999999999999999999999999999999999999")
|
||||||
|
|
||||||
allLogs = []core.PendingLogsEvent{
|
allLogs = []core.PendingLogsEvent{
|
||||||
|
|
@ -473,7 +473,7 @@ func TestPendingLogsSubscription(t *testing.T) {
|
||||||
{Logs: []*types.Log{
|
{Logs: []*types.Log{
|
||||||
{Address: thirdAddress, Topics: []common.Hash{firstTopic}, BlockNumber: 5},
|
{Address: thirdAddress, Topics: []common.Hash{firstTopic}, BlockNumber: 5},
|
||||||
{Address: thirdAddress, Topics: []common.Hash{thirdTopic}, BlockNumber: 5},
|
{Address: thirdAddress, Topics: []common.Hash{thirdTopic}, BlockNumber: 5},
|
||||||
{Address: thirdAddress, Topics: []common.Hash{forthTopic}, BlockNumber: 5},
|
{Address: thirdAddress, Topics: []common.Hash{fourthTopic}, BlockNumber: 5},
|
||||||
{Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 5},
|
{Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 5},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
@ -495,19 +495,19 @@ func TestPendingLogsSubscription(t *testing.T) {
|
||||||
// match all
|
// match all
|
||||||
{FilterCriteria{}, convertLogs(allLogs), nil, nil},
|
{FilterCriteria{}, convertLogs(allLogs), nil, nil},
|
||||||
// match none due to no matching addresses
|
// match none due to no matching addresses
|
||||||
{FilterCriteria{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]*common.Hash{nil}}, []*types.Log{}, nil, nil},
|
{FilterCriteria{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}}, []*types.Log{}, nil, nil},
|
||||||
// match logs based on addresses, ignore topics
|
// match logs based on addresses, ignore topics
|
||||||
{FilterCriteria{Addresses: []common.Address{firstAddr}}, append(convertLogs(allLogs[:2]), allLogs[5].Logs[3]), nil, nil},
|
{FilterCriteria{Addresses: []common.Address{firstAddr}}, append(convertLogs(allLogs[:2]), allLogs[5].Logs[3]), nil, nil},
|
||||||
// match none due to no matching topics (match with address)
|
// match none due to no matching topics (match with address)
|
||||||
{FilterCriteria{Addresses: []common.Address{secondAddr}, Topics: [][]*common.Hash{{¬UsedTopic}}}, []*types.Log{}, nil, nil},
|
{FilterCriteria{Addresses: []common.Address{secondAddr}, Topics: [][]common.Hash{{notUsedTopic}}}, []*types.Log{}, nil, nil},
|
||||||
// match logs based on addresses and topics
|
// match logs based on addresses and topics
|
||||||
{FilterCriteria{Addresses: []common.Address{thirdAddress}, Topics: [][]*common.Hash{{&firstTopic, &secondTopic}}}, append(convertLogs(allLogs[3:5]), allLogs[5].Logs[0]), nil, nil},
|
{FilterCriteria{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, append(convertLogs(allLogs[3:5]), allLogs[5].Logs[0]), nil, nil},
|
||||||
// match logs based on multiple addresses and "or" topics
|
// match logs based on multiple addresses and "or" topics
|
||||||
{FilterCriteria{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]*common.Hash{{&firstTopic, &secondTopic}}}, append(convertLogs(allLogs[2:5]), allLogs[5].Logs[0]), nil, nil},
|
{FilterCriteria{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, append(convertLogs(allLogs[2:5]), allLogs[5].Logs[0]), nil, nil},
|
||||||
// block numbers are ignored for filters created with New***Filter, these return all logs that match the given criteria when the state changes
|
// block numbers are ignored for filters created with New***Filter, these return all logs that match the given criteria when the state changes
|
||||||
{FilterCriteria{Addresses: []common.Address{firstAddr}, FromBlock: big.NewInt(2), ToBlock: big.NewInt(3)}, append(convertLogs(allLogs[:2]), allLogs[5].Logs[3]), nil, nil},
|
{FilterCriteria{Addresses: []common.Address{firstAddr}, FromBlock: big.NewInt(2), ToBlock: big.NewInt(3)}, append(convertLogs(allLogs[:2]), allLogs[5].Logs[3]), nil, nil},
|
||||||
// multiple pending logs, should match only 2 topics from the logs in block 5
|
// multiple pending logs, should match only 2 topics from the logs in block 5
|
||||||
{FilterCriteria{Addresses: []common.Address{thirdAddress}, Topics: [][]*common.Hash{{&firstTopic, &forthTopic}}}, []*types.Log{allLogs[5].Logs[0], allLogs[5].Logs[2]}, nil, nil},
|
{FilterCriteria{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, fourthTopic}}}, []*types.Log{allLogs[5].Logs[0], allLogs[5].Logs[2]}, nil, nil},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -185,14 +185,14 @@ func TestFilters(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filter := New(backend, 0, -1, []common.Address{addr}, [][]*common.Hash{{&hash1, &hash2, &hash3, &hash4}})
|
filter := New(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
|
||||||
|
|
||||||
logs, _ := filter.Logs(context.Background())
|
logs, _ := filter.Logs(context.Background())
|
||||||
if len(logs) != 4 {
|
if len(logs) != 4 {
|
||||||
t.Error("expected 4 log, got", len(logs))
|
t.Error("expected 4 log, got", len(logs))
|
||||||
}
|
}
|
||||||
|
|
||||||
filter = New(backend, 900, 999, []common.Address{addr}, [][]*common.Hash{{&hash3}})
|
filter = New(backend, 900, 999, []common.Address{addr}, [][]common.Hash{{hash3}})
|
||||||
logs, _ = filter.Logs(context.Background())
|
logs, _ = filter.Logs(context.Background())
|
||||||
if len(logs) != 1 {
|
if len(logs) != 1 {
|
||||||
t.Error("expected 1 log, got", len(logs))
|
t.Error("expected 1 log, got", len(logs))
|
||||||
|
|
@ -201,7 +201,7 @@ func TestFilters(t *testing.T) {
|
||||||
t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
|
t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
filter = New(backend, 990, -1, []common.Address{addr}, [][]*common.Hash{{&hash3}})
|
filter = New(backend, 990, -1, []common.Address{addr}, [][]common.Hash{{hash3}})
|
||||||
logs, _ = filter.Logs(context.Background())
|
logs, _ = filter.Logs(context.Background())
|
||||||
if len(logs) != 1 {
|
if len(logs) != 1 {
|
||||||
t.Error("expected 1 log, got", len(logs))
|
t.Error("expected 1 log, got", len(logs))
|
||||||
|
|
@ -210,7 +210,7 @@ func TestFilters(t *testing.T) {
|
||||||
t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
|
t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
filter = New(backend, 1, 10, nil, [][]*common.Hash{{&hash1, &hash2}})
|
filter = New(backend, 1, 10, nil, [][]common.Hash{{hash1, hash2}})
|
||||||
|
|
||||||
logs, _ = filter.Logs(context.Background())
|
logs, _ = filter.Logs(context.Background())
|
||||||
if len(logs) != 2 {
|
if len(logs) != 2 {
|
||||||
|
|
@ -218,7 +218,7 @@ func TestFilters(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
failHash := common.BytesToHash([]byte("fail"))
|
failHash := common.BytesToHash([]byte("fail"))
|
||||||
filter = New(backend, 0, -1, nil, [][]*common.Hash{{&failHash}})
|
filter = New(backend, 0, -1, nil, [][]common.Hash{{failHash}})
|
||||||
|
|
||||||
logs, _ = filter.Logs(context.Background())
|
logs, _ = filter.Logs(context.Background())
|
||||||
if len(logs) != 0 {
|
if len(logs) != 0 {
|
||||||
|
|
@ -233,7 +233,7 @@ func TestFilters(t *testing.T) {
|
||||||
t.Error("expected 0 log, got", len(logs))
|
t.Error("expected 0 log, got", len(logs))
|
||||||
}
|
}
|
||||||
|
|
||||||
filter = New(backend, 0, -1, nil, [][]*common.Hash{{&failHash}, {&hash1}})
|
filter = New(backend, 0, -1, nil, [][]common.Hash{{failHash}, {hash1}})
|
||||||
|
|
||||||
logs, _ = filter.Logs(context.Background())
|
logs, _ = filter.Logs(context.Background())
|
||||||
if len(logs) != 0 {
|
if len(logs) != 0 {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue