diff --git a/.changeset/fair-swans-accept.md b/.changeset/fair-swans-accept.md new file mode 100644 index 00000000000..dd834aa2d80 --- /dev/null +++ b/.changeset/fair-swans-accept.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal Add support for data word detail manual input in Contract Reader for searching through EVM log event data with Contract Reader QueryKey ValueComparators. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a01f510448c..0a546eaf652 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -18,7 +18,7 @@ # To be deprecated in Chainlink V3 /core/services/fluxmonitorv2 @smartcontractkit/foundations -/core/services/job @smartcontractkit/ccip +/core/services/job @smartcontractkit/foundations /core/services/keystore @smartcontractkit/foundations /core/services/ocr* @smartcontractkit/foundations /core/services/periodicbackup @smartcontractkit/foundations diff --git a/.gitignore b/.gitignore index 04ec46de734..38a82dbea7c 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,8 @@ race.* golangci-lint-output.txt /golangci-lint/ .covdata +core/services/job/testdata/wasm/testmodule.wasm +core/services/job/testdata/wasm/testmodule.br # DB state ./db/ diff --git a/contracts/.changeset/funny-meals-remember.md b/contracts/.changeset/funny-meals-remember.md new file mode 100644 index 00000000000..cb40a347e45 --- /dev/null +++ b/contracts/.changeset/funny-meals-remember.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': minor +--- + +#internal Modify Contract Reader tester helper BCFR-912 diff --git a/contracts/src/v0.8/automation/testhelpers/LogUpkeepCounter.sol b/contracts/src/v0.8/automation/testhelpers/LogUpkeepCounter.sol index a51f2d2af1a..8f7fa4643dd 100644 --- a/contracts/src/v0.8/automation/testhelpers/LogUpkeepCounter.sol +++ b/contracts/src/v0.8/automation/testhelpers/LogUpkeepCounter.sol @@ -31,6 +31,7 @@ contract LogUpkeepCounter is ILogAutomation { uint256 public previousPerformBlock; uint256 public initialBlock; uint256 public counter; + bool public autoExecution; constructor(uint256 _testRange) { testRange = _testRange; @@ -38,6 +39,7 @@ contract LogUpkeepCounter is ILogAutomation { lastBlock = block.number; initialBlock = 0; counter = 0; + autoExecution = true; } function start() public { @@ -65,16 +67,18 @@ contract LogUpkeepCounter is ILogAutomation { counter = counter + 1; previousPerformBlock = lastBlock; Log memory log = abi.decode(performData, (Log)); - if (log.topics[0] == sig1) { - emit Trigger(); - } else if (log.topics[0] == sig2) { - emit Trigger(1); - } else if (log.topics[0] == sig3) { - emit Trigger(1, 2); - } else if (log.topics[0] == sig4) { - emit Trigger(1, 2, 3); - } else { - revert("could not find matching sig"); + if (autoExecution) { + if (log.topics[0] == sig1) { + emit Trigger(); + } else if (log.topics[0] == sig2) { + emit Trigger(1); + } else if (log.topics[0] == sig3) { + emit Trigger(1, 2); + } else if (log.topics[0] == sig4) { + emit Trigger(1, 2, 3); + } else { + revert("could not find matching sig"); + } } emit PerformingUpkeep(tx.origin, initialBlock, lastBlock, previousPerformBlock, counter); } @@ -92,4 +96,8 @@ contract LogUpkeepCounter is ILogAutomation { initialBlock = 0; counter = 0; } + + function setAuto(bool _auto) external { + autoExecution = _auto; + } } diff --git a/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol b/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol index 2ca192e9fed..4dd9fe9c747 100644 --- a/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol +++ b/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol @@ -55,6 +55,9 @@ contract ChainReaderTester { // first topic is event hash, second and third topics get hashed before getting stored event TriggeredWithFourTopicsWithHashed(string indexed field1, uint8[32] indexed field2, bytes32 indexed field3); + // emits dynamic bytes which encode data in the same way every time. + event StaticBytes(bytes message); + TestStruct[] private s_seen; uint64[] private s_arr; uint64 private s_value; @@ -181,4 +184,19 @@ contract ChainReaderTester { function triggerWithFourTopicsWithHashed(string memory field1, uint8[32] memory field2, bytes32 field3) public { emit TriggeredWithFourTopicsWithHashed(field1, field2, field3); } + + // 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, val6, val7, raw); + emit StaticBytes(_message); + } } diff --git a/core/capabilities/triggers/logevent/service.go b/core/capabilities/triggers/logevent/service.go index 52e56d991f9..8a59865e3f5 100644 --- a/core/capabilities/triggers/logevent/service.go +++ b/core/capabilities/triggers/logevent/service.go @@ -40,6 +40,7 @@ type Config struct { Network string `json:"network"` LookbackBlocks uint64 `json:"lookbakBlocks"` PollPeriod uint32 `json:"pollPeriod"` + QueryCount uint64 `json:"queryCount"` } func (config Config) Version(capabilityVersion string) string { diff --git a/core/capabilities/triggers/logevent/trigger.go b/core/capabilities/triggers/logevent/trigger.go index 379d9483c24..1ce8ee5fd78 100644 --- a/core/capabilities/triggers/logevent/trigger.go +++ b/core/capabilities/triggers/logevent/trigger.go @@ -84,6 +84,10 @@ func newLogEventTrigger(ctx context.Context, callbackCh := make(chan capabilities.TriggerResponse, defaultSendChannelBufferSize) ticker := time.NewTicker(time.Duration(logEventConfig.PollPeriod) * time.Millisecond) + if logEventConfig.QueryCount == 0 { + logEventConfig.QueryCount = 20 + } + // Initialise a Log Event Trigger l := &logEventTrigger{ ch: callbackCh, @@ -120,6 +124,7 @@ func (l *logEventTrigger) listen() { cursor := "" limitAndSort := query.LimitAndSort{ SortBy: []query.SortBy{query.NewSortByTimestamp(query.Asc)}, + Limit: query.Limit{Count: l.logEventConfig.QueryCount}, } for { select { @@ -134,7 +139,7 @@ func (l *logEventTrigger) listen() { "startBlockNum", l.startBlockNum, "cursor", cursor) if cursor != "" { - limitAndSort.Limit = query.Limit{Cursor: cursor} + limitAndSort.Limit = query.CursorLimit(cursor, query.CursorFollowing, l.logEventConfig.QueryCount) } logs, err = l.contractReader.QueryKey( ctx, diff --git a/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go b/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go index 16b8b1d1aad..2c3fa717bc0 100644 --- a/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go +++ b/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go @@ -63,8 +63,8 @@ type TestStruct struct { } var ChainReaderTesterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"nestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"nestedStaticStruct\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"}],\"name\":\"Triggered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"fieldHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"TriggeredEventWithDynamicTopic\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"TriggeredWithFourTopics\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"field1\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint8[32]\",\"name\":\"field2\",\"type\":\"uint8[32]\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"field3\",\"type\":\"bytes32\"}],\"name\":\"TriggeredWithFourTopicsWithHashed\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"nestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"nestedStaticStruct\",\"type\":\"tuple\"}],\"name\":\"addTestStruct\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAlterablePrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDifferentPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"getElementAtIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"NestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"NestedStaticStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSliceValue\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"nestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"nestedStaticStruct\",\"type\":\"tuple\"}],\"name\":\"returnSeen\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"NestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"NestedStaticStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"value\",\"type\":\"uint64\"}],\"name\":\"setAlterablePrimitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"nestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"nestedStaticStruct\",\"type\":\"tuple\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"}],\"name\":\"triggerEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"triggerEventWithDynamicTopic\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"triggerWithFourTopics\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field1\",\"type\":\"string\"},{\"internalType\":\"uint8[32]\",\"name\":\"field2\",\"type\":\"uint8[32]\"},{\"internalType\":\"bytes32\",\"name\":\"field3\",\"type\":\"bytes32\"}],\"name\":\"triggerWithFourTopicsWithHashed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50600180548082018255600082905260048082047fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6908101805460086003958616810261010090810a8088026001600160401b0391820219909416939093179093558654808801909755848704909301805496909516909202900a918202910219909216919091179055611d9a806100a96000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80636c9a43b611610081578063dbfd73321161005b578063dbfd7332146101de578063ef4e1ced146101f1578063fbe9fbf6146101f857600080fd5b80636c9a43b614610165578063a90e1998146101ae578063ab5e0b38146101c157600080fd5b80634149667f116100b25780634149667f1461012a5780635f7104a21461013d578063679004a41461015057600080fd5b80631b48259e146100d95780632c45576f146100ee5780633272b66c14610117575b600080fd5b6100ec6100e7366004610f5d565b61020a565b005b6101016100fc366004611061565b610264565b60405161010e91906111ca565b60405180910390f35b6100ec610125366004611323565b6105bc565b610101610138366004611365565b610611565b6100ec61014b366004611365565b610731565b610158610af6565b60405161010e9190611458565b6100ec6101733660046114a6565b600280547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b6100ec6101bc3660046115da565b610b82565b6107c65b60405167ffffffffffffffff909116815260200161010e565b6100ec6101ec36600461168f565b610bdc565b60036101c5565b60025467ffffffffffffffff166101c5565b8a60030b7fae927edae02672fdcce7d7e8cf34c611ed3856914a159df5f2a59307b767c25b8b8b8b8b8b8b8b8b8b8b60405161024f9a99989796959493929190611844565b60405180910390a25050505050505050505050565b61026c610c19565b60006102796001846119c4565b81548110610289576102896119fe565b6000918252602091829020604080516101208101909152600c90920201805460030b825260018101805492939192918401916102c490611a2d565b80601f01602080910402602001604051908101604052809291908181526020018280546102f090611a2d565b801561033d5780601f106103125761010080835404028352916020019161033d565b820191906000526020600020905b81548152906001019060200180831161032057829003601f168201915b5050509183525050600282015460ff166020808301919091526040805161040081018083529190930192916003850191826000855b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161037257505050928452505050600482015473ffffffffffffffffffffffffffffffffffffffff16602080830191909152600583018054604080518285028101850182528281529401939283018282801561042b57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610400575b5050509183525050600682015460170b6020808301919091526040805180820182526007808601805460f01b7fffff0000000000000000000000000000000000000000000000000000000000001683528351808501855260088801805490930b815260098801805495909701969395919486830194919392840191906104b090611a2d565b80601f01602080910402602001604051908101604052809291908181526020018280546104dc90611a2d565b80156105295780601f106104fe57610100808354040283529160200191610529565b820191906000526020600020905b81548152906001019060200180831161050c57829003601f168201915b505050919092525050509052508152604080518082018252600a84015460f01b7fffff0000000000000000000000000000000000000000000000000000000000001681528151808301909252600b90930154600781900b825268010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1660208083019190915280840191909152015292915050565b81816040516105cc929190611a7a565b60405180910390207f3d969732b1bbbb9f1d7eb9f3f14e4cb50a74d950b3ef916a397b85dfbab93c678383604051610605929190611a8a565b60405180910390a25050565b610619610c19565b6040518061012001604052808d60030b81526020018c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8b166020808301919091526040805161040081810183529190930192918c9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff891660208083019190915260408051898302818101840183528a82529190930192918a918a91829190850190849080828437600092019190915250505090825250601786900b602082015260400161070985611a9e565b815260200161071d36859003850185611b3c565b905290505b9b9a5050505050505050505050565b60006040518061012001604052808d60030b81526020018c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8b166020808301919091526040805161040081810183529190930192918c9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff891660208083019190915260408051898302818101840183528a82529190930192918a918a91829190850190849080828437600092019190915250505090825250601786900b602082015260400161082385611a9e565b815260200161083736859003850185611b3c565b905281546001808201845560009384526020938490208351600c9093020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90931692909217825592820151919290919082019061089d9082611c1b565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560608201516108eb9060038301906020610c9b565b5060808201516004820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117905560a08201518051610952916005840191602090910190610d2e565b5060c08201516006820180547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905560e082015180516007830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660f09290921c91909117815560208083015180516008860180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff909216919091178155918101519091906009860190610a359082611c1b565b5050505061010092909201518051600a8301805460f09290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092169190911790556020908101518051600b9093018054919092015173ffffffffffffffffffffffffffffffffffffffff1668010000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090911667ffffffffffffffff90931692909217919091179055505050505050505050505050565b60606001805480602002602001604051908101604052809291908181526020018280548015610b7857602002820191906000526020600020906000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff1681526020019060080190602082600701049283019260010382029150808411610b335790505b5050505050905090565b8082604051610b919190611d35565b604051809103902084604051610ba79190611d71565b604051908190038120907f7220e4dbe4e9d0ed5f71acd022bc89c26748ac6784f2c548bc17bb8e52af34b090600090a4505050565b8060030b8260030b8460030b7f91c80dc390f3d041b3a04b0099b19634499541ea26972250986ee4b24a12fac560405160405180910390a4505050565b6040805161012081018252600080825260606020830181905292820152908101610c41610da8565b8152600060208201819052606060408301819052820152608001610c63610dc7565b8152602001610c966040805180820182526000808252825180840190935280835260208381019190915290919082015290565b905290565b600183019183908215610d1e5791602002820160005b83821115610cef57835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302610cb1565b8015610d1c5782816101000a81549060ff0219169055600101602081600001049283019260010302610cef565b505b50610d2a929150610e1a565b5090565b828054828255906000526020600020908101928215610d1e579160200282015b82811115610d1e57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610d4e565b6040518061040001604052806020906020820280368337509192915050565b604051806040016040528060007dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001610c966040518060400160405280600060070b8152602001606081525090565b5b80821115610d2a5760008155600101610e1b565b8035600381900b8114610e4157600080fd5b919050565b803560ff81168114610e4157600080fd5b600060408284031215610e6957600080fd5b50919050565b600060608284031215610e6957600080fd5b806104008101831015610e9357600080fd5b92915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610e4157600080fd5b60008083601f840112610ecf57600080fd5b50813567ffffffffffffffff811115610ee757600080fd5b6020830191508360208260051b8501011115610f0257600080fd5b9250929050565b60008083601f840112610f1b57600080fd5b50813567ffffffffffffffff811115610f3357600080fd5b602083019150836020828501011115610f0257600080fd5b8035601781900b8114610e4157600080fd5b60008060008060008060008060008060006105408c8e031215610f7f57600080fd5b610f888c610e2f565b9a50610f9660208d01610e46565b995067ffffffffffffffff8060408e01351115610fb257600080fd5b610fc28e60408f01358f01610e57565b9950610fd18e60608f01610e6f565b9850610fe08e60c08f01610e81565b9750610fef6104c08e01610e99565b9650806104e08e0135111561100357600080fd5b6110148e6104e08f01358f01610ebd565b90965094506105008d013581101561102b57600080fd5b5061103d8d6105008e01358e01610f09565b909350915061104f6105208d01610f4b565b90509295989b509295989b9093969950565b60006020828403121561107357600080fd5b5035919050565b60005b8381101561109557818101518382015260200161107d565b50506000910152565b600081518084526110b681602086016020860161107a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8060005b60208082106110fb5750611112565b825160ff16855293840193909101906001016110ec565b50505050565b600081518084526020808501945080840160005b8381101561115e57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161112c565b509495945050505050565b7fffff00000000000000000000000000000000000000000000000000000000000081511682526000602082015160406020850152805160070b604085015260208101519050604060608501526111c2608085018261109e565b949350505050565b602081526111de60208201835160030b9052565b6000602083015161054060408401526111fb61056084018261109e565b90506040840151611211606085018260ff169052565b50606084015161122460808501826110e8565b50608084015173ffffffffffffffffffffffffffffffffffffffff1661048084015260a08401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830381016104a08601526112818383611118565b925060c0860151915061129a6104c086018360170b9052565b60e0860151915080858403016104e0860152506112b78282611169565b61010086015180517fffff00000000000000000000000000000000000000000000000000000000000016610500870152602080820151805160070b610520890152015173ffffffffffffffffffffffffffffffffffffffff166105408701529092509050509392505050565b6000806020838503121561133657600080fd5b823567ffffffffffffffff81111561134d57600080fd5b61135985828601610f09565b90969095509350505050565b60008060008060008060008060008060006105408c8e03121561138757600080fd5b6113908c610e2f565b9a5067ffffffffffffffff8060208e013511156113ac57600080fd5b6113bc8e60208f01358f01610f09565b909b5099506113cd60408e01610e46565b98506113dc8e60608f01610e81565b97506113eb6104608e01610e99565b9650806104808e013511156113ff57600080fd5b6114108e6104808f01358f01610ebd565b90965094506114226104a08e01610f4b565b9350806104c08e0135111561143657600080fd5b506114488d6104c08e01358e01610e57565b915061104f8d6104e08e01610e6f565b6020808252825182820181905260009190848201906040850190845b8181101561149a57835167ffffffffffffffff1683529284019291840191600101611474565b50909695505050505050565b6000602082840312156114b857600080fd5b813567ffffffffffffffff811681146114d057600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611529576115296114d7565b60405290565b600082601f83011261154057600080fd5b813567ffffffffffffffff8082111561155b5761155b6114d7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156115a1576115a16114d7565b816040528381528660208588010111156115ba57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600061044084860312156115f057600080fd5b833567ffffffffffffffff8082111561160857600080fd5b6116148783880161152f565b94506020915086603f87011261162957600080fd5b60405161040081018181108382111715611645576116456114d7565b60405290508061042087018881111561165d57600080fd5b8388015b8181101561167f5761167281610e46565b8452928401928401611661565b5095989097509435955050505050565b6000806000606084860312156116a457600080fd5b6116ad84610e2f565b92506116bb60208501610e2f565b91506116c960408501610e2f565b90509250925092565b80357fffff00000000000000000000000000000000000000000000000000000000000081168114610e4157600080fd5b8035600781900b8114610e4157600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b7fffff000000000000000000000000000000000000000000000000000000000000611787826116d2565b16825261179660208201611702565b60070b602083015273ffffffffffffffffffffffffffffffffffffffff6117bf60408301610e99565b1660408301525050565b8060005b60208082106117dc5750611112565b60ff6117e784610e46565b1685529384019391909101906001016117cd565b8183526000602080850194508260005b8581101561115e5773ffffffffffffffffffffffffffffffffffffffff61183183610e99565b168752958201959082019060010161180b565b600061052060ff8d1683528060208401527fffff00000000000000000000000000000000000000000000000000000000000061187f8d6116d2565b16818401525060208b01357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18c36030181126118ba57600080fd5b60406105408401528b016118cd81611702565b60070b61056084015260208101357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe182360301811261190b57600080fd5b0160208101903567ffffffffffffffff81111561192757600080fd5b80360382131561193657600080fd5b604061058085015261194d6105a085018284611714565b91505061195d604084018c61175d565b61196a60a084018b6117c9565b73ffffffffffffffffffffffffffffffffffffffff89166104a08401528281036104c084015261199b81888a6117fb565b90508281036104e08401526119b1818688611714565b91505061072261050083018460170b9052565b81810381811115610e93577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c90821680611a4157607f821691505b602082108103610e69577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8183823760009101908152919050565b6020815260006111c2602083018486611714565b600060408236031215611ab057600080fd5b611ab8611506565b611ac1836116d2565b8152602083013567ffffffffffffffff80821115611ade57600080fd5b818501915060408236031215611af357600080fd5b611afb611506565b611b0483611702565b8152602083013582811115611b1857600080fd5b611b243682860161152f565b60208301525080602085015250505080915050919050565b60008183036060811215611b4f57600080fd5b611b57611506565b611b60846116d2565b815260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe083011215611b9257600080fd5b611b9a611506565b9150611ba860208501611702565b8252611bb660408501610e99565b6020830152816020820152809250505092915050565b601f821115611c1657600081815260208120601f850160051c81016020861015611bf35750805b601f850160051c820191505b81811015611c1257828155600101611bff565b5050505b505050565b815167ffffffffffffffff811115611c3557611c356114d7565b611c4981611c438454611a2d565b84611bcc565b602080601f831160018114611c9c5760008415611c665750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611c12565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015611ce957888601518255948401946001909101908401611cca565b5085821015611d2557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008183825b6020808210611d4a5750611d61565b825160ff1684529283019290910190600101611d3b565b5050506104008201905092915050565b60008251611d8381846020870161107a565b919091019291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"StaticBytes\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"nestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"nestedStaticStruct\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"}],\"name\":\"Triggered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"fieldHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"TriggeredEventWithDynamicTopic\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"TriggeredWithFourTopics\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"field1\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint8[32]\",\"name\":\"field2\",\"type\":\"uint8[32]\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"field3\",\"type\":\"bytes32\"}],\"name\":\"TriggeredWithFourTopicsWithHashed\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"nestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"nestedStaticStruct\",\"type\":\"tuple\"}],\"name\":\"addTestStruct\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAlterablePrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDifferentPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"getElementAtIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"NestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"NestedStaticStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSliceValue\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"nestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"nestedStaticStruct\",\"type\":\"tuple\"}],\"name\":\"returnSeen\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"NestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"NestedStaticStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"value\",\"type\":\"uint64\"}],\"name\":\"setAlterablePrimitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerDynamicTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelDynamicTestStruct\",\"name\":\"nestedDynamicStruct\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"address\",\"name\":\"A\",\"type\":\"address\"}],\"internalType\":\"structInnerStaticTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelStaticTestStruct\",\"name\":\"nestedStaticStruct\",\"type\":\"tuple\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"}],\"name\":\"triggerEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"triggerEventWithDynamicTopic\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"val1\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"val2\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"val3\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"val4\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"val5\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"val6\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"val7\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"raw\",\"type\":\"bytes\"}],\"name\":\"triggerStaticBytes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"triggerWithFourTopics\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field1\",\"type\":\"string\"},{\"internalType\":\"uint8[32]\",\"name\":\"field2\",\"type\":\"uint8[32]\"},{\"internalType\":\"bytes32\",\"name\":\"field3\",\"type\":\"bytes32\"}],\"name\":\"triggerWithFourTopicsWithHashed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50600180548082018255600082905260048082047fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6908101805460086003958616810261010090810a8088026001600160401b0391820219909416939093179093558654808801909755848704909301805496909516909202900a918202910219909216919091179055611fbc806100a96000396000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c8063679004a41161008c578063ab5e0b3811610066578063ab5e0b38146101df578063dbfd7332146101fc578063ef4e1ced1461020f578063fbe9fbf61461021657600080fd5b8063679004a41461016e5780636c9a43b614610183578063a90e1998146101cc57600080fd5b80634149667f116100bd5780634149667f1461013557806351f3f54d146101485780635f7104a21461015b57600080fd5b80631b48259e146100e45780632c45576f146100f95780633272b66c14610122575b600080fd5b6100f76100f2366004610fef565b610228565b005b61010c6101073660046110f3565b610282565b604051610119919061125c565b60405180910390f35b6100f76101303660046113b5565b6105da565b61010c6101433660046113f7565b61062f565b6100f7610156366004611602565b61074f565b6100f76101693660046113f7565b6107c3565b610176610b88565b60405161011991906116b3565b6100f7610191366004611701565b600280547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b6100f76101da366004611743565b610c14565b6107c65b60405167ffffffffffffffff9091168152602001610119565b6100f761020a3660046117f8565b610c6e565b60036101e3565b60025467ffffffffffffffff166101e3565b8a60030b7fae927edae02672fdcce7d7e8cf34c611ed3856914a159df5f2a59307b767c25b8b8b8b8b8b8b8b8b8b8b60405161026d9a999897969594939291906119ad565b60405180910390a25050505050505050505050565b61028a610cab565b6000610297600184611b2d565b815481106102a7576102a7611b67565b6000918252602091829020604080516101208101909152600c90920201805460030b825260018101805492939192918401916102e290611b96565b80601f016020809104026020016040519081016040528092919081815260200182805461030e90611b96565b801561035b5780601f106103305761010080835404028352916020019161035b565b820191906000526020600020905b81548152906001019060200180831161033e57829003601f168201915b5050509183525050600282015460ff166020808301919091526040805161040081018083529190930192916003850191826000855b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161039057505050928452505050600482015473ffffffffffffffffffffffffffffffffffffffff16602080830191909152600583018054604080518285028101850182528281529401939283018282801561044957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161041e575b5050509183525050600682015460170b6020808301919091526040805180820182526007808601805460f01b7fffff0000000000000000000000000000000000000000000000000000000000001683528351808501855260088801805490930b815260098801805495909701969395919486830194919392840191906104ce90611b96565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa90611b96565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b505050919092525050509052508152604080518082018252600a84015460f01b7fffff0000000000000000000000000000000000000000000000000000000000001681528151808301909252600b90930154600781900b825268010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1660208083019190915280840191909152015292915050565b81816040516105ea929190611be3565b60405180910390207f3d969732b1bbbb9f1d7eb9f3f14e4cb50a74d950b3ef916a397b85dfbab93c678383604051610623929190611bf3565b60405180910390a25050565b610637610cab565b6040518061012001604052808d60030b81526020018c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8b166020808301919091526040805161040081810183529190930192918c9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff891660208083019190915260408051898302818101840183528a82529190930192918a918a91829190850190849080828437600092019190915250505090825250601786900b602082015260400161072785611c07565b815260200161073b36859003850185611ca5565b905290505b9b9a5050505050505050505050565b60008888888888888888604051602001610770989796959493929190611d35565b60405160208183030381529060405290507f1e40927ec0bdc7319f09a53452590433ec395dec3b70b982eba779c740685bfe816040516107b09190611ddb565b60405180910390a1505050505050505050565b60006040518061012001604052808d60030b81526020018c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8b166020808301919091526040805161040081810183529190930192918c9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff891660208083019190915260408051898302818101840183528a82529190930192918a918a91829190850190849080828437600092019190915250505090825250601786900b60208201526040016108b585611c07565b81526020016108c936859003850185611ca5565b905281546001808201845560009384526020938490208351600c9093020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90931692909217825592820151919290919082019061092f9082611e3d565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055606082015161097d9060038301906020610d2d565b5060808201516004820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117905560a082015180516109e4916005840191602090910190610dc0565b5060c08201516006820180547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905560e082015180516007830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660f09290921c91909117815560208083015180516008860180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff909216919091178155918101519091906009860190610ac79082611e3d565b5050505061010092909201518051600a8301805460f09290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092169190911790556020908101518051600b9093018054919092015173ffffffffffffffffffffffffffffffffffffffff1668010000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090911667ffffffffffffffff90931692909217919091179055505050505050505050505050565b60606001805480602002602001604051908101604052809291908181526020018280548015610c0a57602002820191906000526020600020906000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff1681526020019060080190602082600701049283019260010382029150808411610bc55790505b5050505050905090565b8082604051610c239190611f57565b604051809103902084604051610c399190611f93565b604051908190038120907f7220e4dbe4e9d0ed5f71acd022bc89c26748ac6784f2c548bc17bb8e52af34b090600090a4505050565b8060030b8260030b8460030b7f91c80dc390f3d041b3a04b0099b19634499541ea26972250986ee4b24a12fac560405160405180910390a4505050565b6040805161012081018252600080825260606020830181905292820152908101610cd3610e3a565b8152600060208201819052606060408301819052820152608001610cf5610e59565b8152602001610d286040805180820182526000808252825180840190935280835260208381019190915290919082015290565b905290565b600183019183908215610db05791602002820160005b83821115610d8157835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302610d43565b8015610dae5782816101000a81549060ff0219169055600101602081600001049283019260010302610d81565b505b50610dbc929150610eac565b5090565b828054828255906000526020600020908101928215610db0579160200282015b82811115610db057825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610de0565b6040518061040001604052806020906020820280368337509192915050565b604051806040016040528060007dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001610d286040518060400160405280600060070b8152602001606081525090565b5b80821115610dbc5760008155600101610ead565b8035600381900b8114610ed357600080fd5b919050565b803560ff81168114610ed357600080fd5b600060408284031215610efb57600080fd5b50919050565b600060608284031215610efb57600080fd5b806104008101831015610f2557600080fd5b92915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ed357600080fd5b60008083601f840112610f6157600080fd5b50813567ffffffffffffffff811115610f7957600080fd5b6020830191508360208260051b8501011115610f9457600080fd5b9250929050565b60008083601f840112610fad57600080fd5b50813567ffffffffffffffff811115610fc557600080fd5b602083019150836020828501011115610f9457600080fd5b8035601781900b8114610ed357600080fd5b60008060008060008060008060008060006105408c8e03121561101157600080fd5b61101a8c610ec1565b9a5061102860208d01610ed8565b995067ffffffffffffffff8060408e0135111561104457600080fd5b6110548e60408f01358f01610ee9565b99506110638e60608f01610f01565b98506110728e60c08f01610f13565b97506110816104c08e01610f2b565b9650806104e08e0135111561109557600080fd5b6110a68e6104e08f01358f01610f4f565b90965094506105008d01358110156110bd57600080fd5b506110cf8d6105008e01358e01610f9b565b90935091506110e16105208d01610fdd565b90509295989b509295989b9093969950565b60006020828403121561110557600080fd5b5035919050565b60005b8381101561112757818101518382015260200161110f565b50506000910152565b6000815180845261114881602086016020860161110c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8060005b602080821061118d57506111a4565b825160ff168552938401939091019060010161117e565b50505050565b600081518084526020808501945080840160005b838110156111f057815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016111be565b509495945050505050565b7fffff00000000000000000000000000000000000000000000000000000000000081511682526000602082015160406020850152805160070b604085015260208101519050604060608501526112546080850182611130565b949350505050565b6020815261127060208201835160030b9052565b60006020830151610540604084015261128d610560840182611130565b905060408401516112a3606085018260ff169052565b5060608401516112b6608085018261117a565b50608084015173ffffffffffffffffffffffffffffffffffffffff1661048084015260a08401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830381016104a086015261131383836111aa565b925060c0860151915061132c6104c086018360170b9052565b60e0860151915080858403016104e08601525061134982826111fb565b61010086015180517fffff00000000000000000000000000000000000000000000000000000000000016610500870152602080820151805160070b610520890152015173ffffffffffffffffffffffffffffffffffffffff166105408701529092509050509392505050565b600080602083850312156113c857600080fd5b823567ffffffffffffffff8111156113df57600080fd5b6113eb85828601610f9b565b90969095509350505050565b60008060008060008060008060008060006105408c8e03121561141957600080fd5b6114228c610ec1565b9a5067ffffffffffffffff8060208e0135111561143e57600080fd5b61144e8e60208f01358f01610f9b565b909b50995061145f60408e01610ed8565b985061146e8e60608f01610f13565b975061147d6104608e01610f2b565b9650806104808e0135111561149157600080fd5b6114a28e6104808f01358f01610f4f565b90965094506114b46104a08e01610fdd565b9350806104c08e013511156114c857600080fd5b506114da8d6104c08e01358e01610ee9565b91506110e18d6104e08e01610f01565b803563ffffffff81168114610ed357600080fd5b803567ffffffffffffffff81168114610ed357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561156857611568611516565b60405290565b600067ffffffffffffffff8084111561158957611589611516565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156115cf576115cf611516565b816040528093508581528686860111156115e857600080fd5b858560208301376000602087830101525050509392505050565b600080600080600080600080610100898b03121561161f57600080fd5b611628896114ea565b975061163660208a016114ea565b965061164460408a016114ea565b955061165260608a016114fe565b94506080890135935060a0890135925060c0890135915060e089013567ffffffffffffffff81111561168357600080fd5b8901601f81018b1361169457600080fd5b6116a38b82356020840161156e565b9150509295985092959890939650565b6020808252825182820181905260009190848201906040850190845b818110156116f557835167ffffffffffffffff16835292840192918401916001016116cf565b50909695505050505050565b60006020828403121561171357600080fd5b61171c826114fe565b9392505050565b600082601f83011261173457600080fd5b61171c8383356020850161156e565b6000806000610440848603121561175957600080fd5b833567ffffffffffffffff8082111561177157600080fd5b61177d87838801611723565b94506020915086603f87011261179257600080fd5b604051610400810181811083821117156117ae576117ae611516565b6040529050806104208701888111156117c657600080fd5b8388015b818110156117e8576117db81610ed8565b84529284019284016117ca565b5095989097509435955050505050565b60008060006060848603121561180d57600080fd5b61181684610ec1565b925061182460208501610ec1565b915061183260408501610ec1565b90509250925092565b80357fffff00000000000000000000000000000000000000000000000000000000000081168114610ed357600080fd5b8035600781900b8114610ed357600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b7fffff0000000000000000000000000000000000000000000000000000000000006118f08261183b565b1682526118ff6020820161186b565b60070b602083015273ffffffffffffffffffffffffffffffffffffffff61192860408301610f2b565b1660408301525050565b8060005b602080821061194557506111a4565b60ff61195084610ed8565b168552938401939190910190600101611936565b8183526000602080850194508260005b858110156111f05773ffffffffffffffffffffffffffffffffffffffff61199a83610f2b565b1687529582019590820190600101611974565b600061052060ff8d1683528060208401527fffff0000000000000000000000000000000000000000000000000000000000006119e88d61183b565b16818401525060208b01357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18c3603018112611a2357600080fd5b60406105408401528b01611a368161186b565b60070b61056084015260208101357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1823603018112611a7457600080fd5b0160208101903567ffffffffffffffff811115611a9057600080fd5b803603821315611a9f57600080fd5b6040610580850152611ab66105a08501828461187d565b915050611ac6604084018c6118c6565b611ad360a084018b611932565b73ffffffffffffffffffffffffffffffffffffffff89166104a08401528281036104c0840152611b0481888a611964565b90508281036104e0840152611b1a81868861187d565b91505061074061050083018460170b9052565b81810381811115610f25577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c90821680611baa57607f821691505b602082108103610efb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8183823760009101908152919050565b60208152600061125460208301848661187d565b600060408236031215611c1957600080fd5b611c21611545565b611c2a8361183b565b8152602083013567ffffffffffffffff80821115611c4757600080fd5b818501915060408236031215611c5c57600080fd5b611c64611545565b611c6d8361186b565b8152602083013582811115611c8157600080fd5b611c8d36828601611723565b60208301525080602085015250505080915050919050565b60008183036060811215611cb857600080fd5b611cc0611545565b611cc98461183b565b815260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe083011215611cfb57600080fd5b611d03611545565b9150611d116020850161186b565b8252611d1f60408501610f2b565b6020830152816020820152809250505092915050565b60007fffffffff00000000000000000000000000000000000000000000000000000000808b60e01b168352808a60e01b166004840152808960e01b166008840152507fffffffffffffffff0000000000000000000000000000000000000000000000008760c01b16600c8301528560148301528460348301528360548301528251611dc781607485016020870161110c565b919091016074019998505050505050505050565b60208152600061171c6020830184611130565b601f821115611e3857600081815260208120601f850160051c81016020861015611e155750805b601f850160051c820191505b81811015611e3457828155600101611e21565b5050505b505050565b815167ffffffffffffffff811115611e5757611e57611516565b611e6b81611e658454611b96565b84611dee565b602080601f831160018114611ebe5760008415611e885750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611e34565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015611f0b57888601518255948401946001909101908401611eec565b5085821015611f4757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008183825b6020808210611f6c5750611f83565b825160ff1684529283019290910190600101611f5d565b5050506104008201905092915050565b60008251611fa581846020870161110c565b919091019291505056fea164736f6c6343000813000a", } var ChainReaderTesterABI = ChainReaderTesterMetaData.ABI @@ -383,6 +383,18 @@ func (_ChainReaderTester *ChainReaderTesterTransactorSession) TriggerEventWithDy return _ChainReaderTester.Contract.TriggerEventWithDynamicTopic(&_ChainReaderTester.TransactOpts, field) } +func (_ChainReaderTester *ChainReaderTesterTransactor) TriggerStaticBytes(opts *bind.TransactOpts, val1 uint32, val2 uint32, val3 uint32, val4 uint64, val5 [32]byte, val6 [32]byte, val7 [32]byte, raw []byte) (*types.Transaction, error) { + return _ChainReaderTester.contract.Transact(opts, "triggerStaticBytes", val1, val2, val3, val4, val5, val6, val7, raw) +} + +func (_ChainReaderTester *ChainReaderTesterSession) TriggerStaticBytes(val1 uint32, val2 uint32, val3 uint32, val4 uint64, val5 [32]byte, val6 [32]byte, val7 [32]byte, raw []byte) (*types.Transaction, error) { + return _ChainReaderTester.Contract.TriggerStaticBytes(&_ChainReaderTester.TransactOpts, val1, val2, val3, val4, val5, val6, val7, raw) +} + +func (_ChainReaderTester *ChainReaderTesterTransactorSession) TriggerStaticBytes(val1 uint32, val2 uint32, val3 uint32, val4 uint64, val5 [32]byte, val6 [32]byte, val7 [32]byte, raw []byte) (*types.Transaction, error) { + return _ChainReaderTester.Contract.TriggerStaticBytes(&_ChainReaderTester.TransactOpts, val1, val2, val3, val4, val5, val6, val7, raw) +} + func (_ChainReaderTester *ChainReaderTesterTransactor) TriggerWithFourTopics(opts *bind.TransactOpts, field1 int32, field2 int32, field3 int32) (*types.Transaction, error) { return _ChainReaderTester.contract.Transact(opts, "triggerWithFourTopics", field1, field2, field3) } @@ -407,6 +419,123 @@ func (_ChainReaderTester *ChainReaderTesterTransactorSession) TriggerWithFourTop return _ChainReaderTester.Contract.TriggerWithFourTopicsWithHashed(&_ChainReaderTester.TransactOpts, field1, field2, field3) } +type ChainReaderTesterStaticBytesIterator struct { + Event *ChainReaderTesterStaticBytes + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChainReaderTesterStaticBytesIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChainReaderTesterStaticBytes) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChainReaderTesterStaticBytes) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChainReaderTesterStaticBytesIterator) Error() error { + return it.fail +} + +func (it *ChainReaderTesterStaticBytesIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChainReaderTesterStaticBytes struct { + Message []byte + Raw types.Log +} + +func (_ChainReaderTester *ChainReaderTesterFilterer) FilterStaticBytes(opts *bind.FilterOpts) (*ChainReaderTesterStaticBytesIterator, error) { + + logs, sub, err := _ChainReaderTester.contract.FilterLogs(opts, "StaticBytes") + if err != nil { + return nil, err + } + return &ChainReaderTesterStaticBytesIterator{contract: _ChainReaderTester.contract, event: "StaticBytes", logs: logs, sub: sub}, nil +} + +func (_ChainReaderTester *ChainReaderTesterFilterer) WatchStaticBytes(opts *bind.WatchOpts, sink chan<- *ChainReaderTesterStaticBytes) (event.Subscription, error) { + + logs, sub, err := _ChainReaderTester.contract.WatchLogs(opts, "StaticBytes") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChainReaderTesterStaticBytes) + if err := _ChainReaderTester.contract.UnpackLog(event, "StaticBytes", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChainReaderTester *ChainReaderTesterFilterer) ParseStaticBytes(log types.Log) (*ChainReaderTesterStaticBytes, error) { + event := new(ChainReaderTesterStaticBytes) + if err := _ChainReaderTester.contract.UnpackLog(event, "StaticBytes", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type ChainReaderTesterTriggeredIterator struct { Event *ChainReaderTesterTriggered @@ -962,6 +1091,8 @@ func (_ChainReaderTester *ChainReaderTesterFilterer) ParseTriggeredWithFourTopic func (_ChainReaderTester *ChainReaderTester) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { + case _ChainReaderTester.abi.Events["StaticBytes"].ID: + return _ChainReaderTester.ParseStaticBytes(log) case _ChainReaderTester.abi.Events["Triggered"].ID: return _ChainReaderTester.ParseTriggered(log) case _ChainReaderTester.abi.Events["TriggeredEventWithDynamicTopic"].ID: @@ -976,6 +1107,10 @@ func (_ChainReaderTester *ChainReaderTester) ParseLog(log types.Log) (generated. } } +func (ChainReaderTesterStaticBytes) Topic() common.Hash { + return common.HexToHash("0x1e40927ec0bdc7319f09a53452590433ec395dec3b70b982eba779c740685bfe") +} + func (ChainReaderTesterTriggered) Topic() common.Hash { return common.HexToHash("0xae927edae02672fdcce7d7e8cf34c611ed3856914a159df5f2a59307b767c25b") } @@ -1017,10 +1152,18 @@ type ChainReaderTesterInterface interface { TriggerEventWithDynamicTopic(opts *bind.TransactOpts, field string) (*types.Transaction, error) + TriggerStaticBytes(opts *bind.TransactOpts, val1 uint32, val2 uint32, val3 uint32, val4 uint64, val5 [32]byte, val6 [32]byte, val7 [32]byte, raw []byte) (*types.Transaction, error) + TriggerWithFourTopics(opts *bind.TransactOpts, field1 int32, field2 int32, field3 int32) (*types.Transaction, error) TriggerWithFourTopicsWithHashed(opts *bind.TransactOpts, field1 string, field2 [32]uint8, field3 [32]byte) (*types.Transaction, error) + FilterStaticBytes(opts *bind.FilterOpts) (*ChainReaderTesterStaticBytesIterator, error) + + WatchStaticBytes(opts *bind.WatchOpts, sink chan<- *ChainReaderTesterStaticBytes) (event.Subscription, error) + + ParseStaticBytes(log types.Log) (*ChainReaderTesterStaticBytes, error) + FilterTriggered(opts *bind.FilterOpts, field []int32) (*ChainReaderTesterTriggeredIterator, error) WatchTriggered(opts *bind.WatchOpts, sink chan<- *ChainReaderTesterTriggered, field []int32) (event.Subscription, error) diff --git a/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go b/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go index 51b7b753cc7..e8685bc9f60 100644 --- a/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go +++ b/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go @@ -42,8 +42,8 @@ type Log struct { } var LogUpkeepCounterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lastBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"counter\",\"type\":\"uint256\"}],\"name\":\"PerformingUpkeep\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"name\":\"setSpread\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"start\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040527f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d6000557f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da6001557f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c86002557f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e716003553480156100a057600080fd5b50604051610f41380380610f418339810160408190526100bf916100da565b600455600060068190554360055560078190556008556100f3565b6000602082840312156100ec57600080fd5b5051919050565b610e3f806101026000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063806b984f11610076578063b66a261c1161005b578063b66a261c14610139578063be9a655514610156578063d832d92f1461015e57600080fd5b8063806b984f14610127578063917d895f1461013057600080fd5b80634585e33b116100a75780634585e33b1461010057806361bc221a146101155780636250a13a1461011e57600080fd5b80632cb15864146100c357806340691db4146100df575b600080fd5b6100cc60075481565b6040519081526020015b60405180910390f35b6100f26100ed366004610889565b610176565b6040516100d6929190610a7c565b61011361010e366004610817565b610365565b005b6100cc60085481565b6100cc60045481565b6100cc60055481565b6100cc60065481565b6101136101473660046109cb565b60045560006007819055600855565b6101136105d7565b6101666106b1565b60405190151581526020016100d6565b600060606101826106b1565b6101ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f7420656c696769626c65000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6000546101fd60c0860186610bca565b600081811061020e5761020e610dd4565b905060200201351480610246575060015461022c60c0860186610bca565b600081811061023d5761023d610dd4565b90506020020135145b80610276575060025461025c60c0860186610bca565b600081811061026d5761026d610dd4565b90506020020135145b806102a6575060035461028c60c0860186610bca565b600081811061029d5761029d610dd4565b90506020020135145b156102d6576001846040516020016102be9190610af9565b6040516020818303038152906040529150915061035e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f670000000000000000000000000000000000000000000000000000000000000060648201526084016101e4565b9250929050565b60075461037157436007555b43600555600854610383906001610d76565b600855600554600655600061039a828401846108f6565b90506000548160c001516000815181106103b6576103b6610dd4565b602002602001015114156103f2576040517f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d90600090a161057f565b6001548160c0015160008151811061040c5761040c610dd4565b6020026020010151141561045457604051600181527f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da906020015b60405180910390a161057f565b6002548160c0015160008151811061046e5761046e610dd4565b602002602001015114156104b3576040805160018152600260208201527f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c89101610447565b6003548160c001516000815181106104cd576104cd610dd4565b6020026020010151141561051d576040805160018152600260208201526003918101919091527f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e7190606001610447565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f636f756c64206e6f742066696e64206d61746368696e6720736967000000000060448201526064016101e4565b60075460055460065460085460408051948552602085019390935291830152606082015232907f8e8112f20a2134e18e591d2cdd68cd86a95d06e6328ede501fc6314f4a5075fa9060800160405180910390a2505050565b6040517f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d90600090a1604051600181527f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da9060200160405180910390a16040805160018152600260208201527f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c8910160405180910390a160408051600181526002602082015260038183015290517f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e719181900360600190a1565b6000600754600014156106c45750600190565b6004546007546106d49043610d8e565b10905090565b803573ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b919050565b600082601f83011261071457600080fd5b8135602067ffffffffffffffff82111561073057610730610e03565b8160051b61073f828201610c5c565b83815282810190868401838801850189101561075a57600080fd5b600093505b8584101561077d57803583526001939093019291840191840161075f565b50979650505050505050565b600082601f83011261079a57600080fd5b813567ffffffffffffffff8111156107b4576107b4610e03565b6107e560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c5c565b8181528460208386010111156107fa57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806020838503121561082a57600080fd5b823567ffffffffffffffff8082111561084257600080fd5b818501915085601f83011261085657600080fd5b81358181111561086557600080fd5b86602082850101111561087757600080fd5b60209290920196919550909350505050565b6000806040838503121561089c57600080fd5b823567ffffffffffffffff808211156108b457600080fd5b9084019061010082870312156108c957600080fd5b909250602084013590808211156108df57600080fd5b506108ec85828601610789565b9150509250929050565b60006020828403121561090857600080fd5b813567ffffffffffffffff8082111561092057600080fd5b90830190610100828603121561093557600080fd5b61093d610c32565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261097560a084016106da565b60a082015260c08301358281111561098c57600080fd5b61099887828601610703565b60c08301525060e0830135828111156109b057600080fd5b6109bc87828601610789565b60e08301525095945050505050565b6000602082840312156109dd57600080fd5b5035919050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115610a1657600080fd5b8260051b8083602087013760009401602001938452509192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b821515815260006020604081840152835180604085015260005b81811015610ab257858101830151858201606001528201610a96565b81811115610ac4576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201606001949350505050565b6020815281356020820152602082013560408201526040820135606082015260608201356080820152608082013560a082015273ffffffffffffffffffffffffffffffffffffffff610b4d60a084016106da565b1660c08201526000610b6260c0840184610cab565b6101008060e0860152610b7a610120860183856109e4565b9250610b8960e0870187610d12565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08685030182870152610bbf848483610a33565b979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610bff57600080fd5b83018035915067ffffffffffffffff821115610c1a57600080fd5b6020019150600581901b360382131561035e57600080fd5b604051610100810167ffffffffffffffff81118282101715610c5657610c56610e03565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610ca357610ca3610e03565b604052919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610ce057600080fd5b830160208101925035905067ffffffffffffffff811115610d0057600080fd5b8060051b360383131561035e57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610d4757600080fd5b830160208101925035905067ffffffffffffffff811115610d6757600080fd5b80360383131561035e57600080fd5b60008219821115610d8957610d89610da5565b500190565b600082821015610da057610da0610da5565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lastBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"counter\",\"type\":\"uint256\"}],\"name\":\"PerformingUpkeep\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"autoExecution\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_auto\",\"type\":\"bool\"}],\"name\":\"setAuto\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"name\":\"setSpread\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"start\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60806040527f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d6000557f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da6001557f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c86002557f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e716003553480156100a057600080fd5b50604051610fe5380380610fe58339810160408190526100bf916100e7565b600455600060068190554360055560078190556008556009805460ff19166001179055610100565b6000602082840312156100f957600080fd5b5051919050565b610ed68061010f6000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063806b984f11610081578063be9a65551161005b578063be9a655514610189578063cf129c7f14610191578063d832d92f146101d057600080fd5b8063806b984f1461015a578063917d895f14610163578063b66a261c1461016c57600080fd5b806353bebdf3116100b257806353bebdf31461012b57806361bc221a146101485780636250a13a1461015157600080fd5b80632cb15864146100d957806340691db4146100f55780634585e33b14610116575b600080fd5b6100e260075481565b6040519081526020015b60405180910390f35b610108610103366004610920565b6101d8565b6040516100ec929190610b13565b6101296101243660046108ae565b6103c7565b005b6009546101389060ff1681565b60405190151581526020016100ec565b6100e260085481565b6100e260045481565b6100e260055481565b6100e260065481565b61012961017a366004610a62565b60045560006007819055600855565b610129610645565b61012961019f366004610885565b600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b61013861071f565b600060606101e461071f565b61024f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f7420656c696769626c65000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60005461025f60c0860186610c61565b600081811061027057610270610e6b565b9050602002013514806102a8575060015461028e60c0860186610c61565b600081811061029f5761029f610e6b565b90506020020135145b806102d857506002546102be60c0860186610c61565b60008181106102cf576102cf610e6b565b90506020020135145b8061030857506003546102ee60c0860186610c61565b60008181106102ff576102ff610e6b565b90506020020135145b15610338576001846040516020016103209190610b90565b604051602081830303815290604052915091506103c0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f67000000000000000000000000000000000000000000000000000000000000006064820152608401610246565b9250929050565b6007546103d357436007555b436005556008546103e5906001610e0d565b60085560055460065560006103fc8284018461098d565b60095490915060ff16156105ed576000548160c0015160008151811061042457610424610e6b565b60200260200101511415610460576040517f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d90600090a16105ed565b6001548160c0015160008151811061047a5761047a610e6b565b602002602001015114156104c257604051600181527f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da906020015b60405180910390a16105ed565b6002548160c001516000815181106104dc576104dc610e6b565b60200260200101511415610521576040805160018152600260208201527f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c891016104b5565b6003548160c0015160008151811061053b5761053b610e6b565b6020026020010151141561058b576040805160018152600260208201526003918101919091527f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e71906060016104b5565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f636f756c64206e6f742066696e64206d61746368696e672073696700000000006044820152606401610246565b60075460055460065460085460408051948552602085019390935291830152606082015232907f8e8112f20a2134e18e591d2cdd68cd86a95d06e6328ede501fc6314f4a5075fa9060800160405180910390a2505050565b6040517f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d90600090a1604051600181527f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da9060200160405180910390a16040805160018152600260208201527f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c8910160405180910390a160408051600181526002602082015260038183015290517f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e719181900360600190a1565b6000600754600014156107325750600190565b6004546007546107429043610e25565b10905090565b803573ffffffffffffffffffffffffffffffffffffffff8116811461076c57600080fd5b919050565b600082601f83011261078257600080fd5b8135602067ffffffffffffffff82111561079e5761079e610e9a565b8160051b6107ad828201610cf3565b8381528281019086840183880185018910156107c857600080fd5b600093505b858410156107eb5780358352600193909301929184019184016107cd565b50979650505050505050565b600082601f83011261080857600080fd5b813567ffffffffffffffff81111561082257610822610e9a565b61085360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610cf3565b81815284602083860101111561086857600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561089757600080fd5b813580151581146108a757600080fd5b9392505050565b600080602083850312156108c157600080fd5b823567ffffffffffffffff808211156108d957600080fd5b818501915085601f8301126108ed57600080fd5b8135818111156108fc57600080fd5b86602082850101111561090e57600080fd5b60209290920196919550909350505050565b6000806040838503121561093357600080fd5b823567ffffffffffffffff8082111561094b57600080fd5b90840190610100828703121561096057600080fd5b9092506020840135908082111561097657600080fd5b50610983858286016107f7565b9150509250929050565b60006020828403121561099f57600080fd5b813567ffffffffffffffff808211156109b757600080fd5b9083019061010082860312156109cc57600080fd5b6109d4610cc9565b8235815260208301356020820152604083013560408201526060830135606082015260808301356080820152610a0c60a08401610748565b60a082015260c083013582811115610a2357600080fd5b610a2f87828601610771565b60c08301525060e083013582811115610a4757600080fd5b610a53878286016107f7565b60e08301525095945050505050565b600060208284031215610a7457600080fd5b5035919050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115610aad57600080fd5b8260051b8083602087013760009401602001938452509192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b821515815260006020604081840152835180604085015260005b81811015610b4957858101830151858201606001528201610b2d565b81811115610b5b576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201606001949350505050565b6020815281356020820152602082013560408201526040820135606082015260608201356080820152608082013560a082015273ffffffffffffffffffffffffffffffffffffffff610be460a08401610748565b1660c08201526000610bf960c0840184610d42565b6101008060e0860152610c1161012086018385610a7b565b9250610c2060e0870187610da9565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08685030182870152610c56848483610aca565b979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610c9657600080fd5b83018035915067ffffffffffffffff821115610cb157600080fd5b6020019150600581901b36038213156103c057600080fd5b604051610100810167ffffffffffffffff81118282101715610ced57610ced610e9a565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d3a57610d3a610e9a565b604052919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610d7757600080fd5b830160208101925035905067ffffffffffffffff811115610d9757600080fd5b8060051b36038313156103c057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610dde57600080fd5b830160208101925035905067ffffffffffffffff811115610dfe57600080fd5b8036038313156103c057600080fd5b60008219821115610e2057610e20610e3c565b500190565b600082821015610e3757610e37610e3c565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } var LogUpkeepCounterABI = LogUpkeepCounterMetaData.ABI @@ -182,6 +182,28 @@ func (_LogUpkeepCounter *LogUpkeepCounterTransactorRaw) Transact(opts *bind.Tran return _LogUpkeepCounter.Contract.contract.Transact(opts, method, params...) } +func (_LogUpkeepCounter *LogUpkeepCounterCaller) AutoExecution(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _LogUpkeepCounter.contract.Call(opts, &out, "autoExecution") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LogUpkeepCounter *LogUpkeepCounterSession) AutoExecution() (bool, error) { + return _LogUpkeepCounter.Contract.AutoExecution(&_LogUpkeepCounter.CallOpts) +} + +func (_LogUpkeepCounter *LogUpkeepCounterCallerSession) AutoExecution() (bool, error) { + return _LogUpkeepCounter.Contract.AutoExecution(&_LogUpkeepCounter.CallOpts) +} + func (_LogUpkeepCounter *LogUpkeepCounterCaller) CheckLog(opts *bind.CallOpts, log Log, arg1 []byte) (bool, []byte, error) { var out []interface{} err := _LogUpkeepCounter.contract.Call(opts, &out, "checkLog", log, arg1) @@ -349,6 +371,18 @@ func (_LogUpkeepCounter *LogUpkeepCounterTransactorSession) PerformUpkeep(perfor return _LogUpkeepCounter.Contract.PerformUpkeep(&_LogUpkeepCounter.TransactOpts, performData) } +func (_LogUpkeepCounter *LogUpkeepCounterTransactor) SetAuto(opts *bind.TransactOpts, _auto bool) (*types.Transaction, error) { + return _LogUpkeepCounter.contract.Transact(opts, "setAuto", _auto) +} + +func (_LogUpkeepCounter *LogUpkeepCounterSession) SetAuto(_auto bool) (*types.Transaction, error) { + return _LogUpkeepCounter.Contract.SetAuto(&_LogUpkeepCounter.TransactOpts, _auto) +} + +func (_LogUpkeepCounter *LogUpkeepCounterTransactorSession) SetAuto(_auto bool) (*types.Transaction, error) { + return _LogUpkeepCounter.Contract.SetAuto(&_LogUpkeepCounter.TransactOpts, _auto) +} + func (_LogUpkeepCounter *LogUpkeepCounterTransactor) SetSpread(opts *bind.TransactOpts, _testRange *big.Int) (*types.Transaction, error) { return _LogUpkeepCounter.contract.Transact(opts, "setSpread", _testRange) } @@ -1017,6 +1051,8 @@ func (_LogUpkeepCounter *LogUpkeepCounter) Address() common.Address { } type LogUpkeepCounterInterface interface { + AutoExecution(opts *bind.CallOpts) (bool, error) + CheckLog(opts *bind.CallOpts, log Log, arg1 []byte) (bool, []byte, error) Counter(opts *bind.CallOpts) (*big.Int, error) @@ -1033,6 +1069,8 @@ type LogUpkeepCounterInterface interface { PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) + SetAuto(opts *bind.TransactOpts, _auto bool) (*types.Transaction, error) + SetSpread(opts *bind.TransactOpts, _testRange *big.Int) (*types.Transaction, error) Start(opts *bind.TransactOpts) (*types.Transaction, error) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index b1b5a56186a..87627f7783d 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -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 b9a488fc786f584a617764d8dc1722acdb30defb6b8f638e0ae03442795eaf3e +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 @@ -54,7 +54,7 @@ keeper_registry_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistry2_1/Keep keepers_vrf_consumer: ../../contracts/solc/v0.8.6/KeepersVRFConsumer/KeepersVRFConsumer.abi ../../contracts/solc/v0.8.6/KeepersVRFConsumer/KeepersVRFConsumer.bin fa75572e689c9e84705c63e8dbe1b7b8aa1a8fe82d66356c4873d024bb9166e8 log_emitter: ../../contracts/solc/v0.8.19/LogEmitter/LogEmitter.abi ../../contracts/solc/v0.8.19/LogEmitter/LogEmitter.bin 4b129ab93432c95ff9143f0631323e189887668889e0b36ccccf18a571e41ccf log_triggered_streams_lookup_wrapper: ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup/LogTriggeredStreamsLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup/LogTriggeredStreamsLookup.bin 920fff3b662909f12ed11b47d168036ffa74ad52070a94e2fa26cdad5e428b4e -log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/LogUpkeepCounter/LogUpkeepCounter.abi ../../contracts/solc/v0.8.6/LogUpkeepCounter/LogUpkeepCounter.bin 42426bbb83f96dfbe55fc576d6c65020eaeed690e2289cf99b0c4aa810a5f4ec +log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/LogUpkeepCounter/LogUpkeepCounter.abi ../../contracts/solc/v0.8.6/LogUpkeepCounter/LogUpkeepCounter.bin 5482033d55eddb653bf580de0cc950db89a329091e085ac4122583df4a9777cd mock_aggregator_proxy: ../../contracts/solc/v0.8.6/MockAggregatorProxy/MockAggregatorProxy.abi ../../contracts/solc/v0.8.6/MockAggregatorProxy/MockAggregatorProxy.bin b16c108f3dd384c342ddff5e94da7c0a8d39d1be5e3d8f2cf61ecc7f0e50ff42 mock_ethusd_aggregator_wrapper: ../../contracts/solc/v0.8.19/MockETHUSDAggregator/MockETHUSDAggregator.abi ../../contracts/solc/v0.8.19/MockETHUSDAggregator/MockETHUSDAggregator.bin b9b361f502d2aad32311c60ca86b071de93a024ac488bcfa19725d368cd05d61 offchain_aggregator_wrapper: OffchainAggregator/OffchainAggregator.abi - 5c8d6562e94166d4790f1ee6e4321d359d9f7262e6c5452a712b1f1c896f45cf diff --git a/core/services/job/models.go b/core/services/job/models.go index 7a2f49eb49c..f4b773a1bfb 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -19,7 +19,6 @@ import ( commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" "github.com/smartcontractkit/chainlink-common/pkg/types" - pkgworkflows "github.com/smartcontractkit/chainlink-common/pkg/workflows" "github.com/smartcontractkit/chainlink/v2/core/services/relay" @@ -865,7 +864,8 @@ type WorkflowSpecType string const ( YamlSpec WorkflowSpecType = "yaml" - DefaultSpecType = YamlSpec + WASMFile WorkflowSpecType = "wasm_file" + DefaultSpecType = "" ) type WorkflowSpec struct { @@ -879,7 +879,7 @@ type WorkflowSpec struct { WorkflowName string `toml:"-" db:"workflow_name"` // Derived. Do not modify. the name of the workflow. CreatedAt time.Time `toml:"-"` UpdatedAt time.Time `toml:"-"` - SpecType WorkflowSpecType `db:"spec_type"` + SpecType WorkflowSpecType `toml:"spec_type" db:"spec_type"` sdkWorkflow *sdk.WorkflowSpec rawSpec []byte } @@ -895,12 +895,8 @@ const ( // Validate checks the workflow spec for correctness func (w *WorkflowSpec) Validate(ctx context.Context) error { - s, err := pkgworkflows.ParseWorkflowSpecYaml(w.Workflow) + s, err := w.SDKSpec(ctx) if err != nil { - return fmt.Errorf("%w: failed to parse workflow spec %s: %w", ErrInvalidWorkflowYAMLSpec, w.Workflow, err) - } - - if _, err = w.SDKSpec(ctx); err != nil { return err } @@ -919,7 +915,11 @@ func (w *WorkflowSpec) SDKSpec(ctx context.Context) (sdk.WorkflowSpec, error) { return *w.sdkWorkflow, nil } - spec, rawSpec, cid, err := workflowSpecFactory.Spec(ctx, w.Workflow, []byte(w.Config), w.SpecType) + workflowSpecFactory, ok := workflowSpecFactories[w.SpecType] + if !ok { + return sdk.WorkflowSpec{}, fmt.Errorf("unknown spec type %s", w.SpecType) + } + spec, rawSpec, cid, err := workflowSpecFactory.Spec(ctx, w.Workflow, []byte(w.Config)) if err != nil { return sdk.WorkflowSpec{}, err } @@ -934,7 +934,12 @@ func (w *WorkflowSpec) RawSpec(ctx context.Context) ([]byte, error) { return w.rawSpec, nil } - rs, err := workflowSpecFactory.RawSpec(ctx, w.Workflow, w.SpecType) + workflowSpecFactory, ok := workflowSpecFactories[w.SpecType] + if !ok { + return nil, fmt.Errorf("unknown spec type %s", w.SpecType) + } + + rs, err := workflowSpecFactory.RawSpec(ctx, w.Workflow, []byte(w.Config)) if err != nil { return nil, err } diff --git a/core/services/job/models_test.go b/core/services/job/models_test.go index 49bd29c9959..02aaff79317 100644 --- a/core/services/job/models_test.go +++ b/core/services/job/models_test.go @@ -1,7 +1,8 @@ -package job +package job_test import ( _ "embed" + "encoding/json" "reflect" "testing" "time" @@ -11,8 +12,10 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/codec" "github.com/smartcontractkit/chainlink-common/pkg/types" pkgworkflows "github.com/smartcontractkit/chainlink-common/pkg/workflows" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/stretchr/testify/assert" @@ -27,7 +30,7 @@ func TestOCR2OracleSpec_RelayIdentifier(t *testing.T) { type fields struct { Relay string ChainID string - RelayConfig JSONConfig + RelayConfig job.JSONConfig } tests := []struct { name string @@ -71,7 +74,7 @@ func TestOCR2OracleSpec_RelayIdentifier(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - s := &OCR2OracleSpec{ + s := &job.OCR2OracleSpec{ Relay: tt.fields.Relay, ChainID: tt.fields.ChainID, RelayConfig: tt.fields.RelayConfig, @@ -96,7 +99,7 @@ var ( ) func TestOCR2OracleSpec(t *testing.T) { - val := OCR2OracleSpec{ + val := job.OCR2OracleSpec{ Relay: relay.NetworkEVM, PluginType: types.Median, ContractID: "foo", @@ -259,13 +262,13 @@ func TestOCR2OracleSpec(t *testing.T) { }) t.Run("round-trip", func(t *testing.T) { - var gotVal OCR2OracleSpec + var gotVal job.OCR2OracleSpec require.NoError(t, toml.Unmarshal([]byte(compact), &gotVal)) gotB, err := toml.Marshal(gotVal) require.NoError(t, err) require.Equal(t, compact, string(gotB)) t.Run("pretty", func(t *testing.T) { - var gotVal OCR2OracleSpec + var gotVal job.OCR2OracleSpec require.NoError(t, toml.Unmarshal([]byte(pretty), &gotVal)) gotB, err := toml.Marshal(gotVal) require.NoError(t, err) @@ -321,7 +324,7 @@ func TestWorkflowSpec_Validate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - w := &WorkflowSpec{ + w := &job.WorkflowSpec{ Workflow: tt.fields.Workflow, } err := w.Validate(testutils.Context(t)) @@ -333,4 +336,24 @@ func TestWorkflowSpec_Validate(t *testing.T) { } }) } + + t.Run("WASM can validate", func(t *testing.T) { + config, err := json.Marshal(sdk.NewWorkflowParams{ + Owner: "owner", + Name: "name", + }) + require.NoError(t, err) + + w := &job.WorkflowSpec{ + Workflow: createTestBinary(t), + SpecType: job.WASMFile, + Config: string(config), + } + + err = w.Validate(testutils.Context(t)) + require.NoError(t, err) + assert.Equal(t, "owner", w.WorkflowOwner) + assert.Equal(t, "name", w.WorkflowName) + require.NotEmpty(t, w.WorkflowID) + }) } diff --git a/core/services/job/testdata/wasm/test_workflow_spec.go b/core/services/job/testdata/wasm/test_workflow_spec.go new file mode 100644 index 00000000000..40b9c0bbb67 --- /dev/null +++ b/core/services/job/testdata/wasm/test_workflow_spec.go @@ -0,0 +1,33 @@ +//go:build wasip1 + +package main + +import ( + "encoding/json" + "log" + + "github.com/smartcontractkit/chainlink-common/pkg/workflows/wasm" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities/cli/cmd/testdata/fixtures/capabilities/basictrigger" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" +) + +func BuildWorkflow(config []byte) *sdk.WorkflowSpecFactory { + params := sdk.NewWorkflowParams{} + if err := json.Unmarshal(config, ¶ms); err != nil { + log.Fatal(err) + } + + workflow := sdk.NewWorkflowSpecFactory(params) + + triggerCfg := basictrigger.TriggerConfig{Name: "trigger", Number: 100} + _ = triggerCfg.New(workflow) + + return workflow +} + +func main() { + runner := wasm.NewRunner() + workflow := BuildWorkflow(runner.Config()) + runner.Run(workflow) +} diff --git a/core/services/job/wasm_file_spec_factory.go b/core/services/job/wasm_file_spec_factory.go new file mode 100644 index 00000000000..fd320578eca --- /dev/null +++ b/core/services/job/wasm_file_spec_factory.go @@ -0,0 +1,95 @@ +package job + +import ( + "bytes" + "context" + "crypto/sha256" + "errors" + "fmt" + "io" + "os" + "path" + "strings" + + "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/wasm/host" + + "github.com/andybalholm/brotli" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +type WasmFileSpecFactory struct{} + +func (w WasmFileSpecFactory) Spec(_ context.Context, workflow string, config []byte) (sdk.WorkflowSpec, []byte, string, error) { + compressedBinary, sha, err := w.rawSpecAndSha(workflow, config) + if err != nil { + return sdk.WorkflowSpec{}, nil, "", err + } + + moduleConfig := &host.ModuleConfig{Logger: logger.NullLogger} + spec, err := host.GetWorkflowSpec(moduleConfig, compressedBinary, config) + if err != nil { + return sdk.WorkflowSpec{}, nil, "", err + } else if spec == nil { + return sdk.WorkflowSpec{}, nil, "", errors.New("workflow spec not found when running wasm") + } + + return *spec, compressedBinary, sha, nil +} + +func (w WasmFileSpecFactory) RawSpec(_ context.Context, workflow string, config []byte) ([]byte, error) { + raw, _, err := w.rawSpecAndSha(workflow, config) + return raw, err +} + +// rawSpecAndSha returns the brotli compressed version of the raw wasm file, alongside the sha256 hash of the raw wasm file +func (w WasmFileSpecFactory) rawSpecAndSha(wf string, config []byte) ([]byte, string, error) { + read, err := os.ReadFile(wf) + if err != nil { + return nil, "", err + } + + extension := strings.ToLower(path.Ext(wf)) + switch extension { + case ".wasm", "": + return w.rawSpecAndShaFromWasm(read, config) + case ".br": + return w.rawSpecAndShaFromBrotli(read, config) + default: + return nil, "", fmt.Errorf("unsupported file type %s", extension) + } +} + +func (w WasmFileSpecFactory) rawSpecAndShaFromBrotli(wasm, config []byte) ([]byte, string, error) { + brr := brotli.NewReader(bytes.NewReader(wasm)) + rawWasm, err := io.ReadAll(brr) + if err != nil { + return nil, "", err + } + + return wasm, w.sha(rawWasm, config), nil +} + +func (w WasmFileSpecFactory) rawSpecAndShaFromWasm(wasm, config []byte) ([]byte, string, error) { + var b bytes.Buffer + bwr := brotli.NewWriter(&b) + if _, err := bwr.Write(wasm); err != nil { + return nil, "", err + } + + if err := bwr.Close(); err != nil { + return nil, "", err + } + + return b.Bytes(), w.sha(wasm, config), nil +} + +func (w WasmFileSpecFactory) sha(wasm, config []byte) string { + sum := sha256.New() + sum.Write(wasm) + sum.Write(config) + return fmt.Sprintf("%x", sum.Sum(nil)) +} + +var _ WorkflowSpecFactory = (*WasmFileSpecFactory)(nil) diff --git a/core/services/job/wasm_file_spec_factory_test.go b/core/services/job/wasm_file_spec_factory_test.go new file mode 100644 index 00000000000..9f390dd1995 --- /dev/null +++ b/core/services/job/wasm_file_spec_factory_test.go @@ -0,0 +1,94 @@ +package job_test + +import ( + "bytes" + "crypto/sha256" + "encoding/json" + "fmt" + "os" + "os/exec" + "strings" + "testing" + + "github.com/andybalholm/brotli" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/wasm/host" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" +) + +func TestWasmFileSpecFactory(t *testing.T) { + binaryLocation := createTestBinary(t) + config, err := json.Marshal(sdk.NewWorkflowParams{ + Owner: "owner", + Name: "name", + }) + require.NoError(t, err) + + rawBinary, err := os.ReadFile(binaryLocation) + require.NoError(t, err) + + b := bytes.Buffer{} + bwr := brotli.NewWriter(&b) + _, err = bwr.Write(rawBinary) + require.NoError(t, err) + + require.NoError(t, bwr.Close()) + + t.Run("Raw binary", func(t *testing.T) { + factory := job.WasmFileSpecFactory{} + actual, rawSpec, actualSha, err2 := factory.Spec(testutils.Context(t), binaryLocation, config) + require.NoError(t, err2) + + expected, err2 := host.GetWorkflowSpec(&host.ModuleConfig{Logger: logger.NullLogger, IsUncompressed: true}, rawBinary, config) + require.NoError(t, err2) + + expectedSha := sha256.New() + expectedSha.Write(rawBinary) + expectedSha.Write(config) + require.Equal(t, fmt.Sprintf("%x", expectedSha.Sum(nil)), actualSha) + + require.Equal(t, *expected, actual) + + assert.Equal(t, b.Bytes(), rawSpec) + }) + + t.Run("Compressed binary", func(t *testing.T) { + brLoc := strings.Replace(binaryLocation, ".wasm", ".br", 1) + compressedBytes := b.Bytes() + require.NoError(t, os.WriteFile(brLoc, compressedBytes, 0600)) + + factory := job.WasmFileSpecFactory{} + actual, rawSpec, actualSha, err2 := factory.Spec(testutils.Context(t), brLoc, config) + require.NoError(t, err2) + + expected, err2 := host.GetWorkflowSpec(&host.ModuleConfig{Logger: logger.NullLogger, IsUncompressed: true}, rawBinary, config) + require.NoError(t, err2) + + expectedSha := sha256.New() + expectedSha.Write(rawBinary) + expectedSha.Write(config) + require.Equal(t, fmt.Sprintf("%x", expectedSha.Sum(nil)), actualSha) + + require.Equal(t, *expected, actual) + + assert.Equal(t, b.Bytes(), rawSpec) + }) +} + +func createTestBinary(t *testing.T) string { + const testBinaryLocation = "testdata/wasm/testmodule.wasm" + + cmd := exec.Command("go", "build", "-o", testBinaryLocation, "github.com/smartcontractkit/chainlink/v2/core/services/job/testdata/wasm") + cmd.Env = append(os.Environ(), "GOOS=wasip1", "GOARCH=wasm") + + output, err := cmd.CombinedOutput() + require.NoError(t, err, string(output)) + + return testBinaryLocation +} diff --git a/core/services/job/workflow_spec_factory.go b/core/services/job/workflow_spec_factory.go index 4cd789dfa1c..f2ad148b0c7 100644 --- a/core/services/job/workflow_spec_factory.go +++ b/core/services/job/workflow_spec_factory.go @@ -2,64 +2,17 @@ package job import ( "context" - "crypto/sha256" - "errors" - "fmt" "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" ) -var ErrInvalidWorkflowType = errors.New("invalid workflow type") - -type SDKWorkflowSpecFactory interface { - Spec(ctx context.Context, rawSpec, config []byte) (sdk.WorkflowSpec, error) - RawSpec(ctx context.Context, wf string) ([]byte, error) -} - -type WorkflowSpecFactory map[WorkflowSpecType]SDKWorkflowSpecFactory - -func (wsf WorkflowSpecFactory) Spec( - ctx context.Context, workflow string, config []byte, tpe WorkflowSpecType) (sdk.WorkflowSpec, []byte, string, error) { - if tpe == "" { - tpe = DefaultSpecType - } - - factory, ok := wsf[tpe] - if !ok { - return sdk.WorkflowSpec{}, nil, "", ErrInvalidWorkflowType - } - - rawSpec, err := factory.RawSpec(ctx, workflow) - if err != nil { - return sdk.WorkflowSpec{}, nil, "", err - } - - spec, err := factory.Spec(ctx, rawSpec, config) - if err != nil { - return sdk.WorkflowSpec{}, nil, "", err - } - - sum := sha256.New() - sum.Write(rawSpec) - sum.Write(config) - - return spec, rawSpec, fmt.Sprintf("%x", sum.Sum(nil)), nil -} - -func (wsf WorkflowSpecFactory) RawSpec( - ctx context.Context, workflow string, tpe WorkflowSpecType) ([]byte, error) { - if tpe == "" { - tpe = DefaultSpecType - } - - factory, ok := wsf[tpe] - if !ok { - return nil, ErrInvalidWorkflowType - } - - return factory.RawSpec(ctx, workflow) +type WorkflowSpecFactory interface { + Spec(ctx context.Context, workflow string, config []byte) (sdk.WorkflowSpec, []byte, string, error) + RawSpec(ctx context.Context, workflow string, config []byte) ([]byte, error) } -var workflowSpecFactory = WorkflowSpecFactory{ - YamlSpec: YAMLSpecFactory{}, +var workflowSpecFactories = map[WorkflowSpecType]WorkflowSpecFactory{ + YamlSpec: YAMLSpecFactory{}, + WASMFile: WasmFileSpecFactory{}, + DefaultSpecType: YAMLSpecFactory{}, } diff --git a/core/services/job/workflow_spec_factory_test.go b/core/services/job/workflow_spec_factory_test.go deleted file mode 100644 index 4c57641a3f4..00000000000 --- a/core/services/job/workflow_spec_factory_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package job_test - -import ( - "context" - "crypto/sha256" - "errors" - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" - - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/services/job" -) - -func TestWorkflowSpecFactory_ToSpec(t *testing.T) { - t.Parallel() - - anyData := "any data" - anyConfig := []byte("any config") - anySpec := sdk.WorkflowSpec{Name: "name", Owner: "owner"} - - t.Run("delegates to factory and calculates CID", func(t *testing.T) { - runYamlSpecTest(t, anySpec, anyData, anyConfig, job.YamlSpec) - }) - - t.Run("delegates default", func(t *testing.T) { - runYamlSpecTest(t, anySpec, anyData, anyConfig, "") - }) - - t.Run("CID without config matches", func(t *testing.T) { - factory := job.WorkflowSpecFactory{ - job.YamlSpec: mockSdkSpecFactory{t: t, noConfig: true, SpecVal: anySpec}, - } - results, _, cid, err := factory.Spec(testutils.Context(t), anyData, nil, job.YamlSpec) - require.NoError(t, err) - - assert.Equal(t, anySpec, results) - - sha256Hash := sha256.New() - sha256Hash.Write([]byte(anyData)) - expectedCid := fmt.Sprintf("%x", sha256Hash.Sum(nil)) - assert.Equal(t, expectedCid, cid) - }) - - t.Run("returns errors from sdk factory", func(t *testing.T) { - anyErr := errors.New("nope") - factory := job.WorkflowSpecFactory{ - job.YamlSpec: mockSdkSpecFactory{t: t, Err: anyErr}, - } - - _, _, _, err := factory.Spec(testutils.Context(t), anyData, anyConfig, job.YamlSpec) - assert.Equal(t, anyErr, err) - }) - - t.Run("returns an error if the type is not supported", func(t *testing.T) { - factory := job.WorkflowSpecFactory{ - job.YamlSpec: mockSdkSpecFactory{t: t, SpecVal: anySpec}, - } - - _, _, _, err := factory.Spec(testutils.Context(t), anyData, anyConfig, "unsupported") - assert.Error(t, err) - }) -} - -func runYamlSpecTest(t *testing.T, anySpec sdk.WorkflowSpec, anyData string, anyConfig []byte, specType job.WorkflowSpecType) { - factory := job.WorkflowSpecFactory{ - job.YamlSpec: mockSdkSpecFactory{t: t, SpecVal: anySpec}, - } - - results, _, cid, err := factory.Spec(testutils.Context(t), anyData, anyConfig, specType) - - require.NoError(t, err) - assert.Equal(t, anySpec, results) - - sha256Hash := sha256.New() - sha256Hash.Write([]byte(anyData)) - sha256Hash.Write(anyConfig) - expectedCid := fmt.Sprintf("%x", sha256Hash.Sum(nil)) - assert.Equal(t, expectedCid, cid) -} - -type mockSdkSpecFactory struct { - t *testing.T - noConfig bool - SpecVal sdk.WorkflowSpec - Err error -} - -func (f mockSdkSpecFactory) RawSpec(_ context.Context, wf string) ([]byte, error) { - return []byte(wf), nil -} - -func (f mockSdkSpecFactory) Spec(_ context.Context, rawSpec, config []byte) (sdk.WorkflowSpec, error) { - assert.ElementsMatch(f.t, rawSpec, []byte("any data")) - if f.noConfig { - assert.Nil(f.t, config) - } else { - assert.ElementsMatch(f.t, config, []byte("any config")) - } - - return f.SpecVal, f.Err -} diff --git a/core/services/job/yaml_spec_factory.go b/core/services/job/yaml_spec_factory.go index ea344a3ffc4..73e5bcc325b 100644 --- a/core/services/job/yaml_spec_factory.go +++ b/core/services/job/yaml_spec_factory.go @@ -2,6 +2,8 @@ package job import ( "context" + "crypto/sha256" + "fmt" "github.com/smartcontractkit/chainlink-common/pkg/workflows" "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" @@ -9,12 +11,13 @@ import ( type YAMLSpecFactory struct{} -var _ SDKWorkflowSpecFactory = (*YAMLSpecFactory)(nil) +var _ WorkflowSpecFactory = (*YAMLSpecFactory)(nil) -func (y YAMLSpecFactory) Spec(_ context.Context, rawSpec, _ []byte) (sdk.WorkflowSpec, error) { - return workflows.ParseWorkflowSpecYaml(string(rawSpec)) +func (y YAMLSpecFactory) Spec(_ context.Context, workflow string, _ []byte) (sdk.WorkflowSpec, []byte, string, error) { + spec, err := workflows.ParseWorkflowSpecYaml(workflow) + return spec, []byte(workflow), fmt.Sprintf("%x", sha256.Sum256([]byte(workflow))), err } -func (y YAMLSpecFactory) RawSpec(_ context.Context, wf string) ([]byte, error) { - return []byte(wf), nil +func (y YAMLSpecFactory) RawSpec(_ context.Context, workflow string, _ []byte) ([]byte, error) { + return []byte(workflow), nil } diff --git a/core/services/job/yaml_spec_factory_test.go b/core/services/job/yaml_spec_factory_test.go index 4d075fe6e20..b40adf3ad63 100644 --- a/core/services/job/yaml_spec_factory_test.go +++ b/core/services/job/yaml_spec_factory_test.go @@ -1,8 +1,11 @@ package job_test import ( + "crypto/sha256" + "fmt" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" commonworkflows "github.com/smartcontractkit/chainlink-common/pkg/workflows" @@ -64,19 +67,13 @@ targets: func TestYamlSpecFactory_GetSpec(t *testing.T) { t.Parallel() - actual, err := job.YAMLSpecFactory{}.Spec(testutils.Context(t), []byte(anyYamlSpec), []byte{}) + actual, raw, actualSha, err := job.YAMLSpecFactory{}.Spec(testutils.Context(t), anyYamlSpec, []byte{}) require.NoError(t, err) expected, err := commonworkflows.ParseWorkflowSpecYaml(anyYamlSpec) require.NoError(t, err) require.Equal(t, expected, actual) -} - -func TestYamlSpecFactory_GetRawSpec(t *testing.T) { - t.Parallel() - - actual, err := job.YAMLSpecFactory{}.RawSpec(testutils.Context(t), anyYamlSpec) - require.NoError(t, err) - require.Equal(t, []byte(anyYamlSpec), actual) + assert.Equal(t, fmt.Sprintf("%x", sha256.Sum256([]byte(anyYamlSpec))), actualSha) + assert.Equal(t, anyYamlSpec, string(raw)) } diff --git a/core/services/relay/evm/chain_components_test.go b/core/services/relay/evm/chain_components_test.go index 50c530904dd..33a862c6ce9 100644 --- a/core/services/relay/evm/chain_components_test.go +++ b/core/services/relay/evm/chain_components_test.go @@ -133,9 +133,66 @@ func TestContractReaderEventsInitValidation(t *testing.T) { }, }, expectedError: fmt.Errorf( - "%w: event %s doesn't exist", + "%w: event %q doesn't exist", clcommontypes.ErrInvalidConfig, "EventName"), }, + { + name: "Event has a unnecessary data word index override", + chainContractReaders: map[string]types.ChainContractReader{ + "ContractWithConflict": { + ContractABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"someDW\",\"type\":\"address\"}],\"name\":\"EventName\",\"type\":\"event\"}]", + ContractPollingFilter: types.ContractPollingFilter{ + GenericEventNames: []string{"SomeEvent"}, + }, + Configs: map[string]*types.ChainReaderDefinition{ + "SomeEvent": { + ChainSpecificName: "EventName", + ReadType: types.Event, + + EventDefinitions: &types.EventDefinitions{ + GenericDataWordDetails: map[string]types.DataWordDetail{ + "DW": { + Name: "someDW", + Index: ptr(0), + }, + }, + }, + }, + }, + }, + }, + expectedError: fmt.Errorf("failed to init dw querying for event: %q, err: data word: %q at index: %d details, were calculated automatically and shouldn't be manully overridden by cfg", + "SomeEvent", "DW", 0), + }, + { + name: "Event has a bad type defined in data word detail override config", + chainContractReaders: map[string]types.ChainContractReader{ + "ContractWithConflict": { + ContractABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"someDW\",\"type\":\"string\"}],\"name\":\"EventName\",\"type\":\"event\"}]", + ContractPollingFilter: types.ContractPollingFilter{ + GenericEventNames: []string{"SomeEvent"}, + }, + Configs: map[string]*types.ChainReaderDefinition{ + "SomeEvent": { + ChainSpecificName: "EventName", + ReadType: types.Event, + + EventDefinitions: &types.EventDefinitions{ + GenericDataWordDetails: map[string]types.DataWordDetail{ + "DW": { + Name: "someDW", + Index: ptr(0), + Type: "abcdefg", + }, + }, + }, + }, + }, + }, + }, + expectedError: fmt.Errorf("failed to init dw querying for event: %q, err: bad abi type: \"abcdefg\" provided for data word: %q at index: %d in config", + "SomeEvent", "DW", 0), + }, } for _, tt := range tests { diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index 6b9f9411789..73948f48774 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -280,7 +280,7 @@ func (cr *chainReader) addMethod( func (cr *chainReader) addEvent(contractName, eventName string, a abi.ABI, chainReaderDefinition types.ChainReaderDefinition) error { event, eventExists := a.Events[chainReaderDefinition.ChainSpecificName] if !eventExists { - return fmt.Errorf("%w: event %s doesn't exist", commontypes.ErrInvalidConfig, chainReaderDefinition.ChainSpecificName) + return fmt.Errorf("%w: event %q doesn't exist", commontypes.ErrInvalidConfig, chainReaderDefinition.ChainSpecificName) } indexedAsUnIndexedABITypes, indexedTopicsCodecTypes, eventDWs := getEventTypes(event) @@ -318,9 +318,9 @@ func (cr *chainReader) addEvent(contractName, eventName string, a abi.ABI, chain maps.Copy(codecModifiers, topicsModifiers) // TODO BCFR-44 no dw modifier for now - dataWordsDetails, dWSCodecTypeInfo, initDWQueryingErr := cr.initDWQuerying(contractName, eventName, eventDWs, eventDefinitions.GenericDataWordNames) + dataWordsDetails, dWSCodecTypeInfo, initDWQueryingErr := cr.initDWQuerying(contractName, eventName, eventDWs, eventDefinitions.GenericDataWordDetails) if initDWQueryingErr != nil { - return initDWQueryingErr + return fmt.Errorf("failed to init dw querying for event: %q, err: %w", eventName, initDWQueryingErr) } maps.Copy(codecTypes, dWSCodecTypeInfo) @@ -359,32 +359,61 @@ func (cr *chainReader) initTopicQuerying(contractName, eventName string, eventIn } // initDWQuerying registers codec types for evm data words to be used for typing value comparator QueryKey filters. -func (cr *chainReader) initDWQuerying(contractName, eventName string, eventDWs map[string]read.DataWordDetail, dWDefs map[string]string) (map[string]read.DataWordDetail, map[string]types.CodecEntry, error) { +func (cr *chainReader) initDWQuerying(contractName, eventName string, abiDWsDetails map[string]read.DataWordDetail, cfgDWsDetails map[string]types.DataWordDetail) (map[string]read.DataWordDetail, map[string]types.CodecEntry, error) { + dWsDetail, err := cr.constructDWDetails(cfgDWsDetails, abiDWsDetails) + if err != nil { + return nil, nil, err + } + dwsCodecTypeInfo := make(map[string]types.CodecEntry) - dWsDetail := make(map[string]read.DataWordDetail) + for genericName := range cfgDWsDetails { + dwDetail, exists := dWsDetail[genericName] + if !exists { + return nil, nil, fmt.Errorf("failed to find data word: %q, it either doesn't exist or can't be searched for", genericName) + } + + dwTypeID := eventName + "." + genericName + if err = cr.addEncoderDef(contractName, dwTypeID, abi.Arguments{abi.Argument{Type: dwDetail.Type}}, nil, nil); err != nil { + return nil, nil, fmt.Errorf("failed to init codec for data word: %q on index: %d, err: %w", genericName, dwDetail.Index, err) + } + + dwCodecTypeID := codec.WrapItemType(contractName, dwTypeID, true) + dwsCodecTypeInfo[dwCodecTypeID] = cr.parsed.EncoderDefs[dwCodecTypeID] + } + + return dWsDetail, dwsCodecTypeInfo, nil +} - for genericName, onChainName := range dWDefs { - for eventID, dWDetail := range eventDWs { +// constructDWDetails combines data word details from config and abi. +func (cr *chainReader) constructDWDetails(cfgDWsDetails map[string]types.DataWordDetail, abiDWsDetails map[string]read.DataWordDetail) (map[string]read.DataWordDetail, error) { + dWsDetail := make(map[string]read.DataWordDetail) + for genericName, cfgDWDetail := range cfgDWsDetails { + for eventID, dWDetail := range abiDWsDetails { // Extract field name in this manner to account for nested fields fieldName := strings.Join(strings.Split(eventID, ".")[1:], ".") - if fieldName == onChainName { + if fieldName == cfgDWDetail.Name { dWsDetail[genericName] = dWDetail - - dwTypeID := eventName + "." + genericName - if err := cr.addEncoderDef(contractName, dwTypeID, abi.Arguments{abi.Argument{Type: dWDetail.Type}}, nil, nil); err != nil { - return nil, nil, fmt.Errorf("%w: failed to init codec for data word %s on index %d querying for event: %q", err, genericName, dWDetail.Index, eventName) - } - - dwCodecTypeID := codec.WrapItemType(contractName, dwTypeID, true) - dwsCodecTypeInfo[dwCodecTypeID] = cr.parsed.EncoderDefs[dwCodecTypeID] break } } - if _, ok := dWsDetail[genericName]; !ok { - return nil, nil, fmt.Errorf("failed to find data word: %q for event: %q, it either doesn't exist or can't be searched for", genericName, eventName) + } + + // 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 cfgDWsDetails { + dwDetail, exists := dWsDetail[genericName] + if exists && cfgDWDetail.Index != nil { + return nil, fmt.Errorf("data word: %q at index: %d details, were calculated automatically and shouldn't be manully overridden by cfg", genericName, dwDetail.Index) + } + + 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 at index: %d in config", cfgDWDetail.Type, genericName, *cfgDWDetail.Index) + } + dWsDetail[genericName] = read.DataWordDetail{Argument: abi.Argument{Type: abiTyp}, Index: *cfgDWDetail.Index} } } - return dWsDetail, dwsCodecTypeInfo, nil + return dWsDetail, nil } // getEventItemTypeAndModifier returns codec entry for expected incoming event item and the modifier. diff --git a/core/services/relay/evm/codec/codec.go b/core/services/relay/evm/codec/codec.go index b0572b54791..397460a7f3e 100644 --- a/core/services/relay/evm/codec/codec.go +++ b/core/services/relay/evm/codec/codec.go @@ -90,7 +90,7 @@ func (c *evmCodec) CreateType(itemType string, forEncoding bool) (any, error) { def, ok := itemTypes[itemType] if !ok { - return nil, fmt.Errorf("%w: cannot find type name %s", commontypes.ErrInvalidType, itemType) + return nil, fmt.Errorf("%w: cannot find type name %q", commontypes.ErrInvalidType, itemType) } // we don't need double pointers, and they can also mess up reflection variable creation and mapstruct decode diff --git a/core/services/relay/evm/evmtesting/chain_components_interface_tester.go b/core/services/relay/evm/evmtesting/chain_components_interface_tester.go index ac8ece9b37f..cc3d3a8fdb6 100644 --- a/core/services/relay/evm/evmtesting/chain_components_interface_tester.go +++ b/core/services/relay/evm/evmtesting/chain_components_interface_tester.go @@ -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" @@ -38,6 +39,7 @@ const ( triggerWithDynamicTopic = "TriggeredEventWithDynamicTopic" triggerWithAllTopics = "TriggeredWithFourTopics" triggerWithAllTopicsWithHashed = "TriggeredWithFourTopicsWithHashed" + staticBytesEventName = "StaticBytes" finalityDepth = 4 ) @@ -120,7 +122,7 @@ func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) { AnyContractName: { ContractABI: chain_reader_tester.ChainReaderTesterMetaData.ABI, ContractPollingFilter: types.ContractPollingFilter{ - GenericEventNames: []string{EventName, EventWithFilterName, triggerWithAllTopicsWithHashed}, + GenericEventNames: []string{EventName, EventWithFilterName, triggerWithAllTopicsWithHashed, staticBytesEventName}, }, Configs: map[string]*types.ChainReaderDefinition{ MethodTakingLatestParamsReturningTestStruct: &methodTakingLatestParamsReturningTestStructConfig, @@ -138,10 +140,11 @@ func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) { ReadType: types.Event, EventDefinitions: &types.EventDefinitions{ GenericTopicNames: map[string]string{"field": "Field"}, - GenericDataWordNames: map[string]string{ - "OracleID": "oracleId", - "NestedStaticStruct.Inner.IntVal": "nestedStaticStruct.Inner.IntVal", - "BigField": "bigField", + GenericDataWordDetails: map[string]types.DataWordDetail{ + "OracleID": {Name: "oracleId"}, + // this is just to illustrate an example, generic names shouldn't really be formatted like this since other chains might not store it in the same way + "NestedStaticStruct.Inner.IntVal": {Name: "nestedStaticStruct.Inner.IntVal"}, + "BigField": {Name: "bigField"}, }, }, OutputModifications: codec.ModifiersConfig{ @@ -149,6 +152,19 @@ func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) { &codec.RenameModifierConfig{Fields: map[string]string{"NestedStaticStruct.Inner.IntVal": "I"}}, }, }, + staticBytesEventName: { + ChainSpecificName: staticBytesEventName, + ReadType: types.Event, + EventDefinitions: &types.EventDefinitions{ + GenericDataWordDetails: map[string]types.DataWordDetail{ + "msgTransmitterEvent": { + Name: "msgTransmitterEvent", + Index: testutils.Ptr(2), + Type: "bytes32", + }, + }, + }, + }, EventWithFilterName: { ChainSpecificName: "Triggered", ReadType: types.Event, @@ -263,6 +279,12 @@ func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) { GasLimit: 2_000_000, Checker: "simulate", }, + "triggerStaticBytes": { + ChainSpecificName: "triggerStaticBytes", + FromAddress: it.Helper.Accounts(t)[1].From, + GasLimit: 2_000_000, + Checker: "simulate", + }, }, }, AnySecondContractName: { diff --git a/core/services/relay/evm/evmtesting/run_tests.go b/core/services/relay/evm/evmtesting/run_tests.go index 7e01cf2b657..ce3df6a07ed 100644 --- a/core/services/relay/evm/evmtesting/run_tests.go +++ b/core/services/relay/evm/evmtesting/run_tests.go @@ -1,6 +1,7 @@ package evmtesting import ( + "encoding/binary" "math/big" "reflect" "time" @@ -221,6 +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) }) + + 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 := 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) { @@ -242,3 +286,31 @@ func triggerFourTopicsWithHashed[T TestingT[T]](t T, it *EVMChainComponentsInter contracts := it.GetBindings(t) SubmitTransactionToCW(t, it, "triggerWithFourTopicsWithHashed", DynamicEvent{Field1: i1, Field2: i2, Field3: i3}, 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) +} diff --git a/core/services/relay/evm/read/event.go b/core/services/relay/evm/read/event.go index a2cf95a2da2..d1efe662489 100644 --- a/core/services/relay/evm/read/event.go +++ b/core/services/relay/evm/read/event.go @@ -79,7 +79,7 @@ type TopicDetail struct { } // DataWordDetail contains all the information about a single evm Data word. -// For b.g. first evm data word(32bytes) of USDC log event is uint256 var called valub. +// For e.g. first evm data word(32bytes) of USDC log event is uint256 var called value. type DataWordDetail struct { Index int abi.Argument diff --git a/core/services/relay/evm/types/types.go b/core/services/relay/evm/types/types.go index df049a70693..17fc885153d 100644 --- a/core/services/relay/evm/types/types.go +++ b/core/services/relay/evm/types/types.go @@ -58,6 +58,14 @@ type ChainCodecConfig struct { ModifierConfigs codec.ModifiersConfig `json:"modifierConfigs,omitempty" toml:"modifierConfigs,omitempty"` } +type DataWordDetail struct { + Name string `json:"name"` + // 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"` +} + type ContractPollingFilter struct { GenericEventNames []string `json:"genericEventNames"` PollingFilter `json:"pollingFilter"` @@ -97,9 +105,9 @@ type EventDefinitions struct { // GenericTopicNames helps QueryingKeys not rely on EVM specific topic names. Key is chain specific name, value is generic name. // This helps us translate chain agnostic querying key "transfer-value" to EVM specific "evmTransferEvent-weiAmountTopic". GenericTopicNames map[string]string `json:"genericTopicNames,omitempty"` - // GenericDataWordNames key is generic name for evm log event data word that maps to on chain name. + // GenericDataWordDetails key is generic name for evm log event data word that maps to chain details. // For e.g. first evm data word(32bytes) of USDC log event is value so the key can be called value. - GenericDataWordNames map[string]string `json:"genericDataWordDefs,omitempty"` + GenericDataWordDetails map[string]DataWordDetail `json:"genericDataWordDetails,omitempty"` // PollingFilter should be defined on a contract level in ContractPollingFilter, // unless event needs to override the contract level filter options. // This will create a separate log poller filter for this event. diff --git a/core/services/relay/evm/types/types_test.go b/core/services/relay/evm/types/types_test.go index 11825ae5c40..f77b4226e87 100644 --- a/core/services/relay/evm/types/types_test.go +++ b/core/services/relay/evm/types/types_test.go @@ -80,7 +80,7 @@ func Test_ChainReaderConfig(t *testing.T) { } }, "configs":{ - "config1":"{\"cacheEnabled\":true,\"chainSpecificName\":\"specificName1\",\"inputModifications\":[{\"Fields\":[\"ts\"],\"Type\":\"epoch to time\"},{\"Fields\":{\"a\":\"b\"},\"Type\":\"rename\"}],\"outputModifications\":[{\"Fields\":[\"ts\"],\"Type\":\"epoch to time\"},{\"Fields\":{\"c\":\"d\"},\"Type\":\"rename\"}],\"eventDefinitions\":{\"genericTopicNames\":{\"TopicKey1\":\"TopicVal1\"},\"genericDataWordDefs\":{\"DataWordKey\": \"DataWordKey\"},\"pollingFilter\":{\"topic2\":[\"0x4abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"topic3\":[\"0x5abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"topic4\":[\"0x6abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"retention\":\"1m0s\",\"maxLogsKept\":100,\"logsPerBlock\":10}},\"confidenceConfirmations\":{\"0.0\":0,\"1.0\":-1}}" + "config1":"{\"cacheEnabled\":true,\"chainSpecificName\":\"specificName1\",\"inputModifications\":[{\"Fields\":[\"ts\"],\"Type\":\"epoch to time\"},{\"Fields\":{\"a\":\"b\"},\"Type\":\"rename\"}],\"outputModifications\":[{\"Fields\":[\"ts\"],\"Type\":\"epoch to time\"},{\"Fields\":{\"c\":\"d\"},\"Type\":\"rename\"}],\"eventDefinitions\":{\"genericTopicNames\":{\"TopicKey1\":\"TopicVal1\"},\"genericDataWordDetails\":{\"DataWordKey\":{\"Name\":\"DataWordKey\"}},\"pollingFilter\":{\"topic2\":[\"0x4abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"topic3\":[\"0x5abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"topic4\":[\"0x6abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"retention\":\"1m0s\",\"maxLogsKept\":100,\"logsPerBlock\":10}},\"confidenceConfirmations\":{\"0.0\":0,\"1.0\":-1}}" } } } @@ -127,8 +127,8 @@ func Test_ChainReaderConfig(t *testing.T) { }, ConfidenceConfirmations: map[string]int{"0.0": 0, "1.0": -1}, EventDefinitions: &EventDefinitions{ - GenericTopicNames: map[string]string{"TopicKey1": "TopicVal1"}, - GenericDataWordNames: map[string]string{"DataWordKey": "DataWordKey"}, + GenericTopicNames: map[string]string{"TopicKey1": "TopicVal1"}, + GenericDataWordDetails: map[string]DataWordDetail{"DataWordKey": {Name: "DataWordKey"}}, PollingFilter: &PollingFilter{ Topic2: evmtypes.HashArray{common.HexToHash("0x4abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52")}, Topic3: evmtypes.HashArray{common.HexToHash("0x5abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52")}, diff --git a/core/services/workflows/models_test.go b/core/services/workflows/models_test.go index 68944e64bad..40fa699b08b 100644 --- a/core/services/workflows/models_test.go +++ b/core/services/workflows/models_test.go @@ -294,7 +294,7 @@ targets: for _, tc := range testCases { t.Run(tc.name, func(st *testing.T) { - spec, err := job.YAMLSpecFactory{}.Spec(testutils.Context(t), []byte(tc.yaml), nil) + spec, _, _, err := job.YAMLSpecFactory{}.Spec(testutils.Context(t), tc.yaml, nil) require.NoError(t, err) wf, err := Parse(spec) @@ -323,7 +323,7 @@ targets: } func TestParsesIntsCorrectly(t *testing.T) { - spec, err := job.YAMLSpecFactory{}.Spec(testutils.Context(t), []byte(hardcodedWorkflow), nil) + spec, _, _, err := job.YAMLSpecFactory{}.Spec(testutils.Context(t), hardcodedWorkflow, nil) require.NoError(t, err) wf, err := Parse(spec) diff --git a/integration-tests/scripts/entrypoint b/integration-tests/scripts/entrypoint index dc4ff1d0dbe..ca460eb8177 100755 --- a/integration-tests/scripts/entrypoint +++ b/integration-tests/scripts/entrypoint @@ -19,6 +19,10 @@ if [ -z "${SUITE}" ]; then exit 1 fi +# Helpful for debugging +pwd +ls -la + # run the tests ./${SUITE}.test -test.v -test.count 1 ${ARGS} -test.run ^${TEST_NAME}$