diff --git a/.changeset/beige-socks-cover.md b/.changeset/beige-socks-cover.md new file mode 100644 index 00000000000..0b7c22d01e5 --- /dev/null +++ b/.changeset/beige-socks-cover.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal changes to core required by change BCF3168 in common to add relayer set diff --git a/.changeset/fast-students-accept.md b/.changeset/fast-students-accept.md new file mode 100644 index 00000000000..8813f3a7812 --- /dev/null +++ b/.changeset/fast-students-accept.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal Optimize workflow engine tests diff --git a/.changeset/proud-toys-travel.md b/.changeset/proud-toys-travel.md new file mode 100644 index 00000000000..e2b1f0c7269 --- /dev/null +++ b/.changeset/proud-toys-travel.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Improving LogPoller read queries by properly sorting by multiple columns #updated diff --git a/.changeset/witty-numbers-sleep.md b/.changeset/witty-numbers-sleep.md new file mode 100644 index 00000000000..d42664d9f76 --- /dev/null +++ b/.changeset/witty-numbers-sleep.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Support for retention in LogPoller's filters registered by ContractTransmitter #changed diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 394faf71e2f..e1891770930 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -77,6 +77,10 @@ jobs: slack-message: "golangci-lint failed: ${{ job.html_url }}\n${{ format('https://github.com/smartcontractkit/chainlink/actions/runs/{0}', github.run_id) }}" core: + env: + # We explicitly have this env var not be "CL_DATABASE_URL" to avoid having it be used by core related tests + # when they should not be using it, while still allowing us to DRY up the setup + DB_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable strategy: fail-fast: false matrix: @@ -92,8 +96,6 @@ jobs: if: github.actor != 'dependabot[bot]' needs: [filter] runs-on: ubuntu-latest-64cores-256GB - env: - CL_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable steps: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -136,6 +138,8 @@ jobs: - name: Setup DB if: ${{ needs.filter.outputs.changes == 'true' }} run: ./chainlink.test local db preparetest + env: + CL_DATABASE_URL: ${{ env.DB_URL }} - name: Install LOOP Plugins if: ${{ needs.filter.outputs.changes == 'true' }} run: | @@ -165,6 +169,7 @@ jobs: env: OUTPUT_FILE: ./output.txt USE_TEE: false + CL_DATABASE_URL: ${{ env.DB_URL }} run: ./tools/bin/${{ matrix.type.cmd }} ./... - name: Print Filtered Test Results if: ${{ failure() && matrix.type.cmd == 'go_core_tests' && needs.filter.outputs.changes == 'true' }} diff --git a/.github/workflows/cicd-changesets.yml b/.github/workflows/cicd-changesets.yml index 0bfec7b22f2..96363588319 100644 --- a/.github/workflows/cicd-changesets.yml +++ b/.github/workflows/cicd-changesets.yml @@ -16,6 +16,7 @@ jobs: permissions: id-token: write contents: read + actions: read steps: - name: Checkout repository uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -28,6 +29,31 @@ jobs: core-changeset: - added: '.changeset/**' + - name: Setup pnpm + uses: pnpm/action-setup@a3252b78c470c02df07e9d59298aecedc3ccdd6d # v3.0.0 + if: steps.changeset-added.outputs.core-changeset == 'true' + with: + version: ^8.0.0 + + - name: Setup node + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + if: steps.changeset-added.outputs.core-changeset == 'true' + with: + node-version: 20 + cache: pnpm + cache-dependency-path: ./pnpm-lock.yaml + + - name: Run changeset version + run: pnpm install && pnpm changeset version + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: steps.changeset-added.outputs.core-changeset == 'true' + + - name: Get release version + if: steps.changeset-added.outputs.core-changeset == 'true' + id: get-release-version + run: echo "version=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + - name: cicd-changesets if: steps.changeset-added.outputs.core-changeset == 'true' uses: smartcontractkit/.github/actions/cicd-changesets@6da79c7b9f14bec077df2c1ad40d53823b409d9c # cicd-changesets@0.3.3 @@ -37,7 +63,7 @@ jobs: git-email: app-token-issuer-releng[bot]@users.noreply.github.com pnpm-use-cache: false pr-draft: true - pr-title: "[DO NOT MERGE] Release Preview - Changeset" + pr-title: "[DO NOT MERGE] Changeset Release Preview - v${{ steps.get-release-version.outputs.version }}" # aws inputs aws-region: ${{ secrets.AWS_REGION }} aws-role-arn: ${{ secrets.AWS_OIDC_CHAINLINK_CI_AUTO_PR_TOKEN_ISSUER_ROLE_ARN }} diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol new file mode 100644 index 00000000000..de7810b4c15 --- /dev/null +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseTest} from "./BaseTest.t.sol"; +import {CapabilityRegistry} from "../CapabilityRegistry.sol"; + +contract CapabilityRegistry_GetCapabilitiesTest is BaseTest { + function test_ReturnsCapabilities() public { + s_capabilityRegistry.addCapability(s_basicCapability); + s_capabilityRegistry.addCapability(s_capabilityWithConfigurationContract); + + CapabilityRegistry.Capability[] memory capabilities = s_capabilityRegistry.getCapabilities(); + + assertEq(capabilities.length, 2); + + assertEq(capabilities[0].capabilityType, "data-streams-reports"); + assertEq(capabilities[0].version, "1.0.0"); + assertEq(uint256(capabilities[0].responseType), uint256(CapabilityRegistry.CapabilityResponseType.REPORT)); + assertEq(capabilities[0].configurationContract, address(0)); + + assertEq(capabilities[1].capabilityType, "read-ethereum-mainnet-gas-price"); + assertEq(capabilities[1].version, "1.0.2"); + assertEq( + uint256(capabilities[1].responseType), + uint256(CapabilityRegistry.CapabilityResponseType.OBSERVATION_IDENTICAL) + ); + assertEq(capabilities[1].configurationContract, address(s_capabilityConfigurationContract)); + } +} diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index e1c7a9f48cc..9553f59ad61 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -23,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/store/models" ) func TestChainScopedConfig(t *testing.T) { @@ -380,6 +381,7 @@ func TestChainScopedConfig_HeadTracker(t *testing.T) { func Test_chainScopedConfig_Validate(t *testing.T) { configWithChains := func(t *testing.T, id int64, chains ...*toml.Chain) config.AppConfig { return configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + s.Database.URL = models.MustSecretURL("postgresql://doesnotexist:justtopassvalidationtests@localhost:5432/chainlink_na_test") chainID := ubig.NewI(id) c.EVM[0] = &toml.EVMConfig{ChainID: chainID, Enabled: ptr(true), Chain: toml.Defaults(chainID, chains...), Nodes: toml.EVMNodes{{ diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 5e0a74a9183..d065553886e 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -224,7 +224,9 @@ func (o *DSORM) SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig AND event_sig = :event_sig AND address = :address AND block_number <= %s - ORDER BY (block_number, log_index) DESC LIMIT 1`, nestedBlockNumberQuery(confs)) + ORDER BY block_number desc, log_index DESC + LIMIT 1 + `, nestedBlockNumberQuery(confs)) var l Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -425,7 +427,7 @@ func (o *DSORM) SelectLogsByBlockRange(ctx context.Context, start, end int64) ([ WHERE evm_chain_id = :evm_chain_id AND block_number >= :start_block AND block_number <= :end_block - ORDER BY (block_number, log_index)` + ORDER BY block_number, log_index` var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -456,7 +458,7 @@ func (o *DSORM) SelectLogs(ctx context.Context, start, end int64, address common AND event_sig = :event_sig AND block_number >= :start_block AND block_number <= :end_block - ORDER BY (block_number, log_index)` + ORDER BY block_number, log_index` var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -488,7 +490,7 @@ func (o *DSORM) SelectLogsCreatedAfter(ctx context.Context, address common.Addre AND event_sig = :event_sig AND block_timestamp > :block_timestamp_after AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -520,7 +522,7 @@ func (o *DSORM) SelectLogsWithSigs(ctx context.Context, start, end int64, addres AND address = :address AND event_sig = ANY(:event_sig_array) AND block_number BETWEEN :start_block AND :end_block - ORDER BY (block_number, log_index)` + ORDER BY block_number, log_index` query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { @@ -647,7 +649,7 @@ func (o *DSORM) SelectLogsDataWordRange(ctx context.Context, address common.Addr AND substring(data from 32*:word_index+1 for 32) >= :word_value_min AND substring(data from 32*:word_index+1 for 32) <= :word_value_max AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -678,7 +680,7 @@ func (o *DSORM) SelectLogsDataWordGreaterThan(ctx context.Context, address commo AND event_sig = :event_sig AND substring(data from 32*:word_index+1 for 32) >= :word_value_min AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -710,7 +712,7 @@ func (o *DSORM) SelectLogsDataWordBetween(ctx context.Context, address common.Ad AND substring(data from 32*:word_index_min+1 for 32) <= :word_value AND substring(data from 32*:word_index_max+1 for 32) >= :word_value AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -741,7 +743,7 @@ func (o *DSORM) SelectIndexedLogsTopicGreaterThan(ctx context.Context, address c AND event_sig = :event_sig AND topics[:topic_index] >= :topic_value_min AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -774,7 +776,7 @@ func (o *DSORM) SelectIndexedLogsTopicRange(ctx context.Context, address common. AND topics[:topic_index] >= :topic_value_min AND topics[:topic_index] <= :topic_value_max AND block_number <= %s - ORDER BY (evm.logs.block_number, evm.logs.log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -805,7 +807,7 @@ func (o *DSORM) SelectIndexedLogs(ctx context.Context, address common.Address, e AND event_sig = :event_sig AND topics[:topic_index] = ANY(:topic_values) AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -838,7 +840,7 @@ func (o *DSORM) SelectIndexedLogsByBlockRange(ctx context.Context, start, end in AND topics[:topic_index] = ANY(:topic_values) AND block_number >= :start_block AND block_number <= :end_block - ORDER BY (block_number, log_index)` + ORDER BY block_number, log_index` var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -872,7 +874,8 @@ func (o *DSORM) SelectIndexedLogsCreatedAfter(ctx context.Context, address commo AND topics[:topic_index] = ANY(:topic_values) AND block_timestamp > :block_timestamp_after AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index + `, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -901,7 +904,7 @@ func (o *DSORM) SelectIndexedLogsByTxHash(ctx context.Context, address common.Ad AND address = :address AND event_sig = :event_sig AND tx_hash = :tx_hash - ORDER BY (block_number, log_index)` + ORDER BY block_number, log_index` var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -949,7 +952,7 @@ func (o *DSORM) SelectIndexedLogsWithSigsExcluding(ctx context.Context, sigA, si AND b.event_sig = :sigB AND b.block_number BETWEEN :start_block AND :end_block AND b.block_number <= %s - ORDER BY block_number,log_index ASC`, nestedQuery, nestedQuery) + ORDER BY block_number, log_index`, nestedQuery, nestedQuery) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 08050c32167..3963538b2c3 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -21,7 +21,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 48a66de1ec3..daedbe64eb3 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1185,8 +1185,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb h1:nJ9dkgvX5vdpFWhYufnRUAiNvNHsXkoBL6C0bDerq/k= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/core/services/chainlink/config_database_test.go b/core/services/chainlink/config_database_test.go index 9cde07c9a63..b52d17452aa 100644 --- a/core/services/chainlink/config_database_test.go +++ b/core/services/chainlink/config_database_test.go @@ -14,6 +14,8 @@ import ( func TestDatabaseConfig(t *testing.T) { opts := GeneralConfigOpts{ ConfigStrings: []string{fullTOML}, + SecretsStrings: []string{`[Database] +URL = "postgresql://doesnotexist:justtopassvalidationtests@localhost:5432/chainlink_na_test"`}, } cfg, err := opts.New() require.NoError(t, err) diff --git a/core/services/chainlink/mocks/relayer_chain_interoperators.go b/core/services/chainlink/mocks/relayer_chain_interoperators.go index 6e47f6a1f9b..5b0815b6569 100644 --- a/core/services/chainlink/mocks/relayer_chain_interoperators.go +++ b/core/services/chainlink/mocks/relayer_chain_interoperators.go @@ -43,6 +43,10 @@ func (f *FakeRelayerChainInteroperators) Get(id types.RelayID) (loop.Relayer, er panic("unimplemented") } +func (f *FakeRelayerChainInteroperators) GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) { + panic("unimplemented") +} + func (f *FakeRelayerChainInteroperators) Slice() []loop.Relayer { return f.Relayers } diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index e17d4d516e9..3ed3c3242ba 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -8,6 +8,7 @@ import ( "sync" "github.com/smartcontractkit/chainlink-common/pkg/loop" + relay "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/adapters" @@ -16,7 +17,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/services" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) var ErrNoSuchRelayer = errors.New("relayer does not exist") @@ -183,6 +183,17 @@ func (rs *CoreRelayerChainInteroperators) Get(id types.RelayID) (loop.Relayer, e return lr, nil } +func (rs *CoreRelayerChainInteroperators) GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) { + rs.mu.Lock() + defer rs.mu.Unlock() + result := make(map[types.RelayID]loop.Relayer) + for id, relayer := range rs.loopRelayers { + result[id] = relayer + } + + return result, nil +} + // LegacyEVMChains returns a container with all the evm chains // TODO BCF-2511 func (rs *CoreRelayerChainInteroperators) LegacyEVMChains() legacyevm.LegacyChainContainer { diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 31645b7c54d..8bb06538f03 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -8,6 +8,7 @@ import ( "github.com/pelletier/go-toml/v2" "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" @@ -23,7 +24,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/plugins" diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index 7b4ab138e7c..ef55021dabf 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -73,6 +73,10 @@ func (g *relayGetter) Get(id types.RelayID) (loop.Relayer, error) { return evmrelayer.NewLoopRelayServerAdapter(g.r, g.e), nil } +func (g *relayGetter) GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) { + return map[types.RelayID]loop.Relayer{}, nil +} + func TestSpawner_CreateJobDeleteJob(t *testing.T) { t.Parallel() ctx := testutils.Context(t) diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 4e1eb0cc623..7747cad3360 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -25,26 +25,22 @@ import ( ocr2keepers20runner "github.com/smartcontractkit/chainlink-automation/pkg/v2/runner" ocr2keepers21config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" ocr2keepers21 "github.com/smartcontractkit/chainlink-automation/pkg/v3/plugin" - "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins/ocr3" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - - "github.com/smartcontractkit/chainlink/v2/core/config/env" - - "github.com/smartcontractkit/chainlink-vrf/altbn_128" - dkgpkg "github.com/smartcontractkit/chainlink-vrf/dkg" - "github.com/smartcontractkit/chainlink-vrf/ocr2vrf" - commonlogger "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" + "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins/ocr3" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - + "github.com/smartcontractkit/chainlink-vrf/altbn_128" + dkgpkg "github.com/smartcontractkit/chainlink-vrf/dkg" + "github.com/smartcontractkit/chainlink-vrf/ocr2vrf" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" coreconfig "github.com/smartcontractkit/chainlink/v2/core/config" + "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" @@ -71,7 +67,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" functionsRelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions" evmmercury "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" @@ -108,6 +103,7 @@ func (e ErrRelayNotEnabled) Error() string { type RelayGetter interface { Get(id types.RelayID) (loop.Relayer, error) + GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) } type Delegate struct { ds sqlutil.DataSource @@ -567,6 +563,11 @@ func (d *Delegate) newServicesGenericPlugin( return nil, ErrJobSpecNoRelayer{PluginName: pCfg.PluginName, Err: err} } + relayerSet, err := generic.NewRelayerSet(d.RelayGetter, jb.ExternalJobID, jb.ID, d.isNewlyCreatedJob) + if err != nil { + return nil, fmt.Errorf("failed to create relayer set: %w", err) + } + relayer, err := d.RelayGetter.Get(rid) if err != nil { return nil, ErrRelayNotEnabled{Err: err, Relay: spec.Relay, PluginName: pCfg.PluginName} @@ -620,7 +621,7 @@ func (d *Delegate) newServicesGenericPlugin( //TODO: remove this workaround when the EVM relayer is running inside of an LOOPP d.lggr.Info("provider is not a LOOPP provider, switching to provider server") - ps, err2 := relay.NewProviderServer(provider, types.OCR2PluginType(pCfg.ProviderType), d.lggr) + ps, err2 := loop.NewProviderServer(provider, types.OCR2PluginType(pCfg.ProviderType), d.lggr) if err2 != nil { return nil, fmt.Errorf("cannot start EVM provider server: %s", err2) } @@ -657,7 +658,7 @@ func (d *Delegate) newServicesGenericPlugin( switch pCfg.OCRVersion { case 2: plugin := reportingplugins.NewLOOPPService(pluginLggr, grpcOpts, cmdFn, pluginConfig, providerClientConn, pr, ta, - errorLog, keyValueStore) + errorLog, keyValueStore, relayerSet) oracleArgs := libocr2.OCR2OracleArgs{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, @@ -683,7 +684,7 @@ func (d *Delegate) newServicesGenericPlugin( case 3: //OCR3 with OCR2 OnchainKeyring and ContractTransmitter plugin := ocr3.NewLOOPPService(pluginLggr, grpcOpts, cmdFn, pluginConfig, providerClientConn, pr, ta, errorLog, - capabilitiesRegistry, keyValueStore) + capabilitiesRegistry, keyValueStore, relayerSet) contractTransmitter := ocrcommon.NewOCR3ContractTransmitterAdapter(provider.ContractTransmitter()) oracleArgs := libocr2.OCR3OracleArgs[[]byte]{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, diff --git a/core/services/ocr2/plugins/generic/relayerset.go b/core/services/ocr2/plugins/generic/relayerset.go new file mode 100644 index 00000000000..0586f600c50 --- /dev/null +++ b/core/services/ocr2/plugins/generic/relayerset.go @@ -0,0 +1,87 @@ +package generic + +import ( + "context" + "fmt" + + "github.com/google/uuid" + + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" +) + +type RelayGetter interface { + GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) +} + +type RelayerSet struct { + wrappedRelayers map[types.RelayID]core.Relayer +} + +func NewRelayerSet(relayGetter RelayGetter, externalJobID uuid.UUID, jobID int32, isNew bool) (*RelayerSet, error) { + + wrappedRelayers := map[types.RelayID]core.Relayer{} + + relayers, err := relayGetter.GetIDToRelayerMap() + if err != nil { + return nil, fmt.Errorf("failed to get relayers: %w", err) + } + + for id, relayer := range relayers { + wrappedRelayers[id] = relayerWrapper{Relayer: relayer, ExternalJobID: externalJobID, JobID: jobID, New: isNew} + } + + return &RelayerSet{wrappedRelayers: wrappedRelayers}, nil +} + +func (r *RelayerSet) Get(_ context.Context, id types.RelayID) (core.Relayer, error) { + if relayer, ok := r.wrappedRelayers[id]; ok { + return relayer, nil + } + + return nil, fmt.Errorf("relayer with id %s not found", id) +} + +func (r *RelayerSet) List(_ context.Context, relayIDs ...types.RelayID) (map[types.RelayID]core.Relayer, error) { + + if len(relayIDs) == 0 { + return r.wrappedRelayers, nil + } + + filterer := map[types.RelayID]bool{} + for _, id := range relayIDs { + filterer[id] = true + } + + result := map[types.RelayID]core.Relayer{} + for id, relayer := range r.wrappedRelayers { + if _, ok := filterer[id]; ok { + result[id] = relayer + } + } + + return result, nil +} + +type relayerWrapper struct { + loop.Relayer + ExternalJobID uuid.UUID + JobID int32 + New bool // Whether this is a first time job add. +} + +func (r relayerWrapper) NewPluginProvider(ctx context.Context, rargs core.RelayArgs, pargs core.PluginArgs) (types.PluginProvider, error) { + + relayArgs := types.RelayArgs{ + ExternalJobID: r.ExternalJobID, + JobID: r.JobID, + ContractID: rargs.ContractID, + New: r.New, + RelayConfig: rargs.RelayConfig, + ProviderType: rargs.ProviderType, + MercuryCredentials: rargs.MercuryCredentials, + } + + return r.Relayer.NewPluginProvider(ctx, relayArgs, types.PluginArgs(pargs)) +} diff --git a/core/services/ocr2/plugins/generic/relayerset_test.go b/core/services/ocr2/plugins/generic/relayerset_test.go new file mode 100644 index 00000000000..9aef7e29d78 --- /dev/null +++ b/core/services/ocr2/plugins/generic/relayerset_test.go @@ -0,0 +1,173 @@ +package generic + +import ( + "context" + "fmt" + "math/big" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" +) + +func TestRelayerSet_List(t *testing.T) { + + testRelayersMap := map[types.RelayID]loop.Relayer{} + testRelayersMap[types.RelayID{Network: "N1", ChainID: "C1"}] = &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N2", ChainID: "C2"}] = &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N3", ChainID: "C3"}] = &TestRelayer{} + + testGetter := TestRelayGetter{relayers: testRelayersMap} + + relayerSet, err := NewRelayerSet(testGetter, uuid.New(), 1, true) + assert.NoError(t, err) + relayers, err := relayerSet.List(context.Background()) + assert.NoError(t, err) + + assert.Equal(t, len(relayers), 3) + + relayers, err = relayerSet.List(context.Background(), types.RelayID{Network: "N1", ChainID: "C1"}, types.RelayID{Network: "N3", ChainID: "C3"}) + assert.NoError(t, err) + + assert.Equal(t, len(relayers), 2) + + _, ok := relayers[types.RelayID{Network: "N1", ChainID: "C1"}] + assert.True(t, ok) + + _, ok = relayers[types.RelayID{Network: "N3", ChainID: "C3"}] + assert.True(t, ok) +} + +func TestRelayerSet_Get(t *testing.T) { + + testRelayersMap := map[types.RelayID]loop.Relayer{} + testRelayersMap[types.RelayID{Network: "N1", ChainID: "C1"}] = &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N2", ChainID: "C2"}] = &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N3", ChainID: "C3"}] = &TestRelayer{} + + testGetter := TestRelayGetter{relayers: testRelayersMap} + + relayerSet, err := NewRelayerSet(testGetter, uuid.New(), 1, true) + assert.NoError(t, err) + + _, err = relayerSet.Get(context.Background(), types.RelayID{Network: "N1", ChainID: "C1"}) + assert.NoError(t, err) + + _, err = relayerSet.Get(context.Background(), types.RelayID{Network: "N4", ChainID: "C4"}) + assert.NotNil(t, err) +} + +func TestRelayerSet_NewPluginProvider(t *testing.T) { + testRelayersMap := map[types.RelayID]loop.Relayer{} + testRelayer := &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N1", ChainID: "C1"}] = testRelayer + testRelayersMap[types.RelayID{Network: "N2", ChainID: "C2"}] = &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N3", ChainID: "C3"}] = &TestRelayer{} + + testGetter := TestRelayGetter{relayers: testRelayersMap} + + externalJobID := uuid.New() + relayerSet, err := NewRelayerSet(testGetter, externalJobID, 1, true) + assert.NoError(t, err) + + relayer, err := relayerSet.Get(context.Background(), types.RelayID{Network: "N1", ChainID: "C1"}) + assert.NoError(t, err) + + _, err = relayer.NewPluginProvider(context.Background(), core.RelayArgs{ + ContractID: "c1", + RelayConfig: []byte("relayconfig"), + ProviderType: "p1", + MercuryCredentials: &types.MercuryCredentials{ + LegacyURL: "legacy", + URL: "url", + Username: "user", + Password: "pass", + }, + }, core.PluginArgs{ + TransmitterID: "t1", + PluginConfig: []byte("pluginconfig"), + }) + assert.NoError(t, err) + + assert.Equal(t, types.RelayArgs{ + ExternalJobID: externalJobID, + JobID: 1, + ContractID: "c1", + New: true, + RelayConfig: []byte("relayconfig"), + ProviderType: "p1", + MercuryCredentials: &types.MercuryCredentials{ + LegacyURL: "legacy", + URL: "url", + Username: "user", + Password: "pass", + }, + }, testRelayer.relayArgs) + + assert.Equal(t, types.PluginArgs{ + TransmitterID: "t1", + PluginConfig: []byte("pluginconfig"), + }, testRelayer.pluginArgs) +} + +type TestRelayGetter struct { + relayers map[types.RelayID]loop.Relayer +} + +func (t TestRelayGetter) Get(id types.RelayID) (loop.Relayer, error) { + if relayer, ok := t.relayers[id]; ok { + return relayer, nil + } + + return nil, fmt.Errorf("relayer with id %s not found", id) +} + +func (t TestRelayGetter) GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) { + return t.relayers, nil +} + +type TestRelayer struct { + relayArgs types.RelayArgs + pluginArgs types.PluginArgs +} + +func (t *TestRelayer) NewPluginProvider(ctx context.Context, args types.RelayArgs, args2 types.PluginArgs) (types.PluginProvider, error) { + t.relayArgs = args + t.pluginArgs = args2 + + return nil, nil +} + +func (t *TestRelayer) Name() string { panic("implement me") } + +func (t *TestRelayer) Start(ctx context.Context) error { panic("implement me") } + +func (t *TestRelayer) Close() error { panic("implement me") } + +func (t *TestRelayer) Ready() error { panic("implement me") } + +func (t *TestRelayer) HealthReport() map[string]error { panic("implement me") } + +func (t *TestRelayer) GetChainStatus(ctx context.Context) (types.ChainStatus, error) { + panic("implement me") +} + +func (t *TestRelayer) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []types.NodeStatus, nextPageToken string, total int, err error) { + panic("implement me") +} + +func (t *TestRelayer) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { + panic("implement me") +} + +func (t *TestRelayer) NewConfigProvider(ctx context.Context, args types.RelayArgs) (types.ConfigProvider, error) { + panic("implement me") +} + +func (t *TestRelayer) NewLLOProvider(ctx context.Context, args types.RelayArgs, args2 types.PluginArgs) (types.LLOProvider, error) { + panic("implement me") +} diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go index 0bb7a0ca2ba..4f927faa009 100644 --- a/core/services/ocrbootstrap/delegate.go +++ b/core/services/ocrbootstrap/delegate.go @@ -22,6 +22,7 @@ import ( type RelayGetter interface { Get(types.RelayID) (loop.Relayer, error) + GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) } // Delegate creates Bootstrap jobs diff --git a/core/services/relay/evm/contract_transmitter.go b/core/services/relay/evm/contract_transmitter.go index af0f83f6979..724bbbe4aa0 100644 --- a/core/services/relay/evm/contract_transmitter.go +++ b/core/services/relay/evm/contract_transmitter.go @@ -5,6 +5,7 @@ import ( "database/sql" "encoding/hex" "math/big" + "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" @@ -63,13 +64,29 @@ func NewOCRContractTransmitter( lp logpoller.LogPoller, lggr logger.Logger, reportToEvmTxMeta ReportToEthMetadata, +) (*contractTransmitter, error) { + return NewOCRContractTransmitterWithRetention(ctx, address, caller, contractABI, transmitter, lp, lggr, reportToEvmTxMeta, 0) +} + +func NewOCRContractTransmitterWithRetention( + ctx context.Context, + address gethcommon.Address, + caller contractReader, + contractABI abi.ABI, + transmitter Transmitter, + lp logpoller.LogPoller, + lggr logger.Logger, + reportToEvmTxMeta ReportToEthMetadata, + retention time.Duration, ) (*contractTransmitter, error) { transmitted, ok := contractABI.Events["Transmitted"] if !ok { return nil, errors.New("invalid ABI, missing transmitted") } - err := lp.RegisterFilter(ctx, logpoller.Filter{Name: transmitterFilterName(address), EventSigs: []common.Hash{transmitted.ID}, Addresses: []common.Address{address}}) + // TODO It would be better to keep MaxLogsKept = 1 for the OCR contract transmitter instead of Retention. We are always interested only in the latest log. + // Although MaxLogsKept is present in the Filter struct, it is not supported by LogPoller yet. + err := lp.RegisterFilter(ctx, logpoller.Filter{Name: transmitterFilterName(address), EventSigs: []common.Hash{transmitted.ID}, Addresses: []common.Address{address}, Retention: retention}) if err != nil { return nil, err } diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 737a8e7561e..585d20df3ab 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -7,6 +7,7 @@ import ( "fmt" "strings" "sync" + "time" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -172,7 +173,7 @@ func (r *Relayer) NewPluginProvider(rargs commontypes.RelayArgs, pargs commontyp return nil, err } - transmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) + transmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI, 0) if err != nil { return nil, err } @@ -476,7 +477,7 @@ type configTransmitterOpts struct { } // newOnChainContractTransmitter creates a new contract transmitter. -func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rargs commontypes.RelayArgs, transmitterID string, ethKeystore keystore.Eth, configWatcher *configWatcher, opts configTransmitterOpts, transmissionContractABI abi.ABI) (*contractTransmitter, error) { +func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rargs commontypes.RelayArgs, transmitterID string, ethKeystore keystore.Eth, configWatcher *configWatcher, opts configTransmitterOpts, transmissionContractABI abi.ABI, transmissionContractRetention time.Duration) (*contractTransmitter, error) { var relayConfig types.RelayConfig if err := json.Unmarshal(rargs.RelayConfig, &relayConfig); err != nil { return nil, err @@ -540,7 +541,7 @@ func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rarg return nil, pkgerrors.Wrap(err, "failed to create transmitter") } - return NewOCRContractTransmitter( + return NewOCRContractTransmitterWithRetention( ctx, configWatcher.contractAddress, configWatcher.chain.Client(), @@ -549,6 +550,7 @@ func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rarg configWatcher.chain.LogPoller(), lggr, nil, + transmissionContractRetention, ) } @@ -578,7 +580,7 @@ func (r *Relayer) NewMedianProvider(rargs commontypes.RelayArgs, pargs commontyp reportCodec := evmreportcodec.ReportCodec{} - contractTransmitter, err := newOnChainContractTransmitter(ctx, lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) + contractTransmitter, err := newOnChainContractTransmitter(ctx, lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI, 0) if err != nil { return nil, err } diff --git a/core/services/relay/evm/loop_impl.go b/core/services/relay/evm/loop_impl.go index 57a09dd49ae..7f9d405847d 100644 --- a/core/services/relay/evm/loop_impl.go +++ b/core/services/relay/evm/loop_impl.go @@ -2,9 +2,9 @@ package evm import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" + relay "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) //go:generate mockery --quiet --name LoopRelayAdapter --output ./mocks/ --case=underscore diff --git a/core/services/relay/evm/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go index 78f4b43b43f..a839ce8430e 100644 --- a/core/services/relay/evm/ocr2keeper.go +++ b/core/services/relay/evm/ocr2keeper.go @@ -91,7 +91,7 @@ func (r *ocr2keeperRelayer) NewOCR2KeeperProvider(rargs commontypes.RelayArgs, p } gasLimit := cfgWatcher.chain.Config().EVM().OCR2().Automation().GasLimit() - contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, cfgWatcher, configTransmitterOpts{pluginGasLimit: &gasLimit}, OCR2AggregatorTransmissionContractABI) + contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, cfgWatcher, configTransmitterOpts{pluginGasLimit: &gasLimit}, OCR2AggregatorTransmissionContractABI, 0) if err != nil { return nil, err } diff --git a/core/services/relay/evm/ocr2vrf.go b/core/services/relay/evm/ocr2vrf.go index a108151be47..b83ce0fd81e 100644 --- a/core/services/relay/evm/ocr2vrf.go +++ b/core/services/relay/evm/ocr2vrf.go @@ -64,7 +64,7 @@ func (r *ocr2vrfRelayer) NewDKGProvider(rargs commontypes.RelayArgs, pargs commo if err != nil { return nil, err } - contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) + contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI, 0) if err != nil { return nil, err } @@ -91,7 +91,7 @@ func (r *ocr2vrfRelayer) NewOCR2VRFProvider(rargs commontypes.RelayArgs, pargs c if err != nil { return nil, err } - contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) + contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI, 0) if err != nil { return nil, err } diff --git a/core/services/relay/evm/relayer_extender.go b/core/services/relay/evm/relayer_extender.go index 83f03b47f9e..5f49a0b16c9 100644 --- a/core/services/relay/evm/relayer_extender.go +++ b/core/services/relay/evm/relayer_extender.go @@ -8,7 +8,7 @@ import ( "github.com/pkg/errors" "go.uber.org/multierr" - "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -19,7 +19,7 @@ import ( var ErrNoChains = errors.New("no EVM chains loaded") type EVMChainRelayerExtender interface { - loop.RelayerExt + relay.RelayerExt Chain() legacyevm.Chain } diff --git a/core/services/relay/grpc_provider_server.go b/core/services/relay/grpc_provider_server.go deleted file mode 100644 index 67bbb8c6c2a..00000000000 --- a/core/services/relay/grpc_provider_server.go +++ /dev/null @@ -1,68 +0,0 @@ -package relay - -import ( - "context" - "net" - - "go.uber.org/multierr" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - - "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -type ProviderServer struct { - s *grpc.Server - lis net.Listener - lggr logger.Logger - conns []*grpc.ClientConn -} - -func (p *ProviderServer) Start(ctx context.Context) error { - p.serve() - return nil -} - -func (p *ProviderServer) Close() error { - var err error - for _, c := range p.conns { - err = multierr.Combine(err, c.Close()) - } - p.s.Stop() - return err -} - -func (p *ProviderServer) GetConn() (*grpc.ClientConn, error) { - cc, err := grpc.Dial(p.lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) - p.conns = append(p.conns, cc) - return cc, err -} - -// NewProviderServer creates a GRPC server that will wrap a provider, this is a workaround to test the Node API PoC until the EVM relayer is loopifyed -func NewProviderServer(p types.PluginProvider, pType types.OCR2PluginType, lggr logger.Logger) (*ProviderServer, error) { - lis, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return nil, err - } - ps := ProviderServer{ - s: grpc.NewServer(), - lis: lis, - lggr: lggr.Named("EVM.ProviderServer"), - } - err = loop.RegisterStandAloneProvider(ps.s, p, pType) - if err != nil { - return nil, err - } - - return &ps, nil -} - -func (p *ProviderServer) serve() { - go func() { - if err := p.s.Serve(p.lis); err != nil { - p.lggr.Errorf("Failed to serve EVM provider server: %v", err) - } - }() -} diff --git a/core/services/relay/grpc_provider_server_test.go b/core/services/relay/grpc_provider_server_test.go deleted file mode 100644 index 72bbbca0f44..00000000000 --- a/core/services/relay/grpc_provider_server_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package relay - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-common/pkg/types" - - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -func TestProviderServer(t *testing.T) { - r := &mockRelayer{} - sa := NewServerAdapter(r, mockRelayerExt{}) - mp, _ := sa.NewPluginProvider(testutils.Context(t), types.RelayArgs{ProviderType: string(types.Median)}, types.PluginArgs{}) - - lggr := logger.TestLogger(t) - _, err := NewProviderServer(mp, "unsupported-type", lggr) - require.ErrorContains(t, err, "unsupported-type") - - ps, err := NewProviderServer(staticMedianProvider{}, types.Median, lggr) - require.NoError(t, err) - - _, err = ps.GetConn() - require.NoError(t, err) -} diff --git a/core/services/relay/relay.go b/core/services/relay/relay.go deleted file mode 100644 index b4cc4517390..00000000000 --- a/core/services/relay/relay.go +++ /dev/null @@ -1,38 +0,0 @@ -package relay - -import ( - "context" - "fmt" - - "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/types" -) - -// ServerAdapter extends [loop.RelayerAdapter] by overriding NewPluginProvider to dispatches calls according to `RelayArgs.ProviderType`. -// This should only be used to adapt relayers not running via GRPC in a LOOPP. -type ServerAdapter struct { - loop.RelayerAdapter -} - -// NewServerAdapter returns a new ServerAdapter. -func NewServerAdapter(r types.Relayer, e loop.RelayerExt) *ServerAdapter { //nolint:staticcheck - return &ServerAdapter{RelayerAdapter: loop.RelayerAdapter{Relayer: r, RelayerExt: e}} -} - -func (r *ServerAdapter) NewPluginProvider(ctx context.Context, rargs types.RelayArgs, pargs types.PluginArgs) (types.PluginProvider, error) { - switch types.OCR2PluginType(rargs.ProviderType) { - case types.Median: - return r.NewMedianProvider(ctx, rargs, pargs) - case types.Functions: - return r.NewFunctionsProvider(ctx, rargs, pargs) - case types.Mercury: - return r.NewMercuryProvider(ctx, rargs, pargs) - case types.OCR2Keeper: - return r.NewAutomationProvider(ctx, rargs, pargs) - case types.DKG, types.OCR2VRF, types.GenericPlugin: - return r.RelayerAdapter.NewPluginProvider(ctx, rargs, pargs) - case types.LLO, types.CCIPCommit, types.CCIPExecution: - return nil, fmt.Errorf("provider type not supported: %s", rargs.ProviderType) - } - return nil, fmt.Errorf("provider type not recognized: %s", rargs.ProviderType) -} diff --git a/core/services/relay/relay_test.go b/core/services/relay/relay_test.go deleted file mode 100644 index c0b2248ed1a..00000000000 --- a/core/services/relay/relay_test.go +++ /dev/null @@ -1,191 +0,0 @@ -package relay - -import ( - "context" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" - ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/types" - - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" -) - -type staticMedianProvider struct { -} - -var _ types.MedianProvider = staticMedianProvider{} - -// ContractConfigTracker implements types.MedianProvider. -func (s staticMedianProvider) ContractConfigTracker() ocr2types.ContractConfigTracker { - return nil -} - -// ContractTransmitter implements types.MedianProvider. -func (s staticMedianProvider) ContractTransmitter() ocr2types.ContractTransmitter { - return nil -} - -// MedianContract implements types.MedianProvider. -func (s staticMedianProvider) MedianContract() median.MedianContract { - return nil -} - -// OffchainConfigDigester implements types.MedianProvider. -func (s staticMedianProvider) OffchainConfigDigester() ocr2types.OffchainConfigDigester { - return nil -} - -// OnchainConfigCodec implements types.MedianProvider. -func (s staticMedianProvider) OnchainConfigCodec() median.OnchainConfigCodec { - return nil -} - -// ReportCodec implements types.MedianProvider. -func (s staticMedianProvider) ReportCodec() median.ReportCodec { - return nil -} - -// ChainReader implements types.MedianProvider. -func (s staticMedianProvider) ChainReader() types.ChainReader { - return nil -} - -// Close implements types.MedianProvider. -func (s staticMedianProvider) Close() error { - return nil -} - -// Codec implements types.MedianProvider. -func (s staticMedianProvider) Codec() types.Codec { - return nil -} - -// HealthReport implements types.MedianProvider. -func (s staticMedianProvider) HealthReport() map[string]error { - return nil -} - -// Name implements types.MedianProvider. -func (s staticMedianProvider) Name() string { - return "" -} - -// Ready implements types.MedianProvider. -func (s staticMedianProvider) Ready() error { - return nil -} - -// Start implements types.MedianProvider. -func (s staticMedianProvider) Start(context.Context) error { - return nil -} - -type staticFunctionsProvider struct { - types.FunctionsProvider -} - -type staticMercuryProvider struct { - types.MercuryProvider -} - -type staticAutomationProvider struct { - types.AutomationProvider -} - -type staticPluginProvider struct { - types.PluginProvider -} - -type mockRelayer struct { - types.Relayer -} - -func (m *mockRelayer) NewMedianProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.MedianProvider, error) { - return staticMedianProvider{}, nil -} - -func (m *mockRelayer) NewFunctionsProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.FunctionsProvider, error) { - return staticFunctionsProvider{}, nil -} - -func (m *mockRelayer) NewMercuryProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.MercuryProvider, error) { - return staticMercuryProvider{}, nil -} - -func (m *mockRelayer) NewAutomationProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.AutomationProvider, error) { - return staticAutomationProvider{}, nil -} - -func (m *mockRelayer) NewPluginProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.PluginProvider, error) { - return staticPluginProvider{}, nil -} - -type mockRelayerExt struct { - loop.RelayerExt -} - -func isType[T any](p any) bool { - _, ok := p.(T) - return ok -} - -func TestRelayerServerAdapter(t *testing.T) { - r := &mockRelayer{} - sa := NewServerAdapter(r, mockRelayerExt{}) - - testCases := []struct { - ProviderType string - Test func(p any) bool - Error string - }{ - { - ProviderType: string(types.Median), - Test: isType[types.MedianProvider], - }, - { - ProviderType: string(types.Functions), - Test: isType[types.FunctionsProvider], - }, - { - ProviderType: string(types.Mercury), - Test: isType[types.MercuryProvider], - }, - { - ProviderType: string(types.CCIPCommit), - Error: "provider type not supported", - }, - { - ProviderType: string(types.CCIPExecution), - Error: "provider type not supported", - }, - { - ProviderType: "unknown", - Error: "provider type not recognized", - }, - { - ProviderType: string(types.GenericPlugin), - Test: isType[types.PluginProvider], - }, - } - - ctx := testutils.Context(t) - for _, tc := range testCases { - pp, err := sa.NewPluginProvider( - ctx, - types.RelayArgs{ProviderType: tc.ProviderType}, - types.PluginArgs{}, - ) - - if tc.Error != "" { - assert.ErrorContains(t, err, tc.Error) - } else { - assert.NoError(t, err) - assert.True(t, tc.Test(pp)) - } - } -} diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 0ecc311acac..040e123567e 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -45,6 +45,14 @@ type Engine struct { // Used for testing to wait for an execution to complete xxxExecutionFinished chan string + // testing lifecycle hook to signal initialization status + afterInit func(success bool) + // Used for testing to control the number of retries + // we'll do when initializing the engine. + maxRetries int + // Used for testing to control the retry interval + // when initializing the engine. + retryMs int } func (e *Engine) Start(ctx context.Context) error { @@ -60,94 +68,67 @@ func (e *Engine) Start(ctx context.Context) error { }) } -// init does the following: -// -// 1. Resolves the underlying capability for each trigger -// 2. Registers each step's capability to this workflow -// 3. Registers for trigger events now that all capabilities are resolved +// resolveWorkflowCapabilities does the following: // -// Steps 1 and 2 are retried every 5 seconds until successful. -func (e *Engine) init(ctx context.Context) { - defer e.wg.Done() - - retrySec := 5 - ticker := time.NewTicker(time.Duration(retrySec) * time.Second) - defer ticker.Stop() - -LOOP: - for { - select { - case <-ctx.Done(): - return - case <-ticker.C: - initSuccessful := true - // Resolve the underlying capability for each trigger - for _, t := range e.workflow.triggers { - tg, err := e.registry.GetTrigger(ctx, t.Type) - if err != nil { - initSuccessful = false - e.logger.Errorf("failed to get trigger capability: %s, retrying in %d seconds", err, retrySec) - continue - } - t.trigger = tg - } - if !initSuccessful { - continue - } - - // Walk the graph and initialize each step. - // This means: - // - fetching the capability - // - register the capability to this workflow - // - initializing the step's executionStrategy - err := e.workflow.walkDo(keywordTrigger, func(s *step) error { - // The graph contains a dummy step for triggers, but - // we handle triggers separately since there might be more than one. - if s.Ref == keywordTrigger { - return nil - } - - err := e.initializeCapability(ctx, s, retrySec) - if err != nil { - return err - } - - return e.initializeExecutionStrategy(s) - }) - if err != nil { - initSuccessful = false - e.logger.Error(err) - } - - if initSuccessful { - break LOOP - } +// 1. Resolves the underlying capability for each trigger +// 2. Registers each step's capability to this workflow +func (e *Engine) resolveWorkflowCapabilities(ctx context.Context) error { + // + // Step 1. Resolve the underlying capability for each trigger + // + triggersInitialized := true + for _, t := range e.workflow.triggers { + tg, err := e.registry.GetTrigger(ctx, t.Type) + if err != nil { + e.logger.Errorf("failed to get trigger capability: %s", err) + // we don't immediately return here, since we want to retry all triggers + // to notify the user of all errors at once. + triggersInitialized = false + } else { + t.trigger = tg } } + if !triggersInitialized { + return fmt.Errorf("failed to resolve triggers") + } + + // Step 2. Walk the graph and register each step's capability to this workflow + // + // This means: + // - fetching the capability + // - register the capability to this workflow + // - initializing the step's executionStrategy + capabilityRegistrationErr := e.workflow.walkDo(keywordTrigger, func(s *step) error { + // The graph contains a dummy step for triggers, but + // we handle triggers separately since there might be more than one + // trigger registered to a workflow. + if s.Ref == keywordTrigger { + return nil + } - // We have all needed capabilities, now we can register for trigger events - for _, t := range e.workflow.triggers { - err := e.registerTrigger(ctx, t) + err := e.initializeCapability(ctx, s) if err != nil { - e.logger.Errorf("failed to register trigger: %s", err) + return err } - } - e.logger.Info("engine initialized") + return e.initializeExecutionStrategy(s) + }) + + return capabilityRegistrationErr } -func (e *Engine) initializeCapability(ctx context.Context, s *step, retrySec int) error { +func (e *Engine) initializeCapability(ctx context.Context, s *step) error { // If the capability already exists, that means we've already registered it if s.capability != nil { return nil } - cp, innerErr := e.registry.Get(ctx, s.Type) - if innerErr != nil { - return fmt.Errorf("failed to get capability with ref %s: %s, retrying in %d seconds", s.Type, innerErr, retrySec) + cp, err := e.registry.Get(ctx, s.Type) + if err != nil { + return fmt.Errorf("failed to get capability with ref %s: %s", s.Type, err) } - // We only need to configure actions, consensus and targets here, and + // We configure actions, consensus and targets here, and // they all satisfy the `CallbackCapability` interface cc, ok := cp.(capabilities.CallbackCapability) if !ok { @@ -155,29 +136,65 @@ func (e *Engine) initializeCapability(ctx context.Context, s *step, retrySec int } if s.config == nil { - configMap, ierr := values.NewMap(s.Config) - if ierr != nil { - return fmt.Errorf("failed to convert config to values.Map: %s", ierr) + configMap, newMapErr := values.NewMap(s.Config) + if newMapErr != nil { + return fmt.Errorf("failed to convert config to values.Map: %s", newMapErr) } s.config = configMap } - reg := capabilities.RegisterToWorkflowRequest{ + registrationRequest := capabilities.RegisterToWorkflowRequest{ Metadata: capabilities.RegistrationMetadata{ WorkflowID: e.workflow.id, }, Config: s.config, } - innerErr = cc.RegisterToWorkflow(ctx, reg) - if innerErr != nil { - return fmt.Errorf("failed to register to workflow (%+v): %w", reg, innerErr) + err = cc.RegisterToWorkflow(ctx, registrationRequest) + if err != nil { + return fmt.Errorf("failed to register to workflow (%+v): %w", registrationRequest, err) } s.capability = cc return nil } +// init does the following: +// +// 1. Resolves the underlying capability for each trigger +// 2. Registers each step's capability to this workflow +// 3. Registers for trigger events now that all capabilities are resolved +// +// Steps 1 and 2 are retried every 5 seconds until successful. +func (e *Engine) init(ctx context.Context) { + defer e.wg.Done() + + retryErr := retryable(ctx, e.logger, e.retryMs, e.maxRetries, func() error { + err := e.resolveWorkflowCapabilities(ctx) + if err != nil { + return fmt.Errorf("failed to resolve workflow: %s", err) + } + return nil + }) + + if retryErr != nil { + e.logger.Errorf("initialization failed: %s", retryErr) + e.afterInit(false) + return + } + + e.logger.Debug("capabilities resolved, registering triggers") + for _, t := range e.workflow.triggers { + err := e.registerTrigger(ctx, t) + if err != nil { + e.logger.Errorf("failed to register trigger: %s", err) + } + } + + e.logger.Info("engine initialized") + e.afterInit(true) +} + // initializeExecutionStrategy for `step`. // Broadly speaking, we'll use `immediateExecution` for non-target steps // and `scheduledExecution` for targets. If we don't have the necessary @@ -609,6 +626,7 @@ func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability) er func (e *Engine) Close() error { return e.StopOnce("Engine", func() error { + e.logger.Info("shutting down engine") ctx := context.Background() // To shut down the engine, we'll start by deregistering // any triggers to ensure no new executions are triggered, @@ -668,6 +686,11 @@ type Config struct { NewWorkerTimeout time.Duration DONInfo *capabilities.DON PeerID func() *p2ptypes.PeerID + + // For testing purposes only + maxRetries int + retryMs int + afterInit func(success bool) } const ( @@ -689,6 +712,14 @@ func NewEngine(cfg Config) (engine *Engine, err error) { cfg.NewWorkerTimeout = defaultNewWorkerTimeout } + if cfg.retryMs == 0 { + cfg.retryMs = 5000 + } + + if cfg.afterInit == nil { + cfg.afterInit = func(success bool) {} + } + // TODO: validation of the workflow spec // We'll need to check, among other things: // - that there are no step `ref` called `trigger` as this is reserved for any triggers @@ -718,14 +749,18 @@ func NewEngine(cfg Config) (engine *Engine, err error) { DON: cfg.DONInfo, PeerID: cfg.PeerID, }, - executionStates: newInMemoryStore(), - pendingStepRequests: make(chan stepRequest, cfg.QueueSize), - newWorkerCh: newWorkerCh, - stepUpdateCh: make(chan stepState), - triggerEvents: make(chan capabilities.CapabilityResponse), - stopCh: make(chan struct{}), - newWorkerTimeout: cfg.NewWorkerTimeout, + executionStates: newInMemoryStore(), + pendingStepRequests: make(chan stepRequest, cfg.QueueSize), + newWorkerCh: newWorkerCh, + stepUpdateCh: make(chan stepState), + triggerEvents: make(chan capabilities.CapabilityResponse), + stopCh: make(chan struct{}), + newWorkerTimeout: cfg.NewWorkerTimeout, + // For testing purposes only xxxExecutionFinished: make(chan string), + afterInit: cfg.afterInit, + maxRetries: cfg.maxRetries, + retryMs: cfg.retryMs, } return engine, nil } diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index d82c9d4b7d2..4821b5800c7 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -65,6 +65,44 @@ targets: abi: "receive(report bytes)" ` +// newTestEngine creates a new engine with some test defaults. +func newTestEngine(t *testing.T, reg *coreCap.Registry, spec string) (eng *Engine, initFailed chan struct{}) { + peerID := p2ptypes.PeerID{} + initFailed = make(chan struct{}) + cfg := Config{ + Lggr: logger.TestLogger(t), + Registry: reg, + Spec: spec, + DONInfo: nil, + PeerID: func() *p2ptypes.PeerID { return &peerID }, + maxRetries: 1, + retryMs: 100, + afterInit: func(success bool) { + if !success { + close(initFailed) + } + }, + } + eng, err := NewEngine(cfg) + require.NoError(t, err) + return eng, initFailed +} + +// getExecutionId returns the execution id of the workflow that is +// currently being executed by the engine. +// +// If the engine fails to initialize, the test will fail rather +// than blocking indefinitely. +func getExecutionId(t *testing.T, eng *Engine, initFailed <-chan struct{}) string { + var eid string + select { + case <-initFailed: + t.FailNow() + case eid = <-eng.xxxExecutionFinished: + } + return eid +} + type mockCapability struct { capabilities.CapabilityInfo capabilities.CallbackExecutable @@ -148,23 +186,13 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { ) require.NoError(t, reg.Add(ctx, target2)) - lggr := logger.TestLogger(t) - peerID := p2ptypes.PeerID{} - cfg := Config{ - Lggr: lggr, - Registry: reg, - Spec: hardcodedWorkflow, - DONInfo: nil, - PeerID: func() *p2ptypes.PeerID { return &peerID }, - } - eng, err := NewEngine(cfg) - require.NoError(t, err) + eng, initFailed := newTestEngine(t, reg, hardcodedWorkflow) - err = eng.Start(ctx) + err := eng.Start(ctx) require.NoError(t, err) defer eng.Close() - eid := <-eng.xxxExecutionFinished + eid := getExecutionId(t, eng, initFailed) assert.Equal(t, cr, <-target1.response) assert.Equal(t, cr, <-target2.response) @@ -312,22 +340,13 @@ func TestEngine_ErrorsTheWorkflowIfAStepErrors(t *testing.T) { require.NoError(t, reg.Add(ctx, mockFailingConsensus())) require.NoError(t, reg.Add(ctx, mockTarget())) - peerID := p2ptypes.PeerID{} - cfg := Config{ - Lggr: logger.TestLogger(t), - Registry: reg, - Spec: simpleWorkflow, - DONInfo: nil, - PeerID: func() *p2ptypes.PeerID { return &peerID }, - } - eng, err := NewEngine(cfg) - require.NoError(t, err) + eng, initFailed := newTestEngine(t, reg, simpleWorkflow) - err = eng.Start(ctx) + err := eng.Start(ctx) require.NoError(t, err) defer eng.Close() - eid := <-eng.xxxExecutionFinished + eid := getExecutionId(t, eng, initFailed) state, err := eng.executionStates.get(ctx, eid) require.NoError(t, err) @@ -420,22 +439,12 @@ func TestEngine_MultiStepDependencies(t *testing.T) { action, out := mockAction() require.NoError(t, reg.Add(ctx, action)) - peerID := p2ptypes.PeerID{} - cfg := Config{ - Lggr: logger.TestLogger(t), - Registry: reg, - Spec: multiStepWorkflow, - DONInfo: nil, - PeerID: func() *p2ptypes.PeerID { return &peerID }, - } - eng, err := NewEngine(cfg) - require.NoError(t, err) - - err = eng.Start(ctx) + eng, initFailed := newTestEngine(t, reg, multiStepWorkflow) + err := eng.Start(ctx) require.NoError(t, err) defer eng.Close() - eid := <-eng.xxxExecutionFinished + eid := getExecutionId(t, eng, initFailed) state, err := eng.executionStates.get(ctx, eid) require.NoError(t, err) diff --git a/core/services/workflows/retry.go b/core/services/workflows/retry.go new file mode 100644 index 00000000000..e3f04353e7f --- /dev/null +++ b/core/services/workflows/retry.go @@ -0,0 +1,53 @@ +package workflows + +import ( + "context" + "fmt" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +// retryable is a helper function that retries a function until it succeeds. +// +// It will retry every `retryMs` milliseconds, up to `maxRetries` times. +// +// If `maxRetries` is 0, it will retry indefinitely. +// +// retryable will return an error in the following conditions: +// - the context is cancelled: the error returned is the context error +// - the retry limit has been hit: the error returned is the last error returned by `fn` +func retryable(ctx context.Context, lggr logger.Logger, retryMs int, maxRetries int, fn func() error) error { + ticker := time.NewTicker(time.Duration(retryMs) * time.Millisecond) + defer ticker.Stop() + + // immediately try once + err := fn() + if err == nil { + return nil + } + retries := 0 + + for { + // if maxRetries is 0, we'll retry indefinitely + if maxRetries > 0 { + if retries >= maxRetries { + lggr.Errorf("%s", err) + return fmt.Errorf("max retries reached, aborting") + } + } + lggr.Errorf("%s, retrying in %.2fs", err, float64(retryMs)/1000) + + select { + case <-ctx.Done(): + return ctx.Err() + case <-ticker.C: + err = fn() + if err == nil { + return nil + } + } + + retries++ + } +} diff --git a/core/services/workflows/retryable_test.go b/core/services/workflows/retryable_test.go new file mode 100644 index 00000000000..1a17ac55fae --- /dev/null +++ b/core/services/workflows/retryable_test.go @@ -0,0 +1,113 @@ +package workflows + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestRetryableZeroMaxRetries(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) + defer cancel() + + fn := func() error { + return errors.New("test error") + } + + err := retryable(ctx, logger.NullLogger, 100, 0, fn) + assert.ErrorIs(t, err, context.DeadlineExceeded, "Expected context deadline exceeded error") +} + +func TestRetryableSuccessOnFirstAttempt(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + fn := func() error { + return nil + } + + err := retryable(ctx, logger.NullLogger, 100, 3, fn) + require.NoError(t, err, "Expected no error as function succeeds on first attempt") +} + +func TestRetryableSuccessAfterRetries(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + retries := 0 + fn := func() error { + if retries < 2 { + retries++ + return errors.New("test error") + } + return nil + } + + err := retryable(ctx, logger.NullLogger, 100, 5, fn) + assert.NoError(t, err, "Expected no error after successful retry") + assert.Equal(t, 2, retries, "Expected two retries before success") +} + +func TestRetryableErrorOnFirstTryNoRetries(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + fn := func() error { + return errors.New("immediate failure") + } + + err := retryable(ctx, logger.NullLogger, 100, 1, fn) + require.Error(t, err, "Expected an error on the first try with no retries allowed") + assert.Equal(t, "max retries reached, aborting", err.Error(), "Expected function to abort after the first try") +} + +func TestRetryableErrorAfterMultipleRetries(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + attempts := 0 + fn := func() error { + attempts++ + return errors.New("persistent error") + } + + maxRetries := 3 + err := retryable(ctx, logger.NullLogger, 100, maxRetries, fn) + require.Error(t, err, "Expected an error after multiple retries") + assert.Equal(t, "max retries reached, aborting", err.Error(), "Expected the max retries reached error message") + assert.Equal(t, maxRetries+1, attempts, "Expected the function to be executed retry + 1 times") +} + +func TestRetryableCancellationHandling(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + + fn := func() error { + return errors.New("test error") + } + + go func() { + time.Sleep(150 * time.Millisecond) + cancel() + }() + + err := retryable(ctx, logger.NullLogger, 100, 5, fn) + assert.ErrorIs(t, err, context.Canceled, "Expected context cancellation error") +} diff --git a/go.mod b/go.mod index 6e081467bc0..3e691e95405 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab @@ -353,5 +353,4 @@ replace ( // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f - ) diff --git a/go.sum b/go.sum index 50cb9f3b44f..90faeacb057 100644 --- a/go.sum +++ b/go.sum @@ -1180,8 +1180,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb h1:nJ9dkgvX5vdpFWhYufnRUAiNvNHsXkoBL6C0bDerq/k= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/contracts/contract_deployer.go b/integration-tests/contracts/contract_deployer.go index c85c927b8d4..e2511c7292e 100644 --- a/integration-tests/contracts/contract_deployer.go +++ b/integration-tests/contracts/contract_deployer.go @@ -435,7 +435,7 @@ func (e *EthereumContractDeployer) DeployStakingEventsMock() (StakingEventsMock, if err != nil { return nil, err } - return &EthereumStakingEventsMock{ + return &LegacyEthereumStakingEventsMock{ client: e.client, eventsMock: instance.(*eth_contracts.StakingEventsMock), address: address, @@ -452,7 +452,7 @@ func (e *EthereumContractDeployer) DeployFunctionsV1EventsMock() (FunctionsV1Eve if err != nil { return nil, err } - return &EthereumFunctionsV1EventsMock{ + return &LegacyEthereumFunctionsV1EventsMock{ client: e.client, eventsMock: instance.(*functions_v1_events_mock.FunctionsV1EventsMock), address: address, @@ -469,7 +469,7 @@ func (e *EthereumContractDeployer) DeployKeeperRegistry11Mock() (KeeperRegistry1 if err != nil { return nil, err } - return &EthereumKeeperRegistry11Mock{ + return &LegacyEthereumKeeperRegistry11Mock{ client: e.client, registryMock: instance.(*keeper_registry_wrapper1_1_mock.KeeperRegistryMock), address: address, @@ -486,7 +486,7 @@ func (e *EthereumContractDeployer) DeployKeeperRegistrar12Mock() (KeeperRegistra if err != nil { return nil, err } - return &EthereumKeeperRegistrar12Mock{ + return &LegacyEthereumKeeperRegistrar12Mock{ client: e.client, registrarMock: instance.(*keeper_registrar_wrapper1_2_mock.KeeperRegistrarMock), address: address, @@ -503,7 +503,7 @@ func (e *EthereumContractDeployer) DeployKeeperGasWrapperMock() (KeeperGasWrappe if err != nil { return nil, err } - return &EthereumKeeperGasWrapperMock{ + return &LegacyEthereumKeeperGasWrapperMock{ client: e.client, gasWrapperMock: instance.(*gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMock), address: address, diff --git a/integration-tests/contracts/etherem_contracts_atlas_seth.go b/integration-tests/contracts/etherem_contracts_atlas_seth.go new file mode 100644 index 00000000000..c28e5198682 --- /dev/null +++ b/integration-tests/contracts/etherem_contracts_atlas_seth.go @@ -0,0 +1,392 @@ +package contracts + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/seth" + + eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "github.com/smartcontractkit/chainlink/integration-tests/wrappers" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_v1_events_mock" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/gas_wrapper_mock" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper1_2_mock" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1_mock" +) + +// EthereumFunctionsV1EventsMock represents the basic functions v1 events mock contract +type EthereumFunctionsV1EventsMock struct { + client *seth.Client + eventsMock *functions_v1_events_mock.FunctionsV1EventsMock + address *common.Address +} + +func (f *EthereumFunctionsV1EventsMock) Address() string { + return f.address.Hex() +} + +func (f *EthereumFunctionsV1EventsMock) EmitRequestProcessed(requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, errByte []byte, callbackReturnData []byte) error { + _, err := f.client.Decode(f.eventsMock.EmitRequestProcessed(f.client.NewTXOpts(), requestId, subscriptionId, totalCostJuels, transmitter, resultCode, response, errByte, callbackReturnData)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitRequestStart(requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitRequestStart(f.client.NewTXOpts(), requestId, donId, subscriptionId, subscriptionOwner, requestingContract, requestInitiator, data, dataVersion, callbackGasLimit, estimatedTotalCostJuels)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCanceled(subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionCanceled(f.client.NewTXOpts(), subscriptionId, fundsRecipient, fundsAmount)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerAdded(subscriptionId uint64, consumer common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionConsumerAdded(f.client.NewTXOpts(), subscriptionId, consumer)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerRemoved(subscriptionId uint64, consumer common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionConsumerRemoved(f.client.NewTXOpts(), subscriptionId, consumer)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCreated(subscriptionId uint64, owner common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionCreated(f.client.NewTXOpts(), subscriptionId, owner)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionFunded(subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionFunded(f.client.NewTXOpts(), subscriptionId, oldBalance, newBalance)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferred(subscriptionId uint64, from common.Address, to common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionOwnerTransferred(f.client.NewTXOpts(), subscriptionId, from, to)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferRequested(subscriptionId uint64, from common.Address, to common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionOwnerTransferRequested(f.client.NewTXOpts(), subscriptionId, from, to)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitRequestNotProcessed(requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) error { + _, err := f.client.Decode(f.eventsMock.EmitRequestNotProcessed(f.client.NewTXOpts(), requestId, coordinator, transmitter, resultCode)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitContractUpdated(id [32]byte, from common.Address, to common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitContractUpdated(f.client.NewTXOpts(), id, from, to)) + return err +} + +// DeployFunctionsV1EventsMock deploys a new instance of the FunctionsV1EventsMock contract +func DeployFunctionsV1EventsMock(client *seth.Client) (FunctionsV1EventsMock, error) { + abi, err := functions_v1_events_mock.FunctionsV1EventsMockMetaData.GetAbi() + if err != nil { + return &EthereumFunctionsV1EventsMock{}, fmt.Errorf("failed to get FunctionsV1EventsMock ABI: %w", err) + } + client.ContractStore.AddABI("FunctionsV1EventsMock", *abi) + client.ContractStore.AddBIN("FunctionsV1EventsMock", common.FromHex(functions_v1_events_mock.FunctionsV1EventsMockMetaData.Bin)) + + data, err := client.DeployContract(client.NewTXOpts(), "FunctionsV1EventsMock", *abi, common.FromHex(functions_v1_events_mock.FunctionsV1EventsMockMetaData.Bin)) + + if err != nil { + return &EthereumFunctionsV1EventsMock{}, fmt.Errorf("FunctionsV1EventsMock instance deployment have failed: %w", err) + } + + instance, err := functions_v1_events_mock.NewFunctionsV1EventsMock(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumFunctionsV1EventsMock{}, fmt.Errorf("failed to instantiate FunctionsV1EventsMock instance: %w", err) + } + + return &EthereumFunctionsV1EventsMock{ + client: client, + eventsMock: instance, + address: &data.Address, + }, nil +} + +// EthereumKeeperRegistry11Mock represents the basic keeper registry 1.1 mock contract +type EthereumKeeperRegistry11Mock struct { + client *seth.Client + registryMock *keeper_registry_wrapper1_1_mock.KeeperRegistryMock + address *common.Address +} + +func (f *EthereumKeeperRegistry11Mock) Address() string { + return f.address.Hex() +} + +func (f *EthereumKeeperRegistry11Mock) EmitUpkeepPerformed(id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) error { + _, err := f.client.Decode(f.registryMock.EmitUpkeepPerformed(f.client.NewTXOpts(), id, success, from, payment, performData)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) EmitUpkeepCanceled(id *big.Int, atBlockHeight uint64) error { + _, err := f.client.Decode(f.registryMock.EmitUpkeepCanceled(f.client.NewTXOpts(), id, atBlockHeight)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) EmitFundsWithdrawn(id *big.Int, amount *big.Int, to common.Address) error { + _, err := f.client.Decode(f.registryMock.EmitFundsWithdrawn(f.client.NewTXOpts(), id, amount, to)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) EmitKeepersUpdated(keepers []common.Address, payees []common.Address) error { + _, err := f.client.Decode(f.registryMock.EmitKeepersUpdated(f.client.NewTXOpts(), keepers, payees)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) EmitUpkeepRegistered(id *big.Int, executeGas uint32, admin common.Address) error { + _, err := f.client.Decode(f.registryMock.EmitUpkeepRegistered(f.client.NewTXOpts(), id, executeGas, admin)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) EmitFundsAdded(id *big.Int, from common.Address, amount *big.Int) error { + _, err := f.client.Decode(f.registryMock.EmitFundsAdded(f.client.NewTXOpts(), id, from, amount)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetUpkeepCount(upkeepCount *big.Int) error { + _, err := f.client.Decode(f.registryMock.SetUpkeepCount(f.client.NewTXOpts(), upkeepCount)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetCanceledUpkeepList(canceledUpkeepList []*big.Int) error { + _, err := f.client.Decode(f.registryMock.SetCanceledUpkeepList(f.client.NewTXOpts(), canceledUpkeepList)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetKeeperList(keepers []common.Address) error { + _, err := f.client.Decode(f.registryMock.SetKeeperList(f.client.NewTXOpts(), keepers)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetConfig(paymentPremiumPPB uint32, flatFeeMicroLink uint32, blockCountPerTurn *big.Int, checkGasLimit uint32, stalenessSeconds *big.Int, gasCeilingMultiplier uint16, fallbackGasPrice *big.Int, fallbackLinkPrice *big.Int) error { + _, err := f.client.Decode(f.registryMock.SetConfig(f.client.NewTXOpts(), paymentPremiumPPB, flatFeeMicroLink, blockCountPerTurn, checkGasLimit, stalenessSeconds, gasCeilingMultiplier, fallbackGasPrice, fallbackLinkPrice)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetUpkeep(id *big.Int, target common.Address, executeGas uint32, balance *big.Int, admin common.Address, maxValidBlocknumber uint64, lastKeeper common.Address, checkData []byte) error { + _, err := f.client.Decode(f.registryMock.SetUpkeep(f.client.NewTXOpts(), id, target, executeGas, balance, admin, maxValidBlocknumber, lastKeeper, checkData)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetMinBalance(id *big.Int, minBalance *big.Int) error { + _, err := f.client.Decode(f.registryMock.SetMinBalance(f.client.NewTXOpts(), id, minBalance)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetCheckUpkeepData(id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) error { + _, err := f.client.Decode(f.registryMock.SetCheckUpkeepData(f.client.NewTXOpts(), id, performData, maxLinkPayment, gasLimit, adjustedGasWei, linkEth)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetPerformUpkeepSuccess(id *big.Int, success bool) error { + _, err := f.client.Decode(f.registryMock.SetPerformUpkeepSuccess(f.client.NewTXOpts(), id, success)) + return err +} + +func DeployKeeperRegistry11Mock(client *seth.Client) (KeeperRegistry11Mock, error) { + abi, err := keeper_registry_wrapper1_1_mock.KeeperRegistryMockMetaData.GetAbi() + if err != nil { + return &EthereumKeeperRegistry11Mock{}, fmt.Errorf("failed to get KeeperRegistry11Mock ABI: %w", err) + } + client.ContractStore.AddABI("KeeperRegistry11Mock", *abi) + client.ContractStore.AddBIN("KeeperRegistry11Mock", common.FromHex(keeper_registry_wrapper1_1_mock.KeeperRegistryMockMetaData.Bin)) + + data, err := client.DeployContract(client.NewTXOpts(), "KeeperRegistry11Mock", *abi, common.FromHex(keeper_registry_wrapper1_1_mock.KeeperRegistryMockMetaData.Bin)) + + if err != nil { + return &EthereumKeeperRegistry11Mock{}, fmt.Errorf("KeeperRegistry11Mock instance deployment have failed: %w", err) + } + + instance, err := keeper_registry_wrapper1_1_mock.NewKeeperRegistryMock(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumKeeperRegistry11Mock{}, fmt.Errorf("failed to instantiate KeeperRegistry11Mock instance: %w", err) + } + + return &EthereumKeeperRegistry11Mock{ + client: client, + registryMock: instance, + address: &data.Address, + }, nil +} + +// EthereumKeeperRegistrar12Mock represents the basic keeper registrar 1.2 mock contract +type EthereumKeeperRegistrar12Mock struct { + client *seth.Client + registrarMock *keeper_registrar_wrapper1_2_mock.KeeperRegistrarMock + address *common.Address +} + +func (f *EthereumKeeperRegistrar12Mock) Address() string { + return f.address.Hex() +} + +func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationRequested(hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) error { + _, err := f.client.Decode(f.registrarMock.EmitRegistrationRequested(f.client.NewTXOpts(), hash, name, encryptedEmail, upkeepContract, gasLimit, adminAddress, checkData, amount, source)) + return err +} + +func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationApproved(hash [32]byte, displayName string, upkeepId *big.Int) error { + _, err := f.client.Decode(f.registrarMock.EmitRegistrationApproved(f.client.NewTXOpts(), hash, displayName, upkeepId)) + return err +} + +func (f *EthereumKeeperRegistrar12Mock) SetRegistrationConfig(autoApproveConfigType uint8, autoApproveMaxAllowed uint32, approvedCount uint32, keeperRegistry common.Address, minLINKJuels *big.Int) error { + _, err := f.client.Decode(f.registrarMock.SetRegistrationConfig(f.client.NewTXOpts(), autoApproveConfigType, autoApproveMaxAllowed, approvedCount, keeperRegistry, minLINKJuels)) + return err +} + +func DeployKeeperRegistrar12Mock(client *seth.Client) (KeeperRegistrar12Mock, error) { + abi, err := keeper_registrar_wrapper1_2_mock.KeeperRegistrarMockMetaData.GetAbi() + if err != nil { + return &EthereumKeeperRegistrar12Mock{}, fmt.Errorf("failed to get KeeperRegistrar12Mock ABI: %w", err) + } + client.ContractStore.AddABI("KeeperRegistrar12Mock", *abi) + client.ContractStore.AddBIN("KeeperRegistrar12Mock", common.FromHex(keeper_registrar_wrapper1_2_mock.KeeperRegistrarMockMetaData.Bin)) + + data, err := client.DeployContract(client.NewTXOpts(), "KeeperRegistrar12Mock", *abi, common.FromHex(keeper_registrar_wrapper1_2_mock.KeeperRegistrarMockMetaData.Bin)) + + if err != nil { + return &EthereumKeeperRegistrar12Mock{}, fmt.Errorf("KeeperRegistrar12Mock instance deployment have failed: %w", err) + } + + instance, err := keeper_registrar_wrapper1_2_mock.NewKeeperRegistrarMock(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumKeeperRegistrar12Mock{}, fmt.Errorf("failed to instantiate KeeperRegistrar12Mock instance: %w", err) + } + + return &EthereumKeeperRegistrar12Mock{ + client: client, + registrarMock: instance, + address: &data.Address, + }, nil +} + +// EthereumKeeperGasWrapperMock represents the basic keeper gas wrapper mock contract +type EthereumKeeperGasWrapperMock struct { + client *seth.Client + gasWrapperMock *gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMock + address *common.Address +} + +func (f *EthereumKeeperGasWrapperMock) Address() string { + return f.address.Hex() +} + +func (f *EthereumKeeperGasWrapperMock) SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) error { + _, err := f.client.Decode(f.gasWrapperMock.SetMeasureCheckGasResult(f.client.NewTXOpts(), result, payload, gas)) + return err +} + +func DeployKeeperGasWrapperMock(client *seth.Client) (KeeperGasWrapperMock, error) { + abi, err := gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData.GetAbi() + if err != nil { + return &EthereumKeeperGasWrapperMock{}, fmt.Errorf("failed to get KeeperGasWrapperMock ABI: %w", err) + } + client.ContractStore.AddABI("KeeperGasWrapperMock", *abi) + client.ContractStore.AddBIN("KeeperGasWrapperMock", common.FromHex(gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData.Bin)) + + data, err := client.DeployContract(client.NewTXOpts(), "KeeperGasWrapperMock", *abi, common.FromHex(gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData.Bin)) + + if err != nil { + return &EthereumKeeperGasWrapperMock{}, fmt.Errorf("KeeperGasWrapperMock instance deployment have failed: %w", err) + } + + instance, err := gas_wrapper_mock.NewKeeperRegistryCheckUpkeepGasUsageWrapperMock(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumKeeperGasWrapperMock{}, fmt.Errorf("failed to instantiate KeeperGasWrapperMock instance: %w", err) + } + + return &EthereumKeeperGasWrapperMock{ + client: client, + gasWrapperMock: instance, + address: &data.Address, + }, nil +} + +// EthereumStakingEventsMock represents the basic events mock contract +type EthereumStakingEventsMock struct { + client *seth.Client + eventsMock *eth_contracts.StakingEventsMock + address *common.Address +} + +func (f *EthereumStakingEventsMock) Address() string { + return f.address.Hex() +} + +func (f *EthereumStakingEventsMock) MaxCommunityStakeAmountIncreased(maxStakeAmount *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitMaxCommunityStakeAmountIncreased(f.client.NewTXOpts(), maxStakeAmount)) + return err +} + +func (f *EthereumStakingEventsMock) PoolSizeIncreased(maxPoolSize *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitPoolSizeIncreased(f.client.NewTXOpts(), maxPoolSize)) + return err +} + +func (f *EthereumStakingEventsMock) MaxOperatorStakeAmountIncreased(maxStakeAmount *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitMaxOperatorStakeAmountIncreased(f.client.NewTXOpts(), maxStakeAmount)) + return err +} + +func (f *EthereumStakingEventsMock) RewardInitialized(rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitRewardInitialized(f.client.NewTXOpts(), rate, available, startTimestamp, endTimestamp)) + return err +} + +func (f *EthereumStakingEventsMock) AlertRaised(alerter common.Address, roundId *big.Int, rewardAmount *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitAlertRaised(f.client.NewTXOpts(), alerter, roundId, rewardAmount)) + return err +} + +func (f *EthereumStakingEventsMock) Staked(staker common.Address, newStake *big.Int, totalStake *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitStaked(f.client.NewTXOpts(), staker, newStake, totalStake)) + return err +} + +func (f *EthereumStakingEventsMock) OperatorAdded(operator common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitOperatorAdded(f.client.NewTXOpts(), operator)) + return err +} + +func (f *EthereumStakingEventsMock) OperatorRemoved(operator common.Address, amount *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitOperatorRemoved(f.client.NewTXOpts(), operator, amount)) + return err +} + +func (f *EthereumStakingEventsMock) FeedOperatorsSet(feedOperators []common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitFeedOperatorsSet(f.client.NewTXOpts(), feedOperators)) + return err +} + +func DeployStakingEventsMock(client *seth.Client) (StakingEventsMock, error) { + abi, err := eth_contracts.StakingEventsMockMetaData.GetAbi() + if err != nil { + return &EthereumStakingEventsMock{}, fmt.Errorf("failed to get StakingEventsMock ABI: %w", err) + } + client.ContractStore.AddABI("StakingEventsMock", *abi) + client.ContractStore.AddBIN("StakingEventsMock", common.FromHex(eth_contracts.StakingEventsMockMetaData.Bin)) + + data, err := client.DeployContract(client.NewTXOpts(), "StakingEventsMock", *abi, common.FromHex(eth_contracts.StakingEventsMockMetaData.Bin)) + + if err != nil { + return &EthereumStakingEventsMock{}, fmt.Errorf("StakingEventsMock instance deployment have failed: %w", err) + } + + instance, err := eth_contracts.NewStakingEventsMock(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumStakingEventsMock{}, fmt.Errorf("failed to instantiate StakingEventsMock instance: %w", err) + } + + return &EthereumStakingEventsMock{ + client: client, + eventsMock: instance, + address: &data.Address, + }, nil +} diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index e8b2f184ce9..adf4dcffe80 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -350,18 +350,18 @@ func (f *EthereumFunctionsBillingRegistryEventsMock) BillingEnd(requestId [32]by return f.client.ProcessTransaction(tx) } -// EthereumStakingEventsMock represents the basic events mock contract -type EthereumStakingEventsMock struct { +// LegacyEthereumStakingEventsMock represents the basic events mock contract +type LegacyEthereumStakingEventsMock struct { client blockchain.EVMClient eventsMock *eth_contracts.StakingEventsMock address *common.Address } -func (f *EthereumStakingEventsMock) Address() string { +func (f *LegacyEthereumStakingEventsMock) Address() string { return f.address.Hex() } -func (f *EthereumStakingEventsMock) MaxCommunityStakeAmountIncreased(maxStakeAmount *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) MaxCommunityStakeAmountIncreased(maxStakeAmount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -373,7 +373,7 @@ func (f *EthereumStakingEventsMock) MaxCommunityStakeAmountIncreased(maxStakeAmo return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) PoolSizeIncreased(maxPoolSize *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) PoolSizeIncreased(maxPoolSize *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -385,7 +385,7 @@ func (f *EthereumStakingEventsMock) PoolSizeIncreased(maxPoolSize *big.Int) erro return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) MaxOperatorStakeAmountIncreased(maxStakeAmount *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) MaxOperatorStakeAmountIncreased(maxStakeAmount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -397,7 +397,7 @@ func (f *EthereumStakingEventsMock) MaxOperatorStakeAmountIncreased(maxStakeAmou return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) RewardInitialized(rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) RewardInitialized(rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -409,7 +409,7 @@ func (f *EthereumStakingEventsMock) RewardInitialized(rate *big.Int, available * return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) AlertRaised(alerter common.Address, roundId *big.Int, rewardAmount *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) AlertRaised(alerter common.Address, roundId *big.Int, rewardAmount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -421,7 +421,7 @@ func (f *EthereumStakingEventsMock) AlertRaised(alerter common.Address, roundId return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) Staked(staker common.Address, newStake *big.Int, totalStake *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) Staked(staker common.Address, newStake *big.Int, totalStake *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -433,7 +433,7 @@ func (f *EthereumStakingEventsMock) Staked(staker common.Address, newStake *big. return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) OperatorAdded(operator common.Address) error { +func (f *LegacyEthereumStakingEventsMock) OperatorAdded(operator common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -445,7 +445,7 @@ func (f *EthereumStakingEventsMock) OperatorAdded(operator common.Address) error return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) OperatorRemoved(operator common.Address, amount *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) OperatorRemoved(operator common.Address, amount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -457,7 +457,7 @@ func (f *EthereumStakingEventsMock) OperatorRemoved(operator common.Address, amo return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) FeedOperatorsSet(feedOperators []common.Address) error { +func (f *LegacyEthereumStakingEventsMock) FeedOperatorsSet(feedOperators []common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -504,18 +504,18 @@ func (f *EthereumOffchainAggregatorEventsMock) NewTransmission(aggregatorRoundId return f.client.ProcessTransaction(tx) } -// EthereumKeeperRegistry11Mock represents the basic keeper registry 1.1 mock contract -type EthereumKeeperRegistry11Mock struct { +// LegacyEthereumKeeperRegistry11Mock represents the basic keeper registry 1.1 mock contract +type LegacyEthereumKeeperRegistry11Mock struct { client blockchain.EVMClient registryMock *keeper_registry_wrapper1_1_mock.KeeperRegistryMock address *common.Address } -func (f *EthereumKeeperRegistry11Mock) Address() string { +func (f *LegacyEthereumKeeperRegistry11Mock) Address() string { return f.address.Hex() } -func (f *EthereumKeeperRegistry11Mock) EmitUpkeepPerformed(id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitUpkeepPerformed(id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -527,7 +527,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitUpkeepPerformed(id *big.Int, success return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) EmitUpkeepCanceled(id *big.Int, atBlockHeight uint64) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitUpkeepCanceled(id *big.Int, atBlockHeight uint64) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -539,7 +539,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitUpkeepCanceled(id *big.Int, atBlockHe return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) EmitFundsWithdrawn(id *big.Int, amount *big.Int, to common.Address) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitFundsWithdrawn(id *big.Int, amount *big.Int, to common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -551,7 +551,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitFundsWithdrawn(id *big.Int, amount *b return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) EmitKeepersUpdated(keepers []common.Address, payees []common.Address) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitKeepersUpdated(keepers []common.Address, payees []common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -563,7 +563,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitKeepersUpdated(keepers []common.Addre return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) EmitUpkeepRegistered(id *big.Int, executeGas uint32, admin common.Address) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitUpkeepRegistered(id *big.Int, executeGas uint32, admin common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -575,7 +575,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitUpkeepRegistered(id *big.Int, execute return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) EmitFundsAdded(id *big.Int, from common.Address, amount *big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitFundsAdded(id *big.Int, from common.Address, amount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -587,7 +587,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitFundsAdded(id *big.Int, from common.A return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetUpkeepCount(_upkeepCount *big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetUpkeepCount(_upkeepCount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -599,7 +599,7 @@ func (f *EthereumKeeperRegistry11Mock) SetUpkeepCount(_upkeepCount *big.Int) err return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetCanceledUpkeepList(_canceledUpkeepList []*big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetCanceledUpkeepList(_canceledUpkeepList []*big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -611,7 +611,7 @@ func (f *EthereumKeeperRegistry11Mock) SetCanceledUpkeepList(_canceledUpkeepList return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetKeeperList(_keepers []common.Address) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetKeeperList(_keepers []common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -623,7 +623,7 @@ func (f *EthereumKeeperRegistry11Mock) SetKeeperList(_keepers []common.Address) return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetConfig(_paymentPremiumPPB uint32, _flatFeeMicroLink uint32, _blockCountPerTurn *big.Int, _checkGasLimit uint32, _stalenessSeconds *big.Int, _gasCeilingMultiplier uint16, _fallbackGasPrice *big.Int, _fallbackLinkPrice *big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetConfig(_paymentPremiumPPB uint32, _flatFeeMicroLink uint32, _blockCountPerTurn *big.Int, _checkGasLimit uint32, _stalenessSeconds *big.Int, _gasCeilingMultiplier uint16, _fallbackGasPrice *big.Int, _fallbackLinkPrice *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -635,7 +635,7 @@ func (f *EthereumKeeperRegistry11Mock) SetConfig(_paymentPremiumPPB uint32, _fla return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetUpkeep(id *big.Int, _target common.Address, _executeGas uint32, _balance *big.Int, _admin common.Address, _maxValidBlocknumber uint64, _lastKeeper common.Address, _checkData []byte) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetUpkeep(id *big.Int, _target common.Address, _executeGas uint32, _balance *big.Int, _admin common.Address, _maxValidBlocknumber uint64, _lastKeeper common.Address, _checkData []byte) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -647,7 +647,7 @@ func (f *EthereumKeeperRegistry11Mock) SetUpkeep(id *big.Int, _target common.Add return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetMinBalance(id *big.Int, minBalance *big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetMinBalance(id *big.Int, minBalance *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -659,7 +659,7 @@ func (f *EthereumKeeperRegistry11Mock) SetMinBalance(id *big.Int, minBalance *bi return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetCheckUpkeepData(id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetCheckUpkeepData(id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -671,7 +671,7 @@ func (f *EthereumKeeperRegistry11Mock) SetCheckUpkeepData(id *big.Int, performDa return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetPerformUpkeepSuccess(id *big.Int, success bool) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetPerformUpkeepSuccess(id *big.Int, success bool) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -683,18 +683,18 @@ func (f *EthereumKeeperRegistry11Mock) SetPerformUpkeepSuccess(id *big.Int, succ return f.client.ProcessTransaction(tx) } -// EthereumKeeperRegistrar12Mock represents the basic keeper registrar 1.2 mock contract -type EthereumKeeperRegistrar12Mock struct { +// LegacyEthereumKeeperRegistrar12Mock represents the basic keeper registrar 1.2 mock contract +type LegacyEthereumKeeperRegistrar12Mock struct { client blockchain.EVMClient registrarMock *keeper_registrar_wrapper1_2_mock.KeeperRegistrarMock address *common.Address } -func (f *EthereumKeeperRegistrar12Mock) Address() string { +func (f *LegacyEthereumKeeperRegistrar12Mock) Address() string { return f.address.Hex() } -func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationRequested(hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) error { +func (f *LegacyEthereumKeeperRegistrar12Mock) EmitRegistrationRequested(hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -706,7 +706,7 @@ func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationRequested(hash [32]byte, return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationApproved(hash [32]byte, displayName string, upkeepId *big.Int) error { +func (f *LegacyEthereumKeeperRegistrar12Mock) EmitRegistrationApproved(hash [32]byte, displayName string, upkeepId *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -718,7 +718,7 @@ func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationApproved(hash [32]byte, return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistrar12Mock) SetRegistrationConfig(_autoApproveConfigType uint8, _autoApproveMaxAllowed uint32, _approvedCount uint32, _keeperRegistry common.Address, _minLINKJuels *big.Int) error { +func (f *LegacyEthereumKeeperRegistrar12Mock) SetRegistrationConfig(_autoApproveConfigType uint8, _autoApproveMaxAllowed uint32, _approvedCount uint32, _keeperRegistry common.Address, _minLINKJuels *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -730,18 +730,18 @@ func (f *EthereumKeeperRegistrar12Mock) SetRegistrationConfig(_autoApproveConfig return f.client.ProcessTransaction(tx) } -// EthereumKeeperGasWrapperMock represents the basic keeper gas wrapper mock contract -type EthereumKeeperGasWrapperMock struct { +// LegacyEthereumKeeperGasWrapperMock represents the basic keeper gas wrapper mock contract +type LegacyEthereumKeeperGasWrapperMock struct { client blockchain.EVMClient gasWrapperMock *gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMock address *common.Address } -func (f *EthereumKeeperGasWrapperMock) Address() string { +func (f *LegacyEthereumKeeperGasWrapperMock) Address() string { return f.address.Hex() } -func (f *EthereumKeeperGasWrapperMock) SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) error { +func (f *LegacyEthereumKeeperGasWrapperMock) SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -753,18 +753,18 @@ func (f *EthereumKeeperGasWrapperMock) SetMeasureCheckGasResult(result bool, pay return f.client.ProcessTransaction(tx) } -// EthereumFunctionsV1EventsMock represents the basic functions v1 events mock contract -type EthereumFunctionsV1EventsMock struct { +// LegacyEthereumFunctionsV1EventsMock represents the basic functions v1 events mock contract +type LegacyEthereumFunctionsV1EventsMock struct { client blockchain.EVMClient eventsMock *functions_v1_events_mock.FunctionsV1EventsMock address *common.Address } -func (f *EthereumFunctionsV1EventsMock) Address() string { +func (f *LegacyEthereumFunctionsV1EventsMock) Address() string { return f.address.Hex() } -func (f *EthereumFunctionsV1EventsMock) EmitRequestProcessed(requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, errByte []byte, callbackReturnData []byte) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitRequestProcessed(requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, errByte []byte, callbackReturnData []byte) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -776,7 +776,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitRequestProcessed(requestId [32]byte, return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitRequestStart(requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitRequestStart(requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -788,7 +788,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitRequestStart(requestId [32]byte, don return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCanceled(subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionCanceled(subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -800,7 +800,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCanceled(subscriptionId return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerAdded(subscriptionId uint64, consumer common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionConsumerAdded(subscriptionId uint64, consumer common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -812,7 +812,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerAdded(subscripti return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerRemoved(subscriptionId uint64, consumer common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionConsumerRemoved(subscriptionId uint64, consumer common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -824,7 +824,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerRemoved(subscrip return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCreated(subscriptionId uint64, owner common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionCreated(subscriptionId uint64, owner common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -836,7 +836,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCreated(subscriptionId u return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionFunded(subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionFunded(subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -848,7 +848,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionFunded(subscriptionId ui return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferred(subscriptionId uint64, from common.Address, to common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferred(subscriptionId uint64, from common.Address, to common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -860,7 +860,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferred(subscri return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferRequested(subscriptionId uint64, from common.Address, to common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferRequested(subscriptionId uint64, from common.Address, to common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -872,7 +872,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferRequested(s return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitRequestNotProcessed(requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitRequestNotProcessed(requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -884,7 +884,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitRequestNotProcessed(requestId [32]by return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitContractUpdated(id [32]byte, from common.Address, to common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitContractUpdated(id [32]byte, from common.Address, to common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 69c09244ef8..3d76a656be5 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -25,12 +25,12 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 - github.com/smartcontractkit/chainlink-testing-framework v1.28.4 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb + github.com/smartcontractkit/chainlink-testing-framework v1.28.7 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c - github.com/smartcontractkit/seth v0.1.6 + github.com/smartcontractkit/seth v0.1.6-0.20240429143720-cacb8160ecec github.com/smartcontractkit/wasp v0.4.5 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index e2be6f36438..61fef05bbad 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1517,8 +1517,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb h1:nJ9dkgvX5vdpFWhYufnRUAiNvNHsXkoBL6C0bDerq/k= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= @@ -1529,8 +1529,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba5 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= -github.com/smartcontractkit/chainlink-testing-framework v1.28.4 h1:/OOPH76VFQlG5HEXrXgBVDv1fjuasQzMV1EyeaaXWzM= -github.com/smartcontractkit/chainlink-testing-framework v1.28.4/go.mod h1:jN+HgXbriq6fKRlIqLw9F3I81aYImV6kBJkIfz0mdIA= +github.com/smartcontractkit/chainlink-testing-framework v1.28.7 h1:Yr93tBl5jVx1cfKywt0C0cbuObDPJ6JIU4FIsZ6bZlM= +github.com/smartcontractkit/chainlink-testing-framework v1.28.7/go.mod h1:x1zDOz8zcLjEvs9fNA9y/DMguLam/2+CJdpxX0+rM8A= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1539,8 +1539,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c h1:lIyMbTaF2H0Q71vkwZHX/Ew4KF2BxiKhqEXwF8rn+KI= github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v0.1.6 h1:exU96KiKM/gxvp7OR8KkOXnTgbtFNepdhMBvyobFKCw= -github.com/smartcontractkit/seth v0.1.6/go.mod h1:2TMOZQ8WTAw7rR1YBbXpnad6VmT/+xDd/nXLmB7Eero= +github.com/smartcontractkit/seth v0.1.6-0.20240429143720-cacb8160ecec h1:BT1loU6TT2YqMenD7XE+aw7IeeTiC25+r1TLKAySVIg= +github.com/smartcontractkit/seth v0.1.6-0.20240429143720-cacb8160ecec/go.mod h1:2TMOZQ8WTAw7rR1YBbXpnad6VmT/+xDd/nXLmB7Eero= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 128c611c04d..c8fde175cab 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,8 +16,8 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 - github.com/smartcontractkit/chainlink-testing-framework v1.28.4 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb + github.com/smartcontractkit/chainlink-testing-framework v1.28.7 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 291f221f4b8..46646e6b289 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1500,8 +1500,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb h1:nJ9dkgvX5vdpFWhYufnRUAiNvNHsXkoBL6C0bDerq/k= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= @@ -1512,8 +1512,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba5 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= -github.com/smartcontractkit/chainlink-testing-framework v1.28.4 h1:/OOPH76VFQlG5HEXrXgBVDv1fjuasQzMV1EyeaaXWzM= -github.com/smartcontractkit/chainlink-testing-framework v1.28.4/go.mod h1:jN+HgXbriq6fKRlIqLw9F3I81aYImV6kBJkIfz0mdIA= +github.com/smartcontractkit/chainlink-testing-framework v1.28.7 h1:Yr93tBl5jVx1cfKywt0C0cbuObDPJ6JIU4FIsZ6bZlM= +github.com/smartcontractkit/chainlink-testing-framework v1.28.7/go.mod h1:x1zDOz8zcLjEvs9fNA9y/DMguLam/2+CJdpxX0+rM8A= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea h1:ZdLmNAfKRjH8AYUvjiiDGUgiWQfq/7iNpxyTkvjx/ko= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea/go.mod h1:gCKC9w6XpNk6jm+XIk2psrkkfxhi421N9NSiFceXW88= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= diff --git a/plugins/medianpoc/plugin.go b/plugins/medianpoc/plugin.go index b937361b9ec..bbd9d437e3a 100644 --- a/plugins/medianpoc/plugin.go +++ b/plugins/medianpoc/plugin.go @@ -66,6 +66,7 @@ func (p *Plugin) NewReportingPluginFactory( telemetry core.TelemetryClient, errorLog core.ErrorLog, keyValueStore core.KeyValueStore, + relayerSet core.RelayerSet, ) (types.ReportingPluginFactory, error) { f, err := p.newFactory(ctx, config, provider, pipelineRunner, telemetry, errorLog) if err != nil { diff --git a/tools/bin/go_core_tests b/tools/bin/go_core_tests index c0b0f43aed4..074527698b3 100755 --- a/tools/bin/go_core_tests +++ b/tools/bin/go_core_tests @@ -33,4 +33,5 @@ if [[ $EXITCODE != 0 ]]; then else echo "All tests passed!" fi +echo "go_core_tests exiting with code $EXITCODE" exit $EXITCODE diff --git a/tools/flakeytests/runner.go b/tools/flakeytests/runner.go index 88ab647e7c1..a37b123d5cf 100644 --- a/tools/flakeytests/runner.go +++ b/tools/flakeytests/runner.go @@ -219,8 +219,8 @@ func (r *Runner) runTests(rep *Report) (*Report, error) { ts = append(ts, test) } - log.Printf("[FLAKEY_TEST] Executing test command with parameters: pkg=%s, tests=%+v, numReruns=%d\n", pkg, ts, r.numReruns) for i := 0; i < r.numReruns; i++ { + log.Printf("[FLAKEY_TEST] Executing test command with parameters: pkg=%s, tests=%+v, numReruns=%d currentRun=%d\n", pkg, ts, r.numReruns, i) pr, err := r.runTest(pkg, ts) if err != nil { return report, err @@ -237,8 +237,8 @@ func (r *Runner) runTests(rep *Report) (*Report, error) { } for pkg := range rep.packagePanics { - log.Printf("[PACKAGE_PANIC]: Executing test command with parameters: pkg=%s, numReruns=%d\n", pkg, r.numReruns) for i := 0; i < r.numReruns; i++ { + log.Printf("[PACKAGE_PANIC]: Executing test command with parameters: pkg=%s, numReruns=%d currentRun=%d\n", pkg, r.numReruns, i) pr, err := r.runTest(pkg, []string{}) if err != nil { return report, err diff --git a/tools/flakeytests/runner_test.go b/tools/flakeytests/runner_test.go index ee069a1655d..8f9433a427b 100644 --- a/tools/flakeytests/runner_test.go +++ b/tools/flakeytests/runner_test.go @@ -14,6 +14,17 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" ) +// This test suite has two sets of tests that are run in two different modes: +// 1. Normal mode: The tests are run as usual. All tests that start with TestSkippedForTests will be skipped. +// There are a set of integration tests that will run this same test suite in integration mode. +// 2. Integration mode: The tests are run with an environment variable set to run the tests that were skipped in normal mode. +// Their output is captured and parsed to check if the flake runner is behaving as expected. +// +// In summary, the first set of tests are executed by the user, and these tests will trigger the second set of tests to run. +var runInIntegrationTestModeEnvKey = "FLAKEY_TEST_RUNNER_RUN_FIXTURE_TEST" +var skipIntegrationTestMode = os.Getenv(runInIntegrationTestModeEnvKey) != "1" +var runInIntegrationTestModeEnv = runInIntegrationTestModeEnvKey + "=1" + type mockReporter struct { report *Report } @@ -307,7 +318,7 @@ func TestRunner_RerunWithNonZeroExitCodeDoesntStopCommand(t *testing.T) { // Used for integration tests func TestSkippedForTests_Subtests(t *testing.T) { - if os.Getenv("FLAKEY_TEST_RUNNER_RUN_FIXTURE_TEST") != "1" { + if skipIntegrationTestMode { t.Skip() } @@ -322,7 +333,7 @@ func TestSkippedForTests_Subtests(t *testing.T) { // Used for integration tests func TestSkippedForTests(t *testing.T) { - if os.Getenv("FLAKEY_TEST_RUNNER_RUN_FIXTURE_TEST") != "1" { + if skipIntegrationTestMode { t.Skip() } @@ -333,7 +344,7 @@ func TestSkippedForTests(t *testing.T) { // Used for integration tests func TestSkippedForTests_Success(t *testing.T) { - if os.Getenv("FLAKEY_TEST_RUNNER_RUN_FIXTURE_TEST") != "1" { + if skipIntegrationTestMode { t.Skip() } @@ -356,7 +367,7 @@ func TestIntegration_DealsWithSubtests(t *testing.T) { repo: "github.com/smartcontractkit/chainlink/v2/tools/flakeytests", command: "../bin/go_core_tests", overrides: func(cmd *exec.Cmd) { - cmd.Env = append(cmd.Env, "FLAKEY_TESTRUNNER_RUN_FIXTURE_TEST=1") + cmd.Env = append(cmd.Env, runInIntegrationTestModeEnv) cmd.Stdout = io.Discard cmd.Stderr = io.Discard }, @@ -392,7 +403,7 @@ func TestIntegration_ParsesPanics(t *testing.T) { repo: "github.com/smartcontractkit/chainlink/v2/tools/flakeytests", command: "../bin/go_core_tests", overrides: func(cmd *exec.Cmd) { - cmd.Env = append(cmd.Env, "FLAKEY_TESTRUNNER_RUN_FIXTURE_TEST=1") + cmd.Env = append(cmd.Env, runInIntegrationTestModeEnv) cmd.Stdout = io.Discard cmd.Stderr = io.Discard }, @@ -423,7 +434,7 @@ func TestIntegration(t *testing.T) { repo: "github.com/smartcontractkit/chainlink/v2/tools/flakeytests", command: "../bin/go_core_tests", overrides: func(cmd *exec.Cmd) { - cmd.Env = append(cmd.Env, "FLAKEY_TESTRUNNER_RUN_FIXTURE_TEST=1") + cmd.Env = append(cmd.Env, runInIntegrationTestModeEnv) cmd.Stdout = io.Discard cmd.Stderr = io.Discard },