Skip to content

Commit

Permalink
Add tests for filter match and decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranbt committed Jan 14, 2021
1 parent 9bc4959 commit 91af917
Show file tree
Hide file tree
Showing 3 changed files with 296 additions and 5 deletions.
103 changes: 103 additions & 0 deletions api/jsonrpc/filter/filter_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,109 @@ type LogFilter struct {
Topics [][]types.Hash
}

func (l *LogFilter) addTopicSet(set ...string) error {
if l.Topics == nil {
l.Topics = [][]types.Hash{}
}
res := []types.Hash{}
for _, i := range set {
item := types.Hash{}
if err := item.UnmarshalText([]byte(i)); err != nil {
return err
}
res = append(res, item)
}
l.Topics = append(l.Topics, res)
return nil
}

func (l *LogFilter) addAddress(raw string) error {
if l.Addresses == nil {
l.Addresses = []types.Address{}
}
addr := types.Address{}
if err := addr.UnmarshalText([]byte(raw)); err != nil {
return err
}
l.Addresses = append(l.Addresses, addr)
return nil
}

func (l *LogFilter) UnmarshalJSON(data []byte) error {
var obj struct {
Address interface{} `json:"address"`
Topics []interface{} `json:"topics"`
}
if err := json.Unmarshal(data, &obj); err != nil {
return err
}

if obj.Address != nil {
// decode address, either "" or [""]
switch raw := obj.Address.(type) {
case string:
// ""
if err := l.addAddress(raw); err != nil {
return err
}

case []interface{}:
// ["", ""]
for _, addr := range raw {
if item, ok := addr.(string); ok {
if err := l.addAddress(item); err != nil {
return err
}
} else {
return fmt.Errorf("address expected")
}
}

default:
return fmt.Errorf("bad")
}
}

if obj.Topics != nil {
// decode topics, either "" or ["", ""] or null
for _, item := range obj.Topics {
switch raw := item.(type) {
case string:
// ""
if err := l.addTopicSet(raw); err != nil {
return err
}

case []interface{}:
// ["", ""]
res := []string{}
for _, i := range raw {
if item, ok := i.(string); ok {
res = append(res, item)
} else {
return fmt.Errorf("hash expected")
}
}
if err := l.addTopicSet(res...); err != nil {
return err
}

case nil:
// null
if err := l.addTopicSet(); err != nil {
return err
}

default:
return fmt.Errorf("bad")
}
}
}

// decode topics
return nil
}

// Match returns whether the receipt includes topics for this filter
func (l *LogFilter) Match(log *types.Log) bool {
// check addresses
Expand Down
188 changes: 188 additions & 0 deletions api/jsonrpc/filter/filter_manager_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package filter

import (
"reflect"
"testing"
"time"

Expand All @@ -10,8 +11,195 @@ import (
"github.com/stretchr/testify/assert"
)

var (
addr1 = types.StringToAddress("1")
addr2 = types.StringToAddress("2")

hash1 = types.StringToHash("1")
hash2 = types.StringToHash("2")
hash3 = types.StringToHash("3")
hash4 = types.StringToHash("4")
)

func TestFilterDecode(t *testing.T) {
cases := []struct {
str string
res *LogFilter
}{
{
`{}`,
&LogFilter{},
},
{
`{
"address": "1"
}`,
nil,
},
{
`{
"address": "` + addr1.String() + `"
}`,
&LogFilter{
Addresses: []types.Address{
addr1,
},
},
},
{
`{
"address": [
"` + addr1.String() + `",
"` + addr2.String() + `"
]
}`,
&LogFilter{
Addresses: []types.Address{
addr1,
addr2,
},
},
},
{
`{
"topics": [
"` + hash1.String() + `",
[
"` + hash1.String() + `"
],
[
"` + hash1.String() + `",
"` + hash2.String() + `"
],
null,
"` + hash1.String() + `"
]
}`,
&LogFilter{
Topics: [][]types.Hash{
{
hash1,
},
{
hash1,
},
{
hash1,
hash2,
},
{},
{
hash1,
},
},
},
},
}

for _, c := range cases {
res := &LogFilter{}
err := res.UnmarshalJSON([]byte(c.str))
if err != nil && c.res != nil {
t.Fatal(err)
}
if err == nil && c.res == nil {
t.Fatal("it should fail")
}
if c.res != nil {
if !reflect.DeepEqual(res, c.res) {
t.Fatal("bad")
}
}
}
}

func TestFilterMatch(t *testing.T) {
cases := []struct {
filter LogFilter
log *types.Log
match bool
}{
{
// correct, exact match
LogFilter{
Topics: [][]types.Hash{
{
hash1,
},
},
},
&types.Log{
Topics: []types.Hash{
hash1,
},
},
true,
},
{
// bad, the filter has two hashes
LogFilter{
Topics: [][]types.Hash{
{
hash1,
},
{
hash1,
},
},
},
&types.Log{
Topics: []types.Hash{
hash1,
},
},
false,
},
{
// correct, wildcard in one hash
LogFilter{
Topics: [][]types.Hash{
{},
{
hash2,
},
},
},
&types.Log{
Topics: []types.Hash{
hash1,
hash2,
},
},
true,
},
{
// correct, more topics than in filter
LogFilter{
Topics: [][]types.Hash{
{
hash1,
},
{
hash2,
},
},
},
&types.Log{
Topics: []types.Hash{
hash1,
hash2,
hash3,
},
},
true,
},
}

for indx, c := range cases {
if c.filter.Match(c.log) != c.match {
t.Fatalf("bad %d", indx)
}
}
}

func TestLogFilter(t *testing.T) {
Expand Down
10 changes: 5 additions & 5 deletions state/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,13 @@ func (t *Transition) postProcess() {
func buildLogs(logs []*types.Log, txHash, blockHash types.Hash, txIndex uint) []*types.Log {
newLogs := []*types.Log{}

for indx, log := range logs {
for _, log := range logs {
newLog := log

newLog.TxHash = txHash
newLog.BlockHash = blockHash
newLog.TxIndex = txIndex
newLog.LogIndex = uint(indx)
//newLog.TxHash = txHash
//newLog.BlockHash = blockHash
//newLog.TxIndex = txIndex
//newLog.LogIndex = uint(indx)

newLogs = append(newLogs, newLog)
}
Expand Down

0 comments on commit 91af917

Please sign in to comment.