Skip to content

Commit

Permalink
Fix Contract Reader test case for CR DW override querying
Browse files Browse the repository at this point in the history
  • Loading branch information
ilija42 committed Oct 1, 2024
1 parent 9e4f909 commit 8be19c1
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 54 deletions.
10 changes: 7 additions & 3 deletions contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,18 @@ contract ChainReaderTester {
function triggerWithFourTopicsWithHashed(string memory field1, uint8[32] memory field2, bytes32 field3) public {
emit TriggeredWithFourTopicsWithHashed(field1, field2, field3);
}

function triggerStaticBytes(uint64 val1, uint32 val2, uint32 val3, bytes32 val4, bytes32 val5) public {

// emulate CCTP message event.
function triggerStaticBytes(uint32 val1, uint32 val2, uint32 val3, uint64 val4, bytes32 val5, bytes32 val6, bytes32 val7, bytes memory raw) public {
bytes memory _message = abi.encodePacked(
val1,
val2,
val3,
val4,
val5);
val5,
val6,
val7,
raw);
emit StaticBytes(_message);
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/Batc
batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.19/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.19/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.bin f13715b38b5b9084b08bffa571fb1c8ef686001535902e1255052f074b31ad4e
blockhash_store: ../../contracts/solc/v0.8.19/BlockhashStore/BlockhashStore.abi ../../contracts/solc/v0.8.19/BlockhashStore/BlockhashStore.bin 31b118f9577240c8834c35f8b5a1440e82a6ca8aea702970de2601824b6ab0e1
chain_module_base: ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin 7a82cc28014761090185c2650239ad01a0901181f1b2b899b42ca293bcda3741
chain_reader_tester: ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.abi ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.bin f703da84f73e8334a8a28e9efd37b0674b25d6ebf5c879614ccc552174d71b35
chain_reader_tester: ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.abi ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.bin 21fcc5fae2a95ce11590bcfc9ea2bde5ad9158f8dcb4efce7264492f8ad2b0a6
chain_specific_util_helper: ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.abi ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.bin 66eb30b0717fefe05672df5ec863c0b9a5a654623c4757307a2726d8f31e26b1
counter: ../../contracts/solc/v0.8.6/Counter/Counter.abi ../../contracts/solc/v0.8.6/Counter/Counter.bin 6ca06e000e8423573ffa0bdfda749d88236ab3da2a4cbb4a868c706da90488c9
cron_upkeep_factory_wrapper: ../../contracts/solc/v0.8.6/CronUpkeepFactory/CronUpkeepFactory.abi - dacb0f8cdf54ae9d2781c5e720fc314b32ed5e58eddccff512c75d6067292cd7
Expand Down
6 changes: 3 additions & 3 deletions core/services/relay/evm/chain_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,16 +401,16 @@ func (cr *chainReader) constructDWDetails(cfgDWsDetail map[string]types.DataWord
// if dw detail isn't set, the index can't be programmatically determined, so we get index and type from cfg
for genericName, cfgDWDetail := range cfgDWsDetail {
dwDetail, exists := dWsDetail[genericName]
if exists && cfgDWDetail.Index != 0 {
if exists && cfgDWDetail.Index != nil {
return nil, fmt.Errorf("data word detail: %q index: %q was calculated automatically and shouldn't be manully overriden by cfg", genericName, dwDetail.Index)
}

if cfgDWDetail.Index != 0 {
if cfgDWDetail.Index != nil {
abiTyp, err := abi.NewType(cfgDWDetail.Type, "", nil)
if err != nil {
return nil, fmt.Errorf("bad abi type: %q provided for data word: %q in config", dwDetail.Type, genericName)
}
dWsDetail[genericName] = read.DataWordDetail{Argument: abi.Argument{Type: abiTyp}, Index: cfgDWDetail.Index}
dWsDetail[genericName] = read.DataWordDetail{Argument: abi.Argument{Type: abiTyp}, Index: *cfgDWDetail.Index}
}
}
return dWsDetail, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types"
. "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with .
"github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"

"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
Expand Down Expand Up @@ -156,10 +157,10 @@ func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) {
ReadType: types.Event,
EventDefinitions: &types.EventDefinitions{
GenericDataWordDetails: map[string]types.DataWordDetail{
"val1": {
Name: "val1",
Index: 5,
Type: "uint64",
"msgTransmitterEvent": {
Name: "msgTransmitterEvent",
Index: testutils.Ptr(2),
Type: "bytes32",
},
},
},
Expand Down
103 changes: 71 additions & 32 deletions core/services/relay/evm/evmtesting/run_tests.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package evmtesting

import (
"encoding/binary"
"math/big"
"reflect"
"time"
Expand Down Expand Up @@ -221,24 +222,49 @@ func RunContractReaderInLoopTests[T TestingT[T]](t T, it ChainComponentsInterfac
return err == nil && len(sequences) == 1 && reflect.DeepEqual(&ts2, sequences[0].Data)
}, it.MaxWaitTimeForEvents(), time.Millisecond*10)
})
// TODO fix test case
//t.Run("Filtering can be done on data words using value comparators on fields that require manual index input", func(t T) {
// val1 := 1
// var res []byte
//
// triggerStaticBytes(t, it, uint64(val1), 29, 43, [32]byte{95}, [32]byte{67})
// assert.Eventually(t, func() bool {
// sequences, err := cr.QueryKey(ctx, boundContract, query.KeyFilter{Key: staticBytesEventName, Expressions: []query.Expression{
// query.Comparator("val1",
// primitives.ValueComparator{
// Value: val1,
// Operator: primitives.Eq,
// }),
// },
// }, query.LimitAndSort{}, res)
// return err == nil && len(sequences) == 1 && reflect.DeepEqual(1, sequences[0].Data)
// }, it.MaxWaitTimeForEvents(), time.Millisecond*10)
//})

t.Run("Filtering can be done on data words using value comparators on fields that require manual index input", func(t T) {
empty12Bytes := [12]byte{}
val1, val2, val3, val4 := uint32(1), uint32(2), uint32(3), uint64(4)
val5, val6, val7 := [32]byte{}, [32]byte{6}, [32]byte{7}
copy(val5[:], append(empty12Bytes[:], 5))
raw := []byte{9, 8}

var buf []byte
buf = binary.BigEndian.AppendUint32(buf, val1)
buf = binary.BigEndian.AppendUint32(buf, val2)
buf = binary.BigEndian.AppendUint32(buf, val3)
buf = binary.BigEndian.AppendUint64(buf, val4)
dataWordOnChainValueToQuery := append(buf[:])

resExpected := append(buf, common.LeftPadBytes(val5[:], 32)...)
resExpected = append(resExpected, common.LeftPadBytes(val6[:], 32)...)
resExpected = append(resExpected, common.LeftPadBytes(val7[:], 32)...)
resExpected = append(resExpected, raw...)

type eventResAsStruct struct {
Message *[]uint8
}
wrapExpectedRes := eventResAsStruct{Message: &resExpected}

// emit the one we want to search for and a couple of random ones to confirm that filtering works
triggerStaticBytes(t, it, val1, val2, val3, val4, val5, val6, val7, raw)
triggerStaticBytes(t, it, 1337, 7331, 4747, val4, val5, val6, val7, raw)
triggerStaticBytes(t, it, 7331, 4747, 1337, val4, val5, val6, val7, raw)
triggerStaticBytes(t, it, 4747, 1337, 7331, val4, val5, val6, val7, raw)

assert.Eventually(t, func() bool {
sequences, err := cr.QueryKey(ctx, boundContract, query.KeyFilter{Key: staticBytesEventName, Expressions: []query.Expression{
query.Comparator("msgTransmitterEvent",
primitives.ValueComparator{
Value: dataWordOnChainValueToQuery,
Operator: primitives.Eq,
}),
},
}, query.LimitAndSort{}, eventResAsStruct{})
return err == nil && len(sequences) == 1 && reflect.DeepEqual(wrapExpectedRes, sequences[0].Data)
}, it.MaxWaitTimeForEvents(), time.Millisecond*10)
})
}

func triggerFourTopics[T TestingT[T]](t T, it *EVMChainComponentsInterfaceTester[T], i1, i2, i3 int32) {
Expand All @@ -261,17 +287,30 @@ func triggerFourTopicsWithHashed[T TestingT[T]](t T, it *EVMChainComponentsInter
SubmitTransactionToCW(t, it, "triggerWithFourTopicsWithHashed", DynamicEvent{Field1: i1, Field2: i2, Field3: i3}, contracts[0], types.Unconfirmed)
}

// TODO
//func triggerStaticBytes[T TestingT[T]](t T, it ChainComponentsInterfaceTester[T], val1 uint64, val2, val3 uint32, val4, val5 [32]byte) {
// type StaticBytesEvent struct {
// Val1 uint64
// Val2 uint32
// Val3 uint32
// Val4 [32]byte
// Val5 [32]byte
// }
//
// contracts := it.GetBindings(t)
//
// SubmitTransactionToCW(t, it, "triggerStaticBytes", StaticBytesEvent{Val1: val1, Val2: val2, Val3: val3, Val4: val4, Val5: val5}, contracts[0], types.Unconfirmed)
//}
// triggerStaticBytes emits a staticBytes events and returns the expected event bytes.
func triggerStaticBytes[T TestingT[T]](t T, it ChainComponentsInterfaceTester[T], val1, val2, val3 uint32, val4 uint64, val5, val6, val7 [32]byte, raw []byte) {
type StaticBytesEvent struct {
Val1 uint32
Val2 uint32
Val3 uint32
Val4 uint64
Val5 [32]byte
Val6 [32]byte
Val7 [32]byte
Raw []byte
}

contracts := it.GetBindings(t)
SubmitTransactionToCW(t, it, "triggerStaticBytes",
StaticBytesEvent{
Val1: val1,
Val2: val2,
Val3: val3,
Val4: val4,
Val5: val5,
Val6: val6,
Val7: val7,
Raw: raw,
},
contracts[0], types.Unconfirmed)
}
4 changes: 2 additions & 2 deletions core/services/relay/evm/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ type ChainCodecConfig struct {

type DataWordDetail struct {
Name string `json:"name"`
// Index should be only used as an override in specific edge case scenarios where the index can't be programatically calculated, otherwise leave this empty.
Index int `json:"index,omitempty"`
// Index is indexed from 0. Index should only be used as an override in specific edge case scenarios where the index can't be programmatically calculated, otherwise leave this as nil.
Index *int `json:"index,omitempty"`
// Type should follow the geth ABI types naming convention
Type string `json:"type,omitempty"`
}
Expand Down

0 comments on commit 8be19c1

Please sign in to comment.