Skip to content

Commit

Permalink
queries validation and query key update
Browse files Browse the repository at this point in the history
  • Loading branch information
ettec committed Dec 9, 2024
1 parent 6dda837 commit 588a182
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 5 deletions.
61 changes: 56 additions & 5 deletions core/services/relay/evm/read/multieventtype.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package read

import (
"context"
"errors"
"fmt"
"iter"
"reflect"
"sort"
"strconv"
"strings"

Expand Down Expand Up @@ -49,6 +51,10 @@ func MultiEventTypeQuery(ctx context.Context, lp logpoller.LogPoller, eventQueri

func multiEventTypeQueryWithoutErrorWrapping(ctx context.Context, lp logpoller.LogPoller, eventQueries []EventQuery, limitAndSort query.LimitAndSort) (iter.Seq2[string, commontypes.Sequence], error) {

if err := validateEventQueries(eventQueries); err != nil {
return nil, fmt.Errorf("error validating event queries: %w", err)
}

for _, eq := range eventQueries {
if err := eq.EventBinding.validateBound(eq.Address); err != nil {
return nil, err
Expand Down Expand Up @@ -78,11 +84,7 @@ func multiEventTypeQueryWithoutErrorWrapping(ctx context.Context, lp logpoller.L

eventQuery := query.Or(allFilterExpressions...)

queryName := ""
for _, eq := range eventQueries {
queryName += eq.EventBinding.contractName + "-" + eq.Address.String() + "-" + eq.EventBinding.eventName + "-"
}
queryName = strings.TrimSuffix(queryName, "-")
queryName := createQueryName(eventQueries)

logs, err := lp.FilteredLogs(ctx, []query.Expression{eventQuery}, limitAndSort, queryName)
if err != nil {
Expand All @@ -97,6 +99,55 @@ func multiEventTypeQueryWithoutErrorWrapping(ctx context.Context, lp logpoller.L
return seqIter, nil
}

func createQueryName(eventQueries []EventQuery) string {
queryName := ""
contractToEvents := map[string][]string{}
for _, eq := range eventQueries {
contractName := eq.EventBinding.contractName + "-" + eq.Address.String()

if _, exists := contractToEvents[contractName]; !exists {
contractToEvents[contractName] = []string{}
}
contractToEvents[contractName] = append(contractToEvents[contractName], eq.EventBinding.eventName)
}

contractNames := make([]string, 0, len(contractToEvents))
for contractName := range contractToEvents {
contractNames = append(contractNames, contractName)
}

sort.Strings(contractNames)

for _, contractName := range contractNames {
queryName += contractName + "-"
for _, event := range contractToEvents[contractName] {
queryName += event + "-"
}
}

queryName = strings.TrimSuffix(queryName, "-")
return queryName
}

func validateEventQueries(eventQueries []EventQuery) error {
duplicateCheck := map[common.Hash]EventQuery{}
for _, eq := range eventQueries {
if eq.EventBinding == nil {
return errors.New("event binding is nil")
}

if eq.SequenceDataType == nil {
return errors.New("sequence data type is nil")
}

if _, exists := duplicateCheck[eq.EventBinding.hash]; exists {
return fmt.Errorf("duplicate event query for event signature %s", eq.EventBinding.hash)
}
duplicateCheck[eq.EventBinding.hash] = eq
}
return nil
}

func decodeMultiEventTypeLogsIntoSequences(ctx context.Context, logs []logpoller.Log, eventQueries []EventQuery) (iter.Seq2[string, commontypes.Sequence], error) {
type sequenceWithKey struct {
Key string
Expand Down
119 changes: 119 additions & 0 deletions core/services/relay/evm/read/multieventtype_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package read

import (
"github.com/ethereum/go-ethereum/common"

"testing"

"github.com/stretchr/testify/assert"

"github.com/smartcontractkit/chainlink-common/pkg/types/query"
)

func TestCreateQueryName(t *testing.T) {
eventQueries := []EventQuery{
{
Filter: query.KeyFilter{Key: "key1"},
EventBinding: &EventBinding{
contractName: "ContractA",
eventName: "EventA",
hash: common.HexToHash("0x1"),
},
SequenceDataType: "dataType1",
Address: common.HexToAddress("0x123"),
},
{
Filter: query.KeyFilter{Key: "key2"},
EventBinding: &EventBinding{
contractName: "ContractB",
eventName: "EventB",
hash: common.HexToHash("0x2"),
},
SequenceDataType: "dataType2",
Address: common.HexToAddress("0x456"),
},
{
Filter: query.KeyFilter{Key: "key1"},
EventBinding: &EventBinding{
contractName: "ContractA",
eventName: "EventA1",
hash: common.HexToHash("0x1"),
},
SequenceDataType: "dataType1",
Address: common.HexToAddress("0x123"),
},
}

expectedQueryName := "ContractA-0x0000000000000000000000000000000000000123-EventA-EventA1-ContractB-0x0000000000000000000000000000000000000456-EventB"
queryName := createQueryName(eventQueries)

assert.Equal(t, expectedQueryName, queryName)
}

func TestValidateEventQueries(t *testing.T) {
tests := []struct {
name string
eventQueries []EventQuery
expectedError string
}{
{
name: "valid event queries",
eventQueries: []EventQuery{
{
EventBinding: &EventBinding{hash: common.HexToHash("0x1")},
SequenceDataType: "dataType1",
},
{
EventBinding: &EventBinding{hash: common.HexToHash("0x2")},
SequenceDataType: "dataType2",
},
},
expectedError: "",
},
{
name: "nil event binding",
eventQueries: []EventQuery{
{
EventBinding: nil,
SequenceDataType: "dataType1",
},
},
expectedError: "event binding is nil",
},
{
name: "nil sequence data type",
eventQueries: []EventQuery{
{
EventBinding: &EventBinding{hash: common.HexToHash("0x1")},
SequenceDataType: nil,
},
},
expectedError: "sequence data type is nil",
},
{
name: "duplicate event query",
eventQueries: []EventQuery{
{
EventBinding: &EventBinding{hash: common.HexToHash("0x1")},
SequenceDataType: "dataType1",
},
{
EventBinding: &EventBinding{hash: common.HexToHash("0x1")},
SequenceDataType: "dataType2",
},
},
expectedError: "duplicate event query for event signature 0x0000000000000000000000000000000000000000000000000000000000000001",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateEventQueries(tt.eventQueries)
if tt.expectedError == "" {
assert.NoError(t, err)
} else {
assert.EqualError(t, err, tt.expectedError)
}
})
}
}

0 comments on commit 588a182

Please sign in to comment.