diff --git a/.changeset/cool-mirrors-beg.md b/.changeset/cool-mirrors-beg.md
deleted file mode 100644
index a030ac7e3a..0000000000
--- a/.changeset/cool-mirrors-beg.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"chainlink": patch
----
-
-#added L3X Config
diff --git a/.changeset/red-meals-mix.md b/.changeset/red-meals-mix.md
deleted file mode 100644
index a3667ed20e..0000000000
--- a/.changeset/red-meals-mix.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"chainlink": minor
----
-
-Bump to start the next version
diff --git a/.github/actions/build-sign-publish-chainlink/action.yml b/.github/actions/build-sign-publish-chainlink/action.yml
index 552913fc58..67ca3068ef 100644
--- a/.github/actions/build-sign-publish-chainlink/action.yml
+++ b/.github/actions/build-sign-publish-chainlink/action.yml
@@ -68,6 +68,13 @@ inputs:
description: When set to the string boolean value of "true", the resulting build image signature will be verified
default: "false"
required: false
+outputs:
+ docker-image-tag:
+ description: The docker image tag that was built and pushed
+ value: ${{ steps.save-non-root-image-name-env.outputs.image-tag }}
+ docker-image-digest:
+ description: The docker image digest that was built and pushed
+ value: ${{ steps.save-non-root-image-name-env.outputs.image-digest }}
runs:
using: composite
@@ -208,10 +215,13 @@ runs:
IMAGES_NAME_RAW=${{ fromJSON(steps.buildpush-nonroot.outputs.metadata)['image.name'] }}
IMAGE_DIGEST=${{ fromJSON(steps.buildpush-nonroot.outputs.metadata)['containerimage.digest'] }}
IMAGE_NAME=$(echo "$IMAGES_NAME_RAW" | cut -d"," -f1)
+ IMAGE_TAG=$(echo "$IMAGES_NAME_RAW" | cut -d":" -f2)
echo "nonroot_image_name=${IMAGE_NAME}" >> $GITHUB_ENV
echo '### Docker Image' >> $GITHUB_STEP_SUMMARY
echo "Image Name: ${IMAGE_NAME}" >> $GITHUB_STEP_SUMMARY
echo "Image Digest: ${IMAGE_DIGEST}" >> $GITHUB_STEP_SUMMARY
+ echo "image-tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT
+ echo "image-digest=${IMAGE_DIGEST}" >> $GITHUB_OUTPUT
- name: Check if non-root image runs as root
id: check-nonroot-runs-root
diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml
index 324d5b04b9..7514743fa8 100644
--- a/.github/workflows/automation-ondemand-tests.yml
+++ b/.github/workflows/automation-ondemand-tests.yml
@@ -146,7 +146,7 @@ jobs:
- name: chaos
id: chaos
suite: chaos
- nodes: 15
+ nodes: 20
os: ubuntu-latest
enabled: ${{ inputs.enableChaos }}
pyroscope_env: ci-automation-on-demand-chaos
diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml
index 865bdaf730..4a477a0e14 100644
--- a/.github/workflows/build-publish.yml
+++ b/.github/workflows/build-publish.yml
@@ -8,6 +8,10 @@ on:
branches:
- "release/**"
+env:
+ ECR_HOSTNAME: public.ecr.aws
+ ECR_IMAGE_NAME: chainlink/chainlink
+
jobs:
checks:
name: "Checks"
@@ -30,17 +34,23 @@ jobs:
permissions:
id-token: write
contents: read
+ outputs:
+ docker-image-tag: ${{ steps.build-sign-publish.outputs.docker-image-tag }}
+ docker-image-digest: ${{ steps.build-sign-publish.outputs.docker-image-digest }}
steps:
- name: Checkout repository
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Build, sign and publish chainlink image
+ id: build-sign-publish
uses: ./.github/actions/build-sign-publish-chainlink
with:
publish: true
aws-role-to-assume: ${{ secrets.AWS_OIDC_IAM_ROLE_ARN }}
aws-role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS }}
aws-region: ${{ secrets.AWS_REGION }}
+ ecr-hostname: ${{ env.ECR_HOSTNAME }}
+ ecr-image-name: ${{ env.ECR_IMAGE_NAME }}
sign-images: true
sign-method: "keypair"
cosign-private-key: ${{ secrets.COSIGN_PRIVATE_KEY }}
@@ -60,3 +70,44 @@ jobs:
hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }}
this-job-name: build-sign-publish-chainlink
continue-on-error: true
+
+ # Notify Slack channel for new git tags.
+ slack-notify:
+ if: github.ref_type == 'tag'
+ needs: [build-sign-publish-chainlink]
+ runs-on: ubuntu-24.04
+ environment: build-publish
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
+ - name: Notify Slack
+ uses: smartcontractkit/.github/actions/slack-notify-git-ref@31e00facdd8f57a2bc7868b5e4c8591bf2aa3727 # slack-notify-git-ref@0.1.2
+ with:
+ slack-channel-id: ${{ secrets.SLACK_CHANNEL_RELEASE_NOTIFICATIONS }}
+ slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN_RELENG }} # Releng Bot
+ git-ref: ${{ github.ref_name }}
+ git-ref-type: ${{ github.ref_type }}
+ changelog-url: >-
+ ${{
+ github.ref_type == 'tag' &&
+ format(
+ 'https://github.com/{0}/blob/{1}/CHANGELOG.md',
+ github.repository,
+ github.ref_name
+ ) || ''
+ }}
+ docker-image-name: >-
+ ${{
+ github.ref_type == 'tag' &&
+ format(
+ '{0}/{1}:{2}',
+ env.ECR_HOSTNAME,
+ env.ECR_IMAGE_NAME,
+ needs.build-sign-publish-chainlink.outputs.docker-image-tag
+ ) || ''
+ }}
+ docker-image-digest: >-
+ ${{
+ github.ref_type == 'tag' &&
+ needs.build-sign-publish-chainlink.outputs.docker-image-digest || ''
+ }}
diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml
index 19ed0329fd..7f569168c0 100644
--- a/.github/workflows/client-compatibility-tests.yml
+++ b/.github/workflows/client-compatibility-tests.yml
@@ -54,6 +54,12 @@ jobs:
- name: Check for go.mod changes
id: changes
run: |
+ if [ -z "${{ github.base_ref }}" ]; then
+ echo "No base branch found, this should not happen in a PR or MQ. Please reach out to the Test Tooling team."
+ echo "Github even that triggered the workflow: $GITHUB_EVENT_NAME"
+ echo "Github ref that triggered the workflow: $GITHUB_REF"
+ exit 1
+ fi
git fetch origin ${{ github.base_ref }}
# if no match is found then grep exits with code 1, but if there is a match it exits with code 0
# this will return a match if there are any changes on that corresponding line, for example if spacing was changed
@@ -120,6 +126,7 @@ jobs:
evm_implementations: ${{ steps.select-implementations.outputs.evm_implementations }}
chainlink_version: ${{ steps.select-chainlink-version.outputs.chainlink_version }}
latest_image_count: ${{ steps.get-image-count.outputs.image_count }}
+ chainlink_ref_path: ${{ steps.select-chainlink-version.outputs.cl_ref_path }}
steps:
# ghlatestreleasechecker is a tool to check if new release is available for a given repo
- name: Set Up ghlatestreleasechecker
@@ -186,28 +193,39 @@ jobs:
# we use 100 days since we really want the latest one, and it's highly improbable there won't be a release in last 100 days
chainlink_version=$(ghlatestreleasechecker "smartcontractkit/chainlink" 100)
echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT
+ cl_ref_path="release"
elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then
echo "Fetching Chainlink version from input"
if [ -n "${{ github.event.inputs.chainlinkVersion }}" ]; then
echo "Chainlink version provided in input"
chainlink_version="${{ github.event.inputs.chainlinkVersion }}"
+ if [[ "$chainlink_version" =~ ^[0-9a-f]{40}$ ]]; then
+ cl_ref_path="commit"
+ else
+ cl_ref_path="release"
+ fi
else
echo "Chainlink version not provided in input. Using latest commit SHA."
chainlink_version=${{ github.sha }}
+ cl_ref_path="commit"
fi
echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT
+ echo "cl_ref_path=$cl_ref_path" >> $GITHUB_OUTPUT
elif [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
echo "Fetching Chainlink version from PR's head commit"
chainlink_version="${{ github.event.pull_request.head.sha }}"
echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT
+ echo "cl_ref_path=commit" >> $GITHUB_OUTPUT
elif [ "$GITHUB_EVENT_NAME" = "merge_queue" ]; then
echo "Fetching Chainlink version from merge queue's head commit"
chainlink_version="${{ github.event.merge_group.head_sha }}"
echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT
+ echo "cl_ref_path=commit" >> $GITHUB_OUTPUT
elif [ "$GITHUB_REF_TYPE" = "tag" ]; then
echo "Fetching Chainlink version from tag"
chainlink_version="${{ github.ref_name }}"
echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT
+ echo "cl_ref_path=release" >> $GITHUB_OUTPUT
else
echo "Unsupported trigger event. It's probably an issue with the pipeline definition. Please reach out to the Test Tooling team."
exit 1
@@ -511,7 +529,7 @@ jobs:
run-client-compatibility-matrix:
name: ${{ matrix.evm_node.product }} compatibility with ${{ matrix.evm_node.docker_image }}
- if: always() && needs.should-run.outputs.should_run == 'true' && needs.build-chainlink.result == 'success' && needs.prepare-compatibility-matrix.outputs.matrix != ''
+ if: always() && needs.should-run.outputs.should_run == 'true' && (needs.build-chainlink.result == 'success' || needs.build-chainlink.result == 'skipped') && needs.prepare-compatibility-matrix.outputs.matrix != ''
environment: integration
permissions:
checks: write
@@ -671,7 +689,7 @@ jobs:
"type": "section",
"text": {
"type": "mrkdwn",
- "text": "<${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}> | <${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.select-versions.outputs.chainlink_version }}|${{ needs.select-versions.outputs.chainlink_version }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Run>"
+ "text": "<${{ github.server_url }}/${{ github.repository }}/${{ needs.select-versions.outputs.chainlink_ref_path }}/${{ needs.select-versions.outputs.chainlink_version }}|${{ needs.select-versions.outputs.chainlink_version }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Run>"
}
}
]
diff --git a/.mockery.yaml b/.mockery.yaml
index 6e56f27795..34b886d187 100644
--- a/.mockery.yaml
+++ b/.mockery.yaml
@@ -258,14 +258,10 @@ packages:
ORM:
Runner:
PipelineParamUnmarshaler:
- github.com/smartcontractkit/chainlink/v2/core/services/headreporter:
+ github.com/smartcontractkit/chainlink/v2/core/services/promreporter:
config:
- dir: "{{ .InterfaceDir }}"
- filename: "{{ .InterfaceName | snakecase }}_mock.go"
- inpackage: true
- mockname: "Mock{{ .InterfaceName | camelcase }}"
+ dir: core/internal/mocks
interfaces:
- HeadReporter:
PrometheusBackend:
github.com/smartcontractkit/libocr/commontypes:
config:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d25c84b322..a78e070b43 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,88 @@
# Changelog Chainlink Core
+## 2.15.0 - 2024-08-19
+
+### Minor Changes
+
+- [#13472](https://github.com/smartcontractkit/chainlink/pull/13472) [`685681e1b3`](https://github.com/smartcontractkit/chainlink/commit/685681e1b3b44ec9dadd4756ec6f0407ffda8afe) Thanks [@vreff](https://github.com/vreff)! - Remove ocr2vrf
+
+ #removed all ocr2vrf and dkg OCR2 plugin materials.
+
+- [#13787](https://github.com/smartcontractkit/chainlink/pull/13787) [`e065b82d2b`](https://github.com/smartcontractkit/chainlink/commit/e065b82d2b8d565c046c2d96065ad1f593d9b488) Thanks [@cedric-cordenier](https://github.com/cedric-cordenier)! - Initialize registry syncer' contract reader lazily #keystone #internal
+
+- [#13514](https://github.com/smartcontractkit/chainlink/pull/13514) [`f84a3f2f27`](https://github.com/smartcontractkit/chainlink/commit/f84a3f2f276847d26c94bf67215e2a3600951c9c) Thanks [@ilija42](https://github.com/ilija42)! - #internal Change CR GetLatestValue to accept confidenceLevels that map to finality for contract read and event querying. Also remove Pending from BoundContract which used to map to finality for log events.
+
+- [#13805](https://github.com/smartcontractkit/chainlink/pull/13805) [`5daee38379`](https://github.com/smartcontractkit/chainlink/commit/5daee38379495cd858d8022339b5e9202e2ef0aa) Thanks [@silaslenihan](https://github.com/silaslenihan)! - #internal Added small check to allow for nil TxMeta in CW SubmitTransaction
+
+- [#13635](https://github.com/smartcontractkit/chainlink/pull/13635) [`055a9d24f8`](https://github.com/smartcontractkit/chainlink/commit/055a9d24f80a0a6cba8a44cab1a2832eef883761) Thanks [@ilija42](https://github.com/ilija42)! - #internal Add BatchGetLatestValues to ChainReader
+
+- [#13753](https://github.com/smartcontractkit/chainlink/pull/13753) [`8beda6093f`](https://github.com/smartcontractkit/chainlink/commit/8beda6093fe464a98b34ceb77bac6ba51add26b2) Thanks [@snehaagni](https://github.com/snehaagni)! - Bump to start the next version
+
+- [#13678](https://github.com/smartcontractkit/chainlink/pull/13678) [`4e3f5e8d4f`](https://github.com/smartcontractkit/chainlink/commit/4e3f5e8d4f022dcabce177ac52477820b85f04b1) Thanks [@krehermann](https://github.com/krehermann)! - #internal refactor goose migrations to use provider
+
+- [#13843](https://github.com/smartcontractkit/chainlink/pull/13843) [`31557117b2`](https://github.com/smartcontractkit/chainlink/commit/31557117b25f456b0dda38453098fa92dba55200) Thanks [@krehermann](https://github.com/krehermann)! - #internal cleanup heavyweight test databases automatically
+
+- [#13861](https://github.com/smartcontractkit/chainlink/pull/13861) [`b3c93a7f25`](https://github.com/smartcontractkit/chainlink/commit/b3c93a7f259a279060f555098efb4d683ab7e838) Thanks [@reductionista](https://github.com/reductionista)! - #bugfix Set LatestFinalizedBlock for finalized blocks saved by logpoller
+
+- [#13821](https://github.com/smartcontractkit/chainlink/pull/13821) [`5b668c186a`](https://github.com/smartcontractkit/chainlink/commit/5b668c186ac8ba294a97b20484352221f258bae2) Thanks [@ferglor](https://github.com/ferglor)! - Use the new log buffer in automation #changed
+
+### Patch Changes
+
+- [#13749](https://github.com/smartcontractkit/chainlink/pull/13749) [`e28f8a4386`](https://github.com/smartcontractkit/chainlink/commit/e28f8a4386fcd0baa09cf95e5f59e3312b592506) Thanks [@shileiwill](https://github.com/shileiwill)! - add chaos and reorg tests #added
+
+- [#13937](https://github.com/smartcontractkit/chainlink/pull/13937) [`27d9c71b19`](https://github.com/smartcontractkit/chainlink/commit/27d9c71b196961666de87bc3128d31f3c22fb3fa) Thanks [@cds95](https://github.com/cds95)! - #internal address security vulnerabilities around updating nodes and node operators on capabilities registry
+
+- [#13692](https://github.com/smartcontractkit/chainlink/pull/13692) [`5f3d58ba67`](https://github.com/smartcontractkit/chainlink/commit/5f3d58ba67a4e92832d2fa9fc2af487b697ee8ab) Thanks [@samsondav](https://github.com/samsondav)! - Add "VerboseLogging" option to mercury
+
+ Off by default, can be enabled like so:
+
+ ```toml
+ [Mercury]
+ VerboseLogging = true
+ ```
+
+ #updated
+
+- [#13687](https://github.com/smartcontractkit/chainlink/pull/13687) [`df0b06ee1c`](https://github.com/smartcontractkit/chainlink/commit/df0b06ee1ce28a8a7977bd3c9bdd8c9c307bef79) Thanks [@KodeyThomas](https://github.com/KodeyThomas)! - #added support for EIP-1559 transactions for Scroll
+
+- [#13857](https://github.com/smartcontractkit/chainlink/pull/13857) [`6bf25fc01c`](https://github.com/smartcontractkit/chainlink/commit/6bf25fc01c2e0c7de2ef9d79d511688c276368c1) Thanks [@Farber98](https://github.com/Farber98)! - remove tautological err check within evm txm. #internal
+
+- [#13839](https://github.com/smartcontractkit/chainlink/pull/13839) [`48b11ddff4`](https://github.com/smartcontractkit/chainlink/commit/48b11ddff47675c4c645764b0a25fd8a23b247ed) Thanks [@jinhoonbang](https://github.com/jinhoonbang)! - #db_update add an empty BAL spec in migrations
+
+- [#13653](https://github.com/smartcontractkit/chainlink/pull/13653) [`b1c9315776`](https://github.com/smartcontractkit/chainlink/commit/b1c9315776c906bd671c5be404b5cd0c5c34fdba) Thanks [@ferglor](https://github.com/ferglor)! - Dequeue minimum guaranteed upkeeps as a priority #changed
+
+- [#13906](https://github.com/smartcontractkit/chainlink/pull/13906) [`6adb82788a`](https://github.com/smartcontractkit/chainlink/commit/6adb82788a3b53514dd8b2c0742565e5bd175f9b) Thanks [@ettec](https://github.com/ettec)! - #internal change chain reader to use nil blocknumber when reading latest value
+
+- [#13793](https://github.com/smartcontractkit/chainlink/pull/13793) [`741351107b`](https://github.com/smartcontractkit/chainlink/commit/741351107b11966f0af8246a76ac7b5bd6a20556) Thanks [@nickcorin](https://github.com/nickcorin)! - #internal Bumped dependencies for `chainlink-common`, `chainlink-solana`, and `chainlink-starknet`.
+
+- [#13789](https://github.com/smartcontractkit/chainlink/pull/13789) [`e140a2bc1c`](https://github.com/smartcontractkit/chainlink/commit/e140a2bc1c90fa2522109c9da021c3085ed9268d) Thanks [@nickcorin](https://github.com/nickcorin)! - #internal add `NewChainWriter` method onto the dummy relayer.
+
+- [#13761](https://github.com/smartcontractkit/chainlink/pull/13761) [`89196f1fb8`](https://github.com/smartcontractkit/chainlink/commit/89196f1fb8306c90d4e45281130c894bb12328f7) Thanks [@agusaldasoro](https://github.com/agusaldasoro)! - Make send signatures configurable when Transmit in Contract Transmitter #internal
+
+- [#13795](https://github.com/smartcontractkit/chainlink/pull/13795) [`683a12e85e`](https://github.com/smartcontractkit/chainlink/commit/683a12e85e91628f240fe24f32b982b53ac30bd9) Thanks [@KuphJr](https://github.com/KuphJr)! - Updated Functions ToS contract wrappers #internal
+
+- [#13838](https://github.com/smartcontractkit/chainlink/pull/13838) [`d6ebada1b6`](https://github.com/smartcontractkit/chainlink/commit/d6ebada1b6572820a98255b8762cf60810db3210) Thanks [@ettec](https://github.com/ettec)! - #internal end to end test for streams capabilities
+
+- [#13815](https://github.com/smartcontractkit/chainlink/pull/13815) [`fb177f4ee7`](https://github.com/smartcontractkit/chainlink/commit/fb177f4ee77898dd12e20499e421a4d591fb92ef) Thanks [@KuphJr](https://github.com/KuphJr)! - #internal Updated wrappers for improved L1 -> L2 fee calculation for Functions
+
+- [#13335](https://github.com/smartcontractkit/chainlink/pull/13335) [`697e469e41`](https://github.com/smartcontractkit/chainlink/commit/697e469e41e640c8c71214461426174340527b4b) Thanks [@ibrajer](https://github.com/ibrajer)! - VRFV2Plus coordinator and wrapper split contracts between L1 and L2 chains #updated
+
+- [#13785](https://github.com/smartcontractkit/chainlink/pull/13785) [`873abacbc6`](https://github.com/smartcontractkit/chainlink/commit/873abacbc6ce1391fec245045c9436b92d3749f4) Thanks [@martin-cll](https://github.com/martin-cll)! - #internal Mercury v3: Include telemetry if bid/ask violation is detected
+
+- [#13877](https://github.com/smartcontractkit/chainlink/pull/13877) [`81a21bb56c`](https://github.com/smartcontractkit/chainlink/commit/81a21bb56cd597858221f775c796994be0f2e0da) Thanks [@ettec](https://github.com/ettec)! - #internal logging of non determinism in target server
+
+- [#13868](https://github.com/smartcontractkit/chainlink/pull/13868) [`00ef51a7c1`](https://github.com/smartcontractkit/chainlink/commit/00ef51a7c11fd227b73e3533f59950aa78b82162) Thanks [@samsondav](https://github.com/samsondav)! - Protocol-level support for preventing bid/ask variant violations in mercury #added
+
+- [#13120](https://github.com/smartcontractkit/chainlink/pull/13120) [`68a6a66919`](https://github.com/smartcontractkit/chainlink/commit/68a6a6691906aec5807f6c8dae12f9da621304ee) Thanks [@george-dorin](https://github.com/george-dorin)! - #changed Rename the `InBackupHealthReport` to `StartUpHealthReport` and enable it for DB migrations as well. This will enable health report to be available during long start-up tasks (db backups and migrations).
+
+- [#13852](https://github.com/smartcontractkit/chainlink/pull/13852) [`ced300beeb`](https://github.com/smartcontractkit/chainlink/commit/ced300beebbd1971e11e83a558bb9b1efe0290d9) Thanks [@ettec](https://github.com/ettec)! - #internal additional logging to remote target capability
+
+- [#13829](https://github.com/smartcontractkit/chainlink/pull/13829) [`51225f83f3`](https://github.com/smartcontractkit/chainlink/commit/51225f83f30a87606c3c7af56618cd16393c345e) Thanks [@nickcorin](https://github.com/nickcorin)! - #internal Use txid as the idempotency key in the evm chainwriter
+
+- [#13712](https://github.com/smartcontractkit/chainlink/pull/13712) [`535d2795c6`](https://github.com/smartcontractkit/chainlink/commit/535d2795c6e9b66315fe066c7dbaf91977d3e913) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Fix TestHeadTracker_CallsHeadTrackableCallbacks flaky test #internal
+
+- [#13713](https://github.com/smartcontractkit/chainlink/pull/13713) [`6d2b5faf10`](https://github.com/smartcontractkit/chainlink/commit/6d2b5faf10efb81a235ff3470bc205c929a6d35d) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Fix TestIntegration_KeeperPluginLogUpkeep_ErrHandler flaky test #internal
+
## 2.14.0 - 2024-07-29
### Minor Changes
diff --git a/contracts/.changeset/blue-onions-sleep.md b/contracts/.changeset/blue-onions-sleep.md
deleted file mode 100644
index 35944a0960..0000000000
--- a/contracts/.changeset/blue-onions-sleep.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-capability registry internal review
diff --git a/contracts/.changeset/brave-seahorses-shave.md b/contracts/.changeset/brave-seahorses-shave.md
deleted file mode 100644
index 3f29e6aa4a..0000000000
--- a/contracts/.changeset/brave-seahorses-shave.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-upgrade keystone contracts to 0.8.24
diff --git a/contracts/.changeset/calm-bikes-grin.md b/contracts/.changeset/calm-bikes-grin.md
deleted file mode 100644
index 675d42ce4f..0000000000
--- a/contracts/.changeset/calm-bikes-grin.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-add events, add getter and add comments #bugfix
diff --git a/contracts/.changeset/chatty-feet-clean.md b/contracts/.changeset/chatty-feet-clean.md
new file mode 100644
index 0000000000..161bfee8ac
--- /dev/null
+++ b/contracts/.changeset/chatty-feet-clean.md
@@ -0,0 +1,5 @@
+---
+'@chainlink/contracts': patch
+---
+
+#internal address security vulnerabilities around updating nodes and node operators on capabilities registry
diff --git a/contracts/.changeset/chilly-rivers-study.md b/contracts/.changeset/chilly-rivers-study.md
deleted file mode 100644
index 0bd5d713a1..0000000000
--- a/contracts/.changeset/chilly-rivers-study.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-add capability registry comment explaining why we do not validate node operator name
diff --git a/contracts/.changeset/cyan-apes-perform.md b/contracts/.changeset/cyan-apes-perform.md
deleted file mode 100644
index b35f80a981..0000000000
--- a/contracts/.changeset/cyan-apes-perform.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': minor
----
-
-#added EnumerableMapAddresses shared lib for AddressToAddress and AddressToBytes32 maps
diff --git a/contracts/.changeset/dull-phones-retire.md b/contracts/.changeset/dull-phones-retire.md
deleted file mode 100644
index be65a31fac..0000000000
--- a/contracts/.changeset/dull-phones-retire.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-capability registry informational findings
diff --git a/contracts/.changeset/empty-ants-suffer.md b/contracts/.changeset/empty-ants-suffer.md
new file mode 100644
index 0000000000..8270da10f1
--- /dev/null
+++ b/contracts/.changeset/empty-ants-suffer.md
@@ -0,0 +1,5 @@
+---
+'@chainlink/contracts': patch
+---
+
+Added updateFromPrevious method to Functions ToS contract
diff --git a/contracts/.changeset/green-pigs-reflect.md b/contracts/.changeset/green-pigs-reflect.md
deleted file mode 100644
index cb197a32bc..0000000000
--- a/contracts/.changeset/green-pigs-reflect.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-add test for v23 #added
diff --git a/contracts/.changeset/happy-plants-dance.md b/contracts/.changeset/happy-plants-dance.md
deleted file mode 100644
index 1b8c7fcb66..0000000000
--- a/contracts/.changeset/happy-plants-dance.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-allow updating capabilities and to add/remove multiple capabilities at once from the capability registry
diff --git a/contracts/.changeset/healthy-impalas-hammer.md b/contracts/.changeset/healthy-impalas-hammer.md
deleted file mode 100644
index dbbef2fca2..0000000000
--- a/contracts/.changeset/healthy-impalas-hammer.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-remove tracking deprecated arrays
diff --git a/contracts/.changeset/hip-comics-rhyme.md b/contracts/.changeset/hip-comics-rhyme.md
deleted file mode 100644
index f114282148..0000000000
--- a/contracts/.changeset/hip-comics-rhyme.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-track config count in DON struct
diff --git a/contracts/.changeset/large-news-nail.md b/contracts/.changeset/large-news-nail.md
deleted file mode 100644
index 016216426a..0000000000
--- a/contracts/.changeset/large-news-nail.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-Add Additional tests to the callWithExactGasLibrary to ensure proper gas usage
diff --git a/contracts/.changeset/long-beans-turn.md b/contracts/.changeset/long-beans-turn.md
deleted file mode 100644
index 3af5e4a217..0000000000
--- a/contracts/.changeset/long-beans-turn.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-implement remove DONs in capability registry
diff --git a/contracts/.changeset/long-cups-perform.md b/contracts/.changeset/long-cups-perform.md
deleted file mode 100644
index 93fba83b55..0000000000
--- a/contracts/.changeset/long-cups-perform.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal
diff --git a/contracts/.changeset/long-jars-protect.md b/contracts/.changeset/long-jars-protect.md
deleted file mode 100644
index 2e5a11e3c8..0000000000
--- a/contracts/.changeset/long-jars-protect.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-update error message when node does not exist
diff --git a/contracts/.changeset/moody-days-share.md b/contracts/.changeset/moody-days-share.md
deleted file mode 100644
index 6c0eb4780b..0000000000
--- a/contracts/.changeset/moody-days-share.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal stub of keystone feed consumer contract
diff --git a/contracts/.changeset/nasty-tables-guess.md b/contracts/.changeset/nasty-tables-guess.md
deleted file mode 100644
index c3c1df76cd..0000000000
--- a/contracts/.changeset/nasty-tables-guess.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-roundup #bugfix
diff --git a/contracts/.changeset/neat-brooms-repeat.md b/contracts/.changeset/neat-brooms-repeat.md
deleted file mode 100644
index 48188702bc..0000000000
--- a/contracts/.changeset/neat-brooms-repeat.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': minor
----
-
-We have multiple validation use-cases on-chain which requires the inputs to be a set, sorted-set or we need to do subset checks.Adding a library for these validations
diff --git a/contracts/.changeset/new-bugs-draw.md b/contracts/.changeset/new-bugs-draw.md
deleted file mode 100644
index 93fba83b55..0000000000
--- a/contracts/.changeset/new-bugs-draw.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal
diff --git a/contracts/.changeset/ninety-cobras-drive.md b/contracts/.changeset/ninety-cobras-drive.md
deleted file mode 100644
index cd57662462..0000000000
--- a/contracts/.changeset/ninety-cobras-drive.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-relax pragma solidity version in VRF SubscriptionAPI.sol
diff --git a/contracts/.changeset/ninety-wolves-sleep.md b/contracts/.changeset/ninety-wolves-sleep.md
deleted file mode 100644
index 7b66938838..0000000000
--- a/contracts/.changeset/ninety-wolves-sleep.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal internal-review-for-capability-registry
diff --git a/contracts/.changeset/odd-gorillas-develop.md b/contracts/.changeset/odd-gorillas-develop.md
deleted file mode 100644
index 93fba83b55..0000000000
--- a/contracts/.changeset/odd-gorillas-develop.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal
diff --git a/contracts/.changeset/orange-tips-attend.md b/contracts/.changeset/orange-tips-attend.md
deleted file mode 100644
index 2b5fa8e88e..0000000000
--- a/contracts/.changeset/orange-tips-attend.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-validate that a node is not part of a DON when removing
diff --git a/contracts/.changeset/proud-seals-draw.md b/contracts/.changeset/proud-seals-draw.md
deleted file mode 100644
index 6bda7ed255..0000000000
--- a/contracts/.changeset/proud-seals-draw.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-move v23 contracts #bugfix
diff --git a/contracts/.changeset/proud-turkeys-fold.md b/contracts/.changeset/proud-turkeys-fold.md
deleted file mode 100644
index eab0c19249..0000000000
--- a/contracts/.changeset/proud-turkeys-fold.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-VRFV2Plus coordinator and wrapper split contracts between L1 and L2 chains #updated
diff --git a/contracts/.changeset/quiet-crews-impress.md b/contracts/.changeset/quiet-crews-impress.md
deleted file mode 100644
index 5310806f1c..0000000000
--- a/contracts/.changeset/quiet-crews-impress.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal Use audited version of OCR2Base.sol in OCR3Capability.sol
diff --git a/contracts/.changeset/quiet-guests-march.md b/contracts/.changeset/quiet-guests-march.md
deleted file mode 100644
index 40285829c1..0000000000
--- a/contracts/.changeset/quiet-guests-march.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-Add update DON function to capability registry
diff --git a/contracts/.changeset/red-wasps-behave.md b/contracts/.changeset/red-wasps-behave.md
deleted file mode 100644
index 93fba83b55..0000000000
--- a/contracts/.changeset/red-wasps-behave.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal
diff --git a/contracts/.changeset/rich-crabs-smoke.md b/contracts/.changeset/rich-crabs-smoke.md
deleted file mode 100644
index fc33cf7d4e..0000000000
--- a/contracts/.changeset/rich-crabs-smoke.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal Keystone Forwarder and Feeds Consumer
diff --git a/contracts/.changeset/selfish-files-learn.md b/contracts/.changeset/selfish-files-learn.md
deleted file mode 100644
index 3d348d1d8d..0000000000
--- a/contracts/.changeset/selfish-files-learn.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-add getters in capability registry
diff --git a/contracts/.changeset/serious-cats-fold.md b/contracts/.changeset/serious-cats-fold.md
deleted file mode 100644
index ccf89c9b04..0000000000
--- a/contracts/.changeset/serious-cats-fold.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-Implemented improved L1 fee calculation for L2 chains in Functions contracts
diff --git a/contracts/.changeset/seven-apes-drop.md b/contracts/.changeset/seven-apes-drop.md
deleted file mode 100644
index 2882975f66..0000000000
--- a/contracts/.changeset/seven-apes-drop.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-increase solhint max-warnings to 2 (from 0) to allow workflow to pass
diff --git a/contracts/.changeset/silent-ravens-lay.md b/contracts/.changeset/silent-ravens-lay.md
deleted file mode 100644
index e987e9e082..0000000000
--- a/contracts/.changeset/silent-ravens-lay.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-remove update capabilities from capability registry
diff --git a/contracts/.changeset/six-ears-sin.md b/contracts/.changeset/six-ears-sin.md
deleted file mode 100644
index 186481a36e..0000000000
--- a/contracts/.changeset/six-ears-sin.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-update ICapabilityConfiguration interface
diff --git a/contracts/.changeset/smart-rules-love.md b/contracts/.changeset/smart-rules-love.md
deleted file mode 100644
index eb2542a685..0000000000
--- a/contracts/.changeset/smart-rules-love.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-Added Base Sepolia to ChainUtils #changed
diff --git a/contracts/.changeset/smart-trainers-begin.md b/contracts/.changeset/smart-trainers-begin.md
deleted file mode 100644
index 5e76abd21e..0000000000
--- a/contracts/.changeset/smart-trainers-begin.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-check data size #bugfix
diff --git a/contracts/.changeset/smooth-years-reply.md b/contracts/.changeset/smooth-years-reply.md
deleted file mode 100644
index 330310cb8d..0000000000
--- a/contracts/.changeset/smooth-years-reply.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-link transfer status check #bugfix
diff --git a/contracts/.changeset/sour-parents-explode.md b/contracts/.changeset/sour-parents-explode.md
deleted file mode 100644
index ff5b52b98f..0000000000
--- a/contracts/.changeset/sour-parents-explode.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-update node signer type
diff --git a/contracts/.changeset/spicy-mirrors-care.md b/contracts/.changeset/spicy-mirrors-care.md
deleted file mode 100644
index 93fba83b55..0000000000
--- a/contracts/.changeset/spicy-mirrors-care.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal
diff --git a/contracts/.changeset/stupid-lamps-sell.md b/contracts/.changeset/stupid-lamps-sell.md
deleted file mode 100644
index ad5d70a04a..0000000000
--- a/contracts/.changeset/stupid-lamps-sell.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-verify valid node operator when adding nodes to capability registry
diff --git a/contracts/.changeset/sweet-geese-rescue.md b/contracts/.changeset/sweet-geese-rescue.md
deleted file mode 100644
index ba0f2c916c..0000000000
--- a/contracts/.changeset/sweet-geese-rescue.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-update uint256 to uint32 for donId declaration in capability config interface
diff --git a/contracts/.changeset/swift-ads-stare.md b/contracts/.changeset/swift-ads-stare.md
deleted file mode 100644
index 33a5d0cf16..0000000000
--- a/contracts/.changeset/swift-ads-stare.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-return hashed capability ids
diff --git a/contracts/.changeset/tender-roses-know.md b/contracts/.changeset/tender-roses-know.md
deleted file mode 100644
index 383837fce0..0000000000
--- a/contracts/.changeset/tender-roses-know.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': minor
----
-
-#internal Modify ChainReader tester contract.
diff --git a/contracts/.changeset/tricky-comics-scream.md b/contracts/.changeset/tricky-comics-scream.md
deleted file mode 100644
index f7cd1ceeab..0000000000
--- a/contracts/.changeset/tricky-comics-scream.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-remove stale automation HH tests
diff --git a/contracts/.changeset/tricky-meals-decide.md b/contracts/.changeset/tricky-meals-decide.md
deleted file mode 100644
index afbb24ad9f..0000000000
--- a/contracts/.changeset/tricky-meals-decide.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-"@chainlink/contracts": patch
----
-
-#bugfix
-fix a funding bug in LinkAvailableBalanceMonitor
diff --git a/contracts/.changeset/two-doors-dance.md b/contracts/.changeset/two-doors-dance.md
deleted file mode 100644
index 93fba83b55..0000000000
--- a/contracts/.changeset/two-doors-dance.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal
diff --git a/contracts/.changeset/witty-onions-relate.md b/contracts/.changeset/witty-onions-relate.md
deleted file mode 100644
index 30d3da6df9..0000000000
--- a/contracts/.changeset/witty-onions-relate.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-#internal KeystoneFeedsConsumer bytes10 decoding bugfix
diff --git a/contracts/.changeset/yellow-snails-wash.md b/contracts/.changeset/yellow-snails-wash.md
deleted file mode 100644
index 479fedcbe4..0000000000
--- a/contracts/.changeset/yellow-snails-wash.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@chainlink/contracts': patch
----
-
-return don capability config contract config from capability registry
diff --git a/contracts/CHANGELOG.md b/contracts/CHANGELOG.md
index ba6dabfeb0..01a9dd4b6c 100644
--- a/contracts/CHANGELOG.md
+++ b/contracts/CHANGELOG.md
@@ -1,5 +1,106 @@
# @chainlink/contracts
+## 1.2.0 - 2024-07-18
+
+### Minor Changes
+
+- [#13428](https://github.com/smartcontractkit/chainlink/pull/13428) [`a02bb0a`](https://github.com/smartcontractkit/chainlink/commit/a02bb0a48cb78c815ec3a2f3bd351f2efc3869d7) Thanks [@elatoskinas](https://github.com/elatoskinas)! - #added EnumerableMapAddresses shared lib for AddressToAddress and AddressToBytes32 maps
+
+- [#13774](https://github.com/smartcontractkit/chainlink/pull/13774) [`b5c0ea9`](https://github.com/smartcontractkit/chainlink/commit/b5c0ea9f106ced6daf8e1f35e88bc39d7b82de28) Thanks [@0xsuryansh](https://github.com/0xsuryansh)! - We have multiple validation use-cases on-chain which requires the inputs to be a set, sorted-set or we need to do subset checks.Adding a library for these validations
+
+- [#13514](https://github.com/smartcontractkit/chainlink/pull/13514) [`f84a3f2`](https://github.com/smartcontractkit/chainlink/commit/f84a3f2f276847d26c94bf67215e2a3600951c9c) Thanks [@ilija42](https://github.com/ilija42)! - #internal Modify ChainReader tester contract.
+
+### Patch Changes
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - capability registry internal review
+
+- [#13546](https://github.com/smartcontractkit/chainlink/pull/13546) [`10ddafa`](https://github.com/smartcontractkit/chainlink/commit/10ddafaebedb94ad5a59968d19256b8c4592857f) Thanks [@cds95](https://github.com/cds95)! - upgrade keystone contracts to 0.8.24
+
+- [#13376](https://github.com/smartcontractkit/chainlink/pull/13376) [`bb40d51`](https://github.com/smartcontractkit/chainlink/commit/bb40d51502487b010a1d6621db42458356dbbdc0) Thanks [@shileiwill](https://github.com/shileiwill)! - add events, add getter and add comments #bugfix
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - add capability registry comment explaining why we do not validate node operator name
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - capability registry informational findings
+
+- [#13644](https://github.com/smartcontractkit/chainlink/pull/13644) [`2ed4478`](https://github.com/smartcontractkit/chainlink/commit/2ed4478ecc7fa6bada1138d204c12236fe56a810) Thanks [@shileiwill](https://github.com/shileiwill)! - add test for v23 #added
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - allow updating capabilities and to add/remove multiple capabilities at once from the capability registry
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - remove tracking deprecated arrays
+
+- [#13183](https://github.com/smartcontractkit/chainlink/pull/13183) [`9630475`](https://github.com/smartcontractkit/chainlink/commit/96304756a77cdb2acf251d21d59b6aa8b55bf61a) Thanks [@cds95](https://github.com/cds95)! - track config count in DON struct
+
+- [#13326](https://github.com/smartcontractkit/chainlink/pull/13326) [`732eea0`](https://github.com/smartcontractkit/chainlink/commit/732eea0f834e1f84c3a7520e131698d38762c78b) Thanks [@jhweintraub](https://github.com/jhweintraub)! - Add Additional tests to the callWithExactGasLibrary to ensure proper gas usage
+
+- [#13183](https://github.com/smartcontractkit/chainlink/pull/13183) [`9630475`](https://github.com/smartcontractkit/chainlink/commit/96304756a77cdb2acf251d21d59b6aa8b55bf61a) Thanks [@cds95](https://github.com/cds95)! - implement remove DONs in capability registry
+
+- [#13425](https://github.com/smartcontractkit/chainlink/pull/13425) [`eeb363f`](https://github.com/smartcontractkit/chainlink/commit/eeb363f1230415dde573607a095b177c612d3bef) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal
+
+- [#13453](https://github.com/smartcontractkit/chainlink/pull/13453) [`8c98c80`](https://github.com/smartcontractkit/chainlink/commit/8c98c80376c3b6d72bffeab62ee45a74449b6ef5) Thanks [@cds95](https://github.com/cds95)! - update error message when node does not exist
+
+- [#13366](https://github.com/smartcontractkit/chainlink/pull/13366) [`d53d6d0`](https://github.com/smartcontractkit/chainlink/commit/d53d6d08dac5d3ee27ae89012669c6c2455295c8) Thanks [@bolekk](https://github.com/bolekk)! - #internal stub of keystone feed consumer contract
+
+- [#13287](https://github.com/smartcontractkit/chainlink/pull/13287) [`8491b24`](https://github.com/smartcontractkit/chainlink/commit/8491b247cd5ff240d281ecfbabc0fe0fa19134f1) Thanks [@shileiwill](https://github.com/shileiwill)! - roundup #bugfix
+
+- [#13426](https://github.com/smartcontractkit/chainlink/pull/13426) [`592b2bb`](https://github.com/smartcontractkit/chainlink/commit/592b2bb5a84a0e8858f77c5faa99e881f911878c) Thanks [@archseer](https://github.com/archseer)! - #internal
+
+- [#13600](https://github.com/smartcontractkit/chainlink/pull/13600) [`4406364`](https://github.com/smartcontractkit/chainlink/commit/4406364702dd5af0b34c0397c00f8489510ecb11) Thanks [@jinhoonbang](https://github.com/jinhoonbang)! - relax pragma solidity version in VRF SubscriptionAPI.sol
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - #internal internal-review-for-capability-registry
+
+- [#13528](https://github.com/smartcontractkit/chainlink/pull/13528) [`95502ad`](https://github.com/smartcontractkit/chainlink/commit/95502ad2699d63891662594f70e82e76682f2ed8) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - validate that a node is not part of a DON when removing
+
+- [#13504](https://github.com/smartcontractkit/chainlink/pull/13504) [`815c5ea`](https://github.com/smartcontractkit/chainlink/commit/815c5ea8715462e00f6ea10cdc0b93ec3e1ba505) Thanks [@shileiwill](https://github.com/shileiwill)! - move v23 contracts #bugfix
+
+- [#13335](https://github.com/smartcontractkit/chainlink/pull/13335) [`697e469`](https://github.com/smartcontractkit/chainlink/commit/697e469e41e640c8c71214461426174340527b4b) Thanks [@ibrajer](https://github.com/ibrajer)! - VRFV2Plus coordinator and wrapper split contracts between L1 and L2 chains #updated
+
+- [#13487](https://github.com/smartcontractkit/chainlink/pull/13487) [`5e27da9`](https://github.com/smartcontractkit/chainlink/commit/5e27da95f09f21272e93f086bc2de5a9bc2ae399) Thanks [@bolekk](https://github.com/bolekk)! - #internal Use audited version of OCR2Base.sol in OCR3Capability.sol
+
+- [#13183](https://github.com/smartcontractkit/chainlink/pull/13183) [`9630475`](https://github.com/smartcontractkit/chainlink/commit/96304756a77cdb2acf251d21d59b6aa8b55bf61a) Thanks [@cds95](https://github.com/cds95)! - Add update DON function to capability registry
+
+- [#13566](https://github.com/smartcontractkit/chainlink/pull/13566) [`f1d478d`](https://github.com/smartcontractkit/chainlink/commit/f1d478d8bbba92f9753f7a1d6733ba4efd1f616a) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal
+
+- [#13389](https://github.com/smartcontractkit/chainlink/pull/13389) [`3959091`](https://github.com/smartcontractkit/chainlink/commit/3959091d4f3925b64cb6b0b55b7f7c72a4f924b9) Thanks [@bolekk](https://github.com/bolekk)! - #internal Keystone Forwarder and Feeds Consumer
+
+- [#13183](https://github.com/smartcontractkit/chainlink/pull/13183) [`9630475`](https://github.com/smartcontractkit/chainlink/commit/96304756a77cdb2acf251d21d59b6aa8b55bf61a) Thanks [@cds95](https://github.com/cds95)! - add getters in capability registry
+
+- [#13815](https://github.com/smartcontractkit/chainlink/pull/13815) [`fb177f4`](https://github.com/smartcontractkit/chainlink/commit/fb177f4ee77898dd12e20499e421a4d591fb92ef) Thanks [@KuphJr](https://github.com/KuphJr)! - Implemented improved L1 fee calculation for L2 chains in Functions contracts
+
+- [#13237](https://github.com/smartcontractkit/chainlink/pull/13237) [`53312f0`](https://github.com/smartcontractkit/chainlink/commit/53312f01f3459408402ed97a9e3935ec63ccee7a) Thanks [@erikburt](https://github.com/erikburt)! - increase solhint max-warnings to 2 (from 0) to allow workflow to pass
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - remove update capabilities from capability registry
+
+- [#13183](https://github.com/smartcontractkit/chainlink/pull/13183) [`9630475`](https://github.com/smartcontractkit/chainlink/commit/96304756a77cdb2acf251d21d59b6aa8b55bf61a) Thanks [@cds95](https://github.com/cds95)! - update ICapabilityConfiguration interface
+
+- [#13216](https://github.com/smartcontractkit/chainlink/pull/13216) [`6099abb`](https://github.com/smartcontractkit/chainlink/commit/6099abbdbfb3ad396ca1ed5138ecd7a13159de19) Thanks [@ibrajer](https://github.com/ibrajer)! - Added Base Sepolia to ChainUtils #changed
+
+- [#13352](https://github.com/smartcontractkit/chainlink/pull/13352) [`33a9cdf`](https://github.com/smartcontractkit/chainlink/commit/33a9cdf8d7c42cab4682121b50d5fa12d9b5ff27) Thanks [@shileiwill](https://github.com/shileiwill)! - check data size #bugfix
+
+- [#13177](https://github.com/smartcontractkit/chainlink/pull/13177) [`0d58a8d`](https://github.com/smartcontractkit/chainlink/commit/0d58a8d5db24f42720226e73328e501637ba59c5) Thanks [@shileiwill](https://github.com/shileiwill)! - link transfer status check #bugfix
+
+- [#13183](https://github.com/smartcontractkit/chainlink/pull/13183) [`9630475`](https://github.com/smartcontractkit/chainlink/commit/96304756a77cdb2acf251d21d59b6aa8b55bf61a) Thanks [@cds95](https://github.com/cds95)! - update node signer type
+
+- [#13580](https://github.com/smartcontractkit/chainlink/pull/13580) [`0d4a3b2`](https://github.com/smartcontractkit/chainlink/commit/0d4a3b2cd8ff938ba018d982ef514c754a7df345) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - verify valid node operator when adding nodes to capability registry
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - update uint256 to uint32 for donId declaration in capability config interface
+
+- [#13453](https://github.com/smartcontractkit/chainlink/pull/13453) [`8c98c80`](https://github.com/smartcontractkit/chainlink/commit/8c98c80376c3b6d72bffeab62ee45a74449b6ef5) Thanks [@cds95](https://github.com/cds95)! - return hashed capability ids
+
+- [#13676](https://github.com/smartcontractkit/chainlink/pull/13676) [`ed6b9ad`](https://github.com/smartcontractkit/chainlink/commit/ed6b9ad7909e09d0ff9850b7a1e34a0137762642) Thanks [@RyanRHall](https://github.com/RyanRHall)! - remove stale automation HH tests
+
+- [#13364](https://github.com/smartcontractkit/chainlink/pull/13364) [`fc007a9`](https://github.com/smartcontractkit/chainlink/commit/fc007a94846c178bc9d5203dbff6b6b8c7546a71) Thanks [@FelixFan1992](https://github.com/FelixFan1992)! - #bugfix
+ fix a funding bug in LinkAvailableBalanceMonitor
+
+- [#13569](https://github.com/smartcontractkit/chainlink/pull/13569) [`f5a70eb`](https://github.com/smartcontractkit/chainlink/commit/f5a70eb09abc9a4d859442c9bd062a74a7ec9c54) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal
+
+- [#13436](https://github.com/smartcontractkit/chainlink/pull/13436) [`f37afb9`](https://github.com/smartcontractkit/chainlink/commit/f37afb9ebaeda10f8b3873b069b8a824e60a81c3) Thanks [@bolekk](https://github.com/bolekk)! - #internal KeystoneFeedsConsumer bytes10 decoding bugfix
+
+- [#13368](https://github.com/smartcontractkit/chainlink/pull/13368) [`000f2cb`](https://github.com/smartcontractkit/chainlink/commit/000f2cb36b7d9b6d046d383c85996ae1ae7a606e) Thanks [@cds95](https://github.com/cds95)! - return don capability config contract config from capability registry
+
## 1.1.1 - 2024-05-23
### Patch Changes
@@ -32,7 +133,6 @@
- [#13022](https://github.com/smartcontractkit/chainlink/pull/13022) [`2805fa6c9b`](https://github.com/smartcontractkit/chainlink/commit/2805fa6c9b469d535edcd3d66c08e1d22bbaa2d0) Thanks [@cds95](https://github.com/cds95)! - #internal
-
- [#12812](https://github.com/smartcontractkit/chainlink/pull/12812) [`5b33a3296f`](https://github.com/smartcontractkit/chainlink/commit/5b33a3296f895cec8a23ba2e235989868f398ddb) Thanks [@shileiwill](https://github.com/shileiwill)! - Support decimals #added
- [#12979](https://github.com/smartcontractkit/chainlink/pull/12979) [`0c4c24ad8c`](https://github.com/smartcontractkit/chainlink/commit/0c4c24ad8c95e505cd2a29be711cc40e612658b0) Thanks [@cds95](https://github.com/cds95)! - Add function to remove node operators from capability registry
diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot
index b54662b868..69e0271684 100644
--- a/contracts/gas-snapshots/functions.gas-snapshot
+++ b/contracts/gas-snapshots/functions.gas-snapshot
@@ -1,21 +1,21 @@
-ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumGoerli() (gas: 15903239)
-ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumMainnet() (gas: 15903196)
-ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumSepolia() (gas: 15903265)
-ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseGoerli() (gas: 15903033)
-ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseMainnet() (gas: 15903011)
-ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseSepolia() (gas: 15903060)
-ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismGoerli() (gas: 15902946)
-ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismMainnet() (gas: 15902968)
-ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismSepolia() (gas: 15903011)
+ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumGoerli() (gas: 16076840)
+ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumMainnet() (gas: 16076819)
+ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumSepolia() (gas: 16076888)
+ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseGoerli() (gas: 16076608)
+ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseMainnet() (gas: 16076564)
+ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseSepolia() (gas: 16076635)
+ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismGoerli() (gas: 16076521)
+ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismMainnet() (gas: 16076543)
+ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismSepolia() (gas: 16076586)
FunctionsBilling_Constructor:test_Constructor_Success() (gas: 17982)
-FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13260)
-FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15875)
+FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13283)
+FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15853)
FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32450)
-FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 90999)
+FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 90977)
FunctionsBilling_EstimateCost:test_EstimateCost_SuccessLowGasPrice() (gas: 91102)
FunctionsBilling_GetAdminFeeJuels:test_GetAdminFeeJuels_Success() (gas: 18671)
-FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 30727)
-FunctionsBilling_GetDONFeeJuels:test_GetDONFeeJuels_Success() (gas: 41128)
+FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 30750)
+FunctionsBilling_GetDONFeeJuels:test_GetDONFeeJuels_Success() (gas: 41151)
FunctionsBilling_GetOperationFee:test_GetOperationFeeJuels_Success() (gas: 40548)
FunctionsBilling_GetWeiPerUnitLink:test_GetWeiPerUnitLink_Success() (gas: 29751)
FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertIfInsufficientBalance() (gas: 70136)
@@ -23,41 +23,41 @@ FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertWithNoBalance() (gas:
FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessCoordinatorOwner() (gas: 129908)
FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceNoAmountGiven() (gas: 171930)
FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceValidAmountGiven() (gas: 145165)
-FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13297)
+FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13320)
FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 222357)
-FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 21654)
-FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 54121)
+FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 21632)
+FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 54099)
FunctionsBilling__DisperseFeePool:test__DisperseFeePool_RevertIfNotSet() (gas: 8810)
-FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13375)
-FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 185953)
+FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13353)
+FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 185976)
FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 524582)
FunctionsClient_Constructor:test_Constructor_Success() (gas: 10407)
-FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14617)
-FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22917)
+FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14595)
+FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22983)
FunctionsClient__SendRequest:test__SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 55069)
FunctionsCoordinator_Constructor:test_Constructor_Success() (gas: 15085)
-FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15378)
+FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15356)
FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_Success() (gas: 91691)
-FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15356)
-FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 515973)
-FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20365)
+FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15334)
+FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 515951)
+FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20409)
FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_Success() (gas: 88970)
-FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_RevertNotOwner() (gas: 13892)
+FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_RevertNotOwner() (gas: 13915)
FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_Success() (gas: 513165)
-FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22736)
-FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 152672)
+FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22802)
+FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 152650)
FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessFound() (gas: 15106)
-FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 22938)
+FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 22916)
FunctionsRequest_DEFAULT_BUFFER_SIZE:test_DEFAULT_BUFFER_SIZE() (gas: 3089)
FunctionsRequest_EncodeCBOR:test_EncodeCBOR_Success() (gas: 3066)
FunctionsRequest_REQUEST_DATA_VERSION:test_REQUEST_DATA_VERSION() (gas: 3068)
FunctionsRouter_Constructor:test_Constructor_Success() (gas: 15107)
-FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 172497)
+FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 172475)
FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 163010)
FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 38777)
FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35900)
FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 180976)
-FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28086)
+FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28152)
FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 156535)
FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 335070)
FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 348695)
@@ -65,19 +65,19 @@ FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2627478)
FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 658423)
FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 18323)
FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 13241)
-FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 40170)
-FunctionsRouter_GetContractById:test_GetContractById_RevertIfRouteDoesNotExist() (gas: 13839)
+FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 40193)
+FunctionsRouter_GetContractById:test_GetContractById_RevertIfRouteDoesNotExist() (gas: 13862)
FunctionsRouter_GetContractById:test_GetContractById_SuccessIfRouteExists() (gas: 17704)
-FunctionsRouter_GetProposedContractById:test_GetProposedContractById_RevertIfRouteDoesNotExist() (gas: 16373)
-FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRouteExists() (gas: 24266)
+FunctionsRouter_GetProposedContractById:test_GetProposedContractById_RevertIfRouteDoesNotExist() (gas: 16417)
+FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRouteExists() (gas: 24289)
FunctionsRouter_GetProposedContractSet:test_GetProposedContractSet_Success() (gas: 27289)
FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertGasLimitTooBig() (gas: 28087)
FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertInvalidConfig() (gas: 41095)
FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 24632)
-FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13338)
-FunctionsRouter_Pause:test_Pause_Success() (gas: 20669)
-FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14791)
-FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() (gas: 21693)
+FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13361)
+FunctionsRouter_Pause:test_Pause_Success() (gas: 20647)
+FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14769)
+FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() (gas: 21716)
FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfLengthMismatch() (gas: 14670)
FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNewContract() (gas: 19048)
FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23392)
@@ -85,149 +85,151 @@ FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (ga
FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59400)
FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 217996)
FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29426)
-FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57904)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57882)
FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 208451)
FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 50953)
FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25082)
-FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29132)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29177)
FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34291)
-FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 226346)
-FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65896)
+FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 226324)
+FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65918)
FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36012)
FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29896)
FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 57539)
FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27503)
-FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35717)
+FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35672)
FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40810)
FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 232783)
FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 214899)
FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 33531)
-FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13403)
-FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13293)
-FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77725)
-FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 24437)
-FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 63353)
-FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13336)
+FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13381)
+FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13337)
+FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77748)
+FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 24415)
+FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 63331)
+FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13314)
FunctionsRouter_UpdateContracts:test_UpdateContracts_Success() (gas: 39269)
FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60413)
FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 61040)
FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 139706)
FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62780)
-FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 239911)
+FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 239919)
FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 138033)
FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164977)
-FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12955)
-FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 102450)
-FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87205)
+FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12933)
+FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 102428)
+FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87272)
FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18100)
FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 96221)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15053)
-FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 102529)
-FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89318)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 102507)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89341)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20157)
-FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 218330)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 218308)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 115656)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 126964)
FunctionsSubscriptions_CancelSubscription_ReceiveDeposit:test_CancelSubscription_SuccessRecieveDeposit() (gas: 75369)
FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 10488)
FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28688)
-FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17994)
+FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 18038)
FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 353899)
-FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 17256)
-FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessInvalidSubscription() (gas: 13438)
-FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessValidSubscription() (gas: 41243)
+FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 17279)
+FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessInvalidSubscription() (gas: 13504)
+FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessValidSubscription() (gas: 41221)
FunctionsSubscriptions_GetSubscription:test_GetSubscription_Success() (gas: 32968)
FunctionsSubscriptions_GetSubscriptionCount:test_GetSubscriptionCount_Success() (gas: 13305)
-FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfEndIsAfterLastSubscription() (gas: 16547)
+FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfEndIsAfterLastSubscription() (gas: 16570)
FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfStartIsAfterEnd() (gas: 13465)
-FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_Success() (gas: 65990)
-FunctionsSubscriptions_GetTotalBalance:test_GetTotalBalance_Success() (gas: 15347)
+FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_Success() (gas: 65968)
+FunctionsSubscriptions_GetTotalBalance:test_GetTotalBalance_Success() (gas: 15370)
FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoCalldata() (gas: 39908)
FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoSubscription() (gas: 42382)
FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNotLink() (gas: 13419)
FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfPaused() (gas: 47325)
FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_Success() (gas: 84314)
-FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfAmountMoreThanBalance() (gas: 20766)
+FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfAmountMoreThanBalance() (gas: 20744)
FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfBalanceInvariant() (gas: 189)
-FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfNoAmount() (gas: 15641)
+FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfNoAmount() (gas: 15686)
FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfPaused() (gas: 20859)
-FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessPaysRecipient() (gas: 60075)
+FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessPaysRecipient() (gas: 60119)
FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessSetsBalanceToZero() (gas: 57716)
-FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNoSubscription() (gas: 12818)
-FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15549)
-FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 55141)
+FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNoSubscription() (gas: 12796)
+FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15594)
+FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 55177)
FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 49607)
FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 53166)
-FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 186533)
-FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17945)
+FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 186511)
+FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17923)
FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfBalanceInvariant() (gas: 210)
-FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15555)
+FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15600)
FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 33839)
-FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddressZero() (gas: 31649)
+FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddressZero() (gas: 31627)
FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 33935)
FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 31584)
-FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 17818)
-FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 203333)
-FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27664)
-FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57815)
+FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 17796)
+FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 203311)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27642)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57793)
FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15013)
-FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 119775)
-FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17969)
-FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20137)
-FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68596)
-FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_SuccessChangeProposedOwner() (gas: 83539)
-FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15554)
-FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41376)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 119820)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17947)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20181)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68574)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_SuccessChangeProposedOwner() (gas: 83582)
+FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15577)
+FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41358)
FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 30310)
FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription() (gas: 15031)
FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 102444)
-FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87254)
-FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18058)
+FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87277)
+FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18103)
FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 215863)
-FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42088)
+FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42066)
FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12888)
FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15684)
FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 38434)
FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (gas: 25955)
FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25261)
-FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28242)
-FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 58416)
-FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26418)
+FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28220)
+FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 58394)
+FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26462)
FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15759)
FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 153701)
-FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94913)
-FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25859)
-FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 88990)
-FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23619)
-FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866552)
-FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 28525)
-FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946965)
-FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 104509)
-FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15491)
-FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 97541)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94943)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25925)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 89013)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23620)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866619)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 28526)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946966)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 104555)
+FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15535)
+FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 97587)
FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 15345)
FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19243)
FunctionsTermsOfServiceAllowList_GetAllowedSendersCount:test_GetAllowedSendersCount_Success() (gas: 13332)
-FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13153024)
-FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16554)
-FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13284)
-FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20312)
+FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13326576)
+FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16532)
+FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13307)
+FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20335)
FunctionsTermsOfServiceAllowList_GetBlockedSendersCount:test_GetBlockedSendersCount_Success() (gas: 13268)
-FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13153034)
+FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13326564)
FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16549)
-FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13367)
-FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18537)
-FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 16388)
+FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13345)
+FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18580)
+FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 16411)
FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11918)
-FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 16257)
-FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23848)
+FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 16235)
+FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23877)
FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15776)
FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 86974)
-FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13502)
-FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 96216)
-FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13812)
-FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22817)
-Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84702)
+FunctionsTermsOfServiceAllowList_MigratePreviouslyAllowedSenders:test_MigratePreviouslyAllowedSenders_RevertIfNotOwner() (gas: 13987)
+FunctionsTermsOfServiceAllowList_MigratePreviouslyAllowedSenders:test_MigratePreviouslyAllowedSenders_Success() (gas: 210636)
+FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13548)
+FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 96240)
+FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13819)
+FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22824)
+Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84725)
Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79140)
Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73419)
Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MaximumGas() (gas: 20562)
diff --git a/contracts/scripts/native_solc_compile_all_keystone b/contracts/scripts/native_solc_compile_all_keystone
index 0516b2aedb..a42b06b8f6 100755
--- a/contracts/scripts/native_solc_compile_all_keystone
+++ b/contracts/scripts/native_solc_compile_all_keystone
@@ -32,3 +32,4 @@ compileContract () {
compileContract keystone/CapabilitiesRegistry.sol
compileContract keystone/KeystoneForwarder.sol
compileContract keystone/OCR3Capability.sol
+compileContract keystone/KeystoneFeedsConsumer.sol
diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol
index 04604e6797..0ba8e5d6ca 100644
--- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol
+++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol
@@ -16,7 +16,8 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController,
using EnumerableSet for EnumerableSet.AddressSet;
/// @inheritdoc ITypeAndVersion
- string public constant override typeAndVersion = "Functions Terms of Service Allow List v1.1.0";
+ string public constant override typeAndVersion = "Functions Terms of Service Allow List v1.1.1";
+ address private s_previousToSContract;
EnumerableSet.AddressSet private s_allowedSenders;
EnumerableSet.AddressSet private s_blockedSenders;
@@ -29,6 +30,7 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController,
error InvalidUsage();
error RecipientIsBlocked();
error InvalidCalldata();
+ error NoPreviousToSContract();
TermsOfServiceAllowListConfig private s_config;
@@ -41,7 +43,8 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController,
constructor(
TermsOfServiceAllowListConfig memory config,
address[] memory initialAllowedSenders,
- address[] memory initialBlockedSenders
+ address[] memory initialBlockedSenders,
+ address previousToSContract
) ConfirmedOwner(msg.sender) {
updateConfig(config);
@@ -56,6 +59,8 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController,
}
s_blockedSenders.add(initialBlockedSenders[j]);
}
+
+ s_previousToSContract = previousToSContract;
}
// ================================================================
@@ -197,4 +202,19 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController,
return blockedSenders;
}
+
+ /// @inheritdoc ITermsOfServiceAllowList
+ function migratePreviouslyAllowedSenders(address[] memory previousSendersToAdd) external override onlyOwner {
+ if (s_previousToSContract == address(0)) {
+ revert NoPreviousToSContract();
+ }
+ IAccessController previousToSContract = IAccessController(s_previousToSContract);
+ for (uint256 i = 0; i < previousSendersToAdd.length; ++i) {
+ if (previousToSContract.hasAccess(previousSendersToAdd[i], "")) {
+ if (!s_blockedSenders.contains(previousSendersToAdd[i])) {
+ s_allowedSenders.add(previousSendersToAdd[i]);
+ }
+ }
+ }
+ }
}
diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol
index 65db9c42b6..32a0ecef79 100644
--- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol
+++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol
@@ -69,6 +69,10 @@ interface ITermsOfServiceAllowList {
uint64 blockedSenderIdxStart,
uint64 blockedSenderIdxEnd
) external view returns (address[] memory blockedSenders);
+
+ /// @notice Enables migrating any previously allowed senders to the new contract
+ /// @param previousSendersToAdd - List of addresses to migrate. These address must be allowed on the previous ToS contract and not blocked
+ function migratePreviouslyAllowedSenders(address[] memory previousSendersToAdd) external;
}
// ================================================================
diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol
index e121f7b881..9bf09748b8 100644
--- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol
+++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol
@@ -11,7 +11,7 @@ import "forge-std/Vm.sol";
/// @notice #constructor
contract FunctionsTermsOfServiceAllowList_Constructor is FunctionsRoutesSetup {
function test_Constructor_Success() public {
- assertEq(s_termsOfServiceAllowList.typeAndVersion(), "Functions Terms of Service Allow List v1.1.0");
+ assertEq(s_termsOfServiceAllowList.typeAndVersion(), "Functions Terms of Service Allow List v1.1.1");
assertEq(s_termsOfServiceAllowList.owner(), OWNER_ADDRESS);
}
}
@@ -511,3 +511,47 @@ contract FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange is FunctionsR
s_termsOfServiceAllowList.getBlockedSendersInRange(1, BlockedSendersCount + 1);
}
}
+
+/// @notice #migratePreviouslyAllowedSenders
+contract FunctionsTermsOfServiceAllowList_MigratePreviouslyAllowedSenders is FunctionsRoutesSetup {
+ function setUp() public virtual override {
+ FunctionsRoutesSetup.setUp();
+ }
+
+ function test_MigratePreviouslyAllowedSenders_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ address[] memory empty = new address[](0);
+ s_termsOfServiceAllowList.migratePreviouslyAllowedSenders(empty);
+ }
+
+ function test_MigratePreviouslyAllowedSenders_Success() public {
+ address previouslyAllowedSender1 = 0x1000000000000000000000000000000000000000;
+ address previouslyAllowedSender2 = 0x2000000000000000000000000000000000000000;
+ address currentlyBlockedSender = 0xB000000000000000000000000000000000000000;
+
+ address[] memory mockPreviousAllowlist = new address[](3);
+ mockPreviousAllowlist[0] = previouslyAllowedSender1;
+ mockPreviousAllowlist[1] = currentlyBlockedSender;
+ mockPreviousAllowlist[2] = previouslyAllowedSender2;
+
+ s_termsOfServiceAllowList.blockSender(currentlyBlockedSender);
+
+ vm.mockCall(
+ MOCK_PREVIOUS_TOS_ADDRESS,
+ abi.encodeWithSelector(TermsOfServiceAllowList.hasAccess.selector),
+ abi.encode(true)
+ );
+ s_termsOfServiceAllowList.migratePreviouslyAllowedSenders(mockPreviousAllowlist);
+
+ address[] memory currentlyAllowedSenders = s_termsOfServiceAllowList.getAllAllowedSenders();
+
+ address[] memory expectedAllowedSenders = new address[](2);
+ expectedAllowedSenders[0] = previouslyAllowedSender1;
+ expectedAllowedSenders[1] = previouslyAllowedSender2;
+ assertEq(currentlyAllowedSenders, expectedAllowedSenders);
+ }
+}
diff --git a/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol b/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol
index 815366e62a..444fc18fe8 100644
--- a/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol
+++ b/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol
@@ -37,6 +37,7 @@ contract FunctionsRouterSetup is BaseTest {
int256 internal LINK_USD_RATE = 1_500_000_000;
uint8 internal LINK_USD_DECIMALS = 8;
+ address public MOCK_PREVIOUS_TOS_ADDRESS = 0x746f730000000000000000000000000000000000;
uint256 internal TOS_SIGNER_PRIVATE_KEY = 0x3;
address internal TOS_SIGNER = vm.addr(TOS_SIGNER_PRIVATE_KEY);
@@ -57,7 +58,8 @@ contract FunctionsRouterSetup is BaseTest {
s_termsOfServiceAllowList = new TermsOfServiceAllowList(
getTermsOfServiceConfig(),
initialAllowedSenders,
- initialBlockedSenders
+ initialBlockedSenders,
+ MOCK_PREVIOUS_TOS_ADDRESS
);
}
diff --git a/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol b/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol
index 6b150dc5d7..ba61584d0a 100644
--- a/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol
+++ b/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol
@@ -502,7 +502,7 @@ contract CapabilitiesRegistry is OwnerIsCreator, TypeAndVersionInterface {
NodeOperator memory nodeOperator = nodeOperators[i];
if (nodeOperator.admin == address(0)) revert InvalidNodeOperatorAdmin();
- if (msg.sender != nodeOperator.admin && msg.sender != owner) revert AccessForbidden(msg.sender);
+ if (msg.sender != currentNodeOperator.admin && msg.sender != owner) revert AccessForbidden(msg.sender);
if (
currentNodeOperator.admin != nodeOperator.admin ||
@@ -611,11 +611,12 @@ contract CapabilitiesRegistry is OwnerIsCreator, TypeAndVersionInterface {
bool isOwner = msg.sender == owner();
for (uint256 i; i < nodes.length; ++i) {
NodeParams memory node = nodes[i];
- NodeOperator memory nodeOperator = s_nodeOperators[node.nodeOperatorId];
- if (!isOwner && msg.sender != nodeOperator.admin) revert AccessForbidden(msg.sender);
-
Node storage storedNode = s_nodes[node.p2pId];
+ NodeOperator memory nodeOperator = s_nodeOperators[storedNode.nodeOperatorId];
+
if (storedNode.signer == bytes32("")) revert NodeDoesNotExist(node.p2pId);
+ if (!isOwner && msg.sender != nodeOperator.admin) revert AccessForbidden(msg.sender);
+
if (node.signer == bytes32("")) revert InvalidNodeSigner();
bytes32 previousSigner = storedNode.signer;
diff --git a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol
index bc722eff29..ba1a7c6a8c 100644
--- a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol
+++ b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol
@@ -1,15 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
+import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol";
+import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol";
import {IReceiver} from "./interfaces/IReceiver.sol";
-import {KeystoneFeedsPermissionHandler} from "./KeystoneFeedsPermissionHandler.sol";
-import {KeystoneFeedDefaultMetadataLib} from "./lib/KeystoneFeedDefaultMetadataLib.sol";
-
-contract KeystoneFeedsConsumer is IReceiver, KeystoneFeedsPermissionHandler {
- using KeystoneFeedDefaultMetadataLib for bytes;
+contract KeystoneFeedsConsumer is IReceiver, OwnerIsCreator, IERC165 {
event FeedReceived(bytes32 indexed feedId, uint224 price, uint32 timestamp);
+ error UnauthorizedSender(address sender);
+ error UnauthorizedWorkflowOwner(address workflowOwner);
+ error UnauthorizedWorkflowName(bytes10 workflowName);
+
struct ReceivedFeedReport {
bytes32 FeedId;
uint224 Price;
@@ -22,11 +24,53 @@ contract KeystoneFeedsConsumer is IReceiver, KeystoneFeedsPermissionHandler {
}
mapping(bytes32 feedId => StoredFeedReport feedReport) internal s_feedReports;
+ address[] internal s_allowedSendersList;
+ mapping(address sender => bool) internal s_allowedSenders;
+ address[] internal s_allowedWorkflowOwnersList;
+ mapping(address owner => bool) internal s_allowedWorkflowOwners;
+ bytes10[] internal s_allowedWorkflowNamesList;
+ mapping(bytes10 workflowName => bool) internal s_allowedWorkflowNames;
+
+ function setConfig(
+ address[] calldata _allowedSendersList,
+ address[] calldata _allowedWorkflowOwnersList,
+ bytes10[] calldata _allowedWorkflowNamesList
+ ) external onlyOwner {
+ for (uint32 i = 0; i < s_allowedSendersList.length; ++i) {
+ s_allowedSenders[s_allowedSendersList[i]] = false;
+ }
+ for (uint32 i = 0; i < _allowedSendersList.length; ++i) {
+ s_allowedSenders[_allowedSendersList[i]] = true;
+ }
+ s_allowedSendersList = _allowedSendersList;
+ for (uint32 i = 0; i < s_allowedWorkflowOwnersList.length; ++i) {
+ s_allowedWorkflowOwners[s_allowedWorkflowOwnersList[i]] = false;
+ }
+ for (uint32 i = 0; i < _allowedWorkflowOwnersList.length; ++i) {
+ s_allowedWorkflowOwners[_allowedWorkflowOwnersList[i]] = true;
+ }
+ s_allowedWorkflowOwnersList = _allowedWorkflowOwnersList;
+ for (uint32 i = 0; i < s_allowedWorkflowNamesList.length; ++i) {
+ s_allowedWorkflowNames[s_allowedWorkflowNamesList[i]] = false;
+ }
+ for (uint32 i = 0; i < _allowedWorkflowNamesList.length; ++i) {
+ s_allowedWorkflowNames[_allowedWorkflowNamesList[i]] = true;
+ }
+ s_allowedWorkflowNamesList = _allowedWorkflowNamesList;
+ }
function onReport(bytes calldata metadata, bytes calldata rawReport) external {
- (bytes10 workflowName, address workflowOwner, bytes2 reportName) = metadata._extractMetadataInfo();
+ if (!s_allowedSenders[msg.sender]) {
+ revert UnauthorizedSender(msg.sender);
+ }
- _validateReportPermission(msg.sender, workflowOwner, workflowName, reportName);
+ (bytes10 workflowName, address workflowOwner) = _getInfo(metadata);
+ if (!s_allowedWorkflowNames[workflowName]) {
+ revert UnauthorizedWorkflowName(workflowName);
+ }
+ if (!s_allowedWorkflowOwners[workflowOwner]) {
+ revert UnauthorizedWorkflowOwner(workflowOwner);
+ }
ReceivedFeedReport[] memory feeds = abi.decode(rawReport, (ReceivedFeedReport[]));
for (uint256 i = 0; i < feeds.length; ++i) {
@@ -35,8 +79,27 @@ contract KeystoneFeedsConsumer is IReceiver, KeystoneFeedsPermissionHandler {
}
}
+ // solhint-disable-next-line chainlink-solidity/explicit-returns
+ function _getInfo(bytes memory metadata) internal pure returns (bytes10 workflowName, address workflowOwner) {
+ // (first 32 bytes contain length of the byte array)
+ // workflow_cid // offset 32, size 32
+ // workflow_name // offset 64, size 10
+ // workflow_owner // offset 74, size 20
+ // report_name // offset 94, size 2
+ assembly {
+ // no shifting needed for bytes10 type
+ workflowName := mload(add(metadata, 64))
+ // shift right by 12 bytes to get the actual value
+ workflowOwner := shr(mul(12, 8), mload(add(metadata, 74)))
+ }
+ }
+
function getPrice(bytes32 feedId) external view returns (uint224, uint32) {
StoredFeedReport memory report = s_feedReports[feedId];
return (report.Price, report.Timestamp);
}
+
+ function supportsInterface(bytes4 interfaceId) public pure override returns (bool) {
+ return interfaceId == this.onReport.selector;
+ }
}
diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodeOperatorsTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodeOperatorsTest.t.sol
index e0d1742c98..721fd35eae 100644
--- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodeOperatorsTest.t.sol
+++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodeOperatorsTest.t.sol
@@ -19,10 +19,7 @@ contract CapabilitiesRegistry_UpdateNodeOperatorTest is BaseTest {
changePrank(STRANGER);
CapabilitiesRegistry.NodeOperator[] memory nodeOperators = new CapabilitiesRegistry.NodeOperator[](1);
- nodeOperators[0] = CapabilitiesRegistry.NodeOperator({
- admin: NEW_NODE_OPERATOR_ADMIN,
- name: NEW_NODE_OPERATOR_NAME
- });
+ nodeOperators[0] = CapabilitiesRegistry.NodeOperator({admin: ADMIN, name: NEW_NODE_OPERATOR_NAME});
uint32[] memory nodeOperatorIds = new uint32[](1);
nodeOperatorIds[0] = TEST_NODE_OPERATOR_ID;
diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodesTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodesTest.t.sol
index 43c6adc35b..9b516767f2 100644
--- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodesTest.t.sol
+++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodesTest.t.sol
@@ -59,6 +59,24 @@ contract CapabilitiesRegistry_UpdateNodesTest is BaseTest {
s_CapabilitiesRegistry.updateNodes(nodes);
}
+ function test_RevertWhen_CalledByAnotherNodeOperatorAdmin() public {
+ changePrank(NODE_OPERATOR_TWO_ADMIN);
+ CapabilitiesRegistry.NodeParams[] memory nodes = new CapabilitiesRegistry.NodeParams[](1);
+
+ bytes32[] memory hashedCapabilityIds = new bytes32[](1);
+ hashedCapabilityIds[0] = s_basicHashedCapabilityId;
+
+ nodes[0] = CapabilitiesRegistry.NodeParams({
+ nodeOperatorId: TEST_NODE_OPERATOR_TWO_ID,
+ p2pId: P2P_ID,
+ signer: NEW_NODE_SIGNER,
+ hashedCapabilityIds: hashedCapabilityIds
+ });
+
+ vm.expectRevert(abi.encodeWithSelector(CapabilitiesRegistry.AccessForbidden.selector, NODE_OPERATOR_TWO_ADMIN));
+ s_CapabilitiesRegistry.updateNodes(nodes);
+ }
+
function test_RevertWhen_NodeDoesNotExist() public {
changePrank(NODE_OPERATOR_ONE_ADMIN);
CapabilitiesRegistry.NodeParams[] memory nodes = new CapabilitiesRegistry.NodeParams[](1);
diff --git a/core/capabilities/integration_tests/keystone_contracts_setup.go b/core/capabilities/integration_tests/keystone_contracts_setup.go
new file mode 100644
index 0000000000..42269d1bd4
--- /dev/null
+++ b/core/capabilities/integration_tests/keystone_contracts_setup.go
@@ -0,0 +1,345 @@
+package integration_tests
+
+import (
+ "context"
+ "encoding/hex"
+ "fmt"
+ "log"
+ "os"
+ "strings"
+ "sync"
+ "testing"
+ "time"
+
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/eth/ethconfig"
+ gethlog "github.com/ethereum/go-ethereum/log"
+ "github.com/stretchr/testify/require"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/durationpb"
+
+ ragetypes "github.com/smartcontractkit/libocr/ragep2p/types"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"
+ "github.com/smartcontractkit/chainlink-common/pkg/values"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
+ "github.com/smartcontractkit/chainlink-common/pkg/services"
+
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/feeds_consumer"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/forwarder"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+
+ kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
+)
+
+type peer struct {
+ PeerID string
+ Signer string
+}
+
+func peerIDToBytes(peerID string) ([32]byte, error) {
+ var peerIDB ragetypes.PeerID
+ err := peerIDB.UnmarshalText([]byte(peerID))
+ if err != nil {
+ return [32]byte{}, err
+ }
+
+ return peerIDB, nil
+}
+
+func peers(ps []peer) ([][32]byte, error) {
+ out := [][32]byte{}
+ for _, p := range ps {
+ b, err := peerIDToBytes(p.PeerID)
+ if err != nil {
+ return nil, err
+ }
+
+ out = append(out, b)
+ }
+
+ return out, nil
+}
+
+func peerToNode(nopID uint32, p peer) (kcr.CapabilitiesRegistryNodeParams, error) {
+ peerIDB, err := peerIDToBytes(p.PeerID)
+ if err != nil {
+ return kcr.CapabilitiesRegistryNodeParams{}, fmt.Errorf("failed to convert peerID: %w", err)
+ }
+
+ sig := strings.TrimPrefix(p.Signer, "0x")
+ signerB, err := hex.DecodeString(sig)
+ if err != nil {
+ return kcr.CapabilitiesRegistryNodeParams{}, fmt.Errorf("failed to convert signer: %w", err)
+ }
+
+ var sigb [32]byte
+ copy(sigb[:], signerB)
+
+ return kcr.CapabilitiesRegistryNodeParams{
+ NodeOperatorId: nopID,
+ P2pId: peerIDB,
+ Signer: sigb,
+ }, nil
+}
+
+func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workflowDonPeers []peer, triggerDonPeers []peer,
+ targetDonPeerIDs []peer,
+ transactOpts *bind.TransactOpts, backend *ethBackend) common.Address {
+ addr, _, reg, err := kcr.DeployCapabilitiesRegistry(transactOpts, backend)
+ require.NoError(t, err)
+
+ backend.Commit()
+
+ streamsTrigger := kcr.CapabilitiesRegistryCapability{
+ LabelledName: "streams-trigger",
+ Version: "1.0.0",
+ CapabilityType: uint8(capabilities.CapabilityTypeTrigger),
+ }
+ sid, err := reg.GetHashedCapabilityId(&bind.CallOpts{}, streamsTrigger.LabelledName, streamsTrigger.Version)
+ require.NoError(t, err)
+
+ writeChain := kcr.CapabilitiesRegistryCapability{
+ LabelledName: "write_geth-testnet",
+ Version: "1.0.0",
+ CapabilityType: uint8(capabilities.CapabilityTypeTarget),
+ }
+ wid, err := reg.GetHashedCapabilityId(&bind.CallOpts{}, writeChain.LabelledName, writeChain.Version)
+ if err != nil {
+ log.Printf("failed to call GetHashedCapabilityId: %s", err)
+ }
+
+ ocr := kcr.CapabilitiesRegistryCapability{
+ LabelledName: "offchain_reporting",
+ Version: "1.0.0",
+ CapabilityType: uint8(capabilities.CapabilityTypeConsensus),
+ }
+ ocrid, err := reg.GetHashedCapabilityId(&bind.CallOpts{}, ocr.LabelledName, ocr.Version)
+ require.NoError(t, err)
+
+ _, err = reg.AddCapabilities(transactOpts, []kcr.CapabilitiesRegistryCapability{
+ streamsTrigger,
+ writeChain,
+ ocr,
+ })
+ require.NoError(t, err)
+ backend.Commit()
+
+ _, err = reg.AddNodeOperators(transactOpts, []kcr.CapabilitiesRegistryNodeOperator{
+ {
+ Admin: transactOpts.From,
+ Name: "TEST_NODE_OPERATOR",
+ },
+ })
+ require.NoError(t, err)
+ blockHash := backend.Commit()
+
+ logs, err := backend.FilterLogs(ctx, ethereum.FilterQuery{
+ BlockHash: &blockHash,
+ FromBlock: nil,
+ ToBlock: nil,
+ Addresses: nil,
+ Topics: nil,
+ })
+
+ require.NoError(t, err)
+
+ recLog, err := reg.ParseNodeOperatorAdded(logs[0])
+ require.NoError(t, err)
+
+ nopID := recLog.NodeOperatorId
+ nodes := []kcr.CapabilitiesRegistryNodeParams{}
+ for _, wfPeer := range workflowDonPeers {
+ n, innerErr := peerToNode(nopID, wfPeer)
+ require.NoError(t, innerErr)
+
+ n.HashedCapabilityIds = [][32]byte{ocrid}
+ nodes = append(nodes, n)
+ }
+
+ for _, triggerPeer := range triggerDonPeers {
+ n, innerErr := peerToNode(nopID, triggerPeer)
+ require.NoError(t, innerErr)
+
+ n.HashedCapabilityIds = [][32]byte{sid}
+ nodes = append(nodes, n)
+ }
+
+ for _, targetPeer := range targetDonPeerIDs {
+ n, innerErr := peerToNode(nopID, targetPeer)
+ require.NoError(t, innerErr)
+
+ n.HashedCapabilityIds = [][32]byte{wid}
+ nodes = append(nodes, n)
+ }
+
+ _, err = reg.AddNodes(transactOpts, nodes)
+ require.NoError(t, err)
+
+ // workflow DON
+ ps, err := peers(workflowDonPeers)
+ require.NoError(t, err)
+
+ cc := newCapabilityConfig()
+ ccb, err := proto.Marshal(cc)
+ require.NoError(t, err)
+
+ cfgs := []kcr.CapabilitiesRegistryCapabilityConfiguration{
+ {
+ CapabilityId: ocrid,
+ Config: ccb,
+ },
+ }
+
+ workflowDonF := uint8(2)
+ _, err = reg.AddDON(transactOpts, ps, cfgs, false, true, workflowDonF)
+ require.NoError(t, err)
+
+ // trigger DON
+ ps, err = peers(triggerDonPeers)
+ require.NoError(t, err)
+
+ triggerDonF := 1
+ config := &pb.RemoteTriggerConfig{
+ RegistrationRefresh: durationpb.New(20000 * time.Millisecond),
+ RegistrationExpiry: durationpb.New(60000 * time.Millisecond),
+ // F + 1
+ MinResponsesToAggregate: uint32(triggerDonF) + 1,
+ }
+ configb, err := proto.Marshal(config)
+ require.NoError(t, err)
+
+ cfgs = []kcr.CapabilitiesRegistryCapabilityConfiguration{
+ {
+ CapabilityId: sid,
+ Config: configb,
+ },
+ }
+
+ _, err = reg.AddDON(transactOpts, ps, cfgs, true, false, uint8(triggerDonF))
+ require.NoError(t, err)
+
+ // target DON
+ ps, err = peers(targetDonPeerIDs)
+ require.NoError(t, err)
+
+ cfgs = []kcr.CapabilitiesRegistryCapabilityConfiguration{
+ {
+ CapabilityId: wid,
+ Config: ccb,
+ },
+ }
+
+ targetDonF := uint8(1)
+ _, err = reg.AddDON(transactOpts, ps, cfgs, true, false, targetDonF)
+ require.NoError(t, err)
+
+ backend.Commit()
+
+ return addr
+}
+
+func newCapabilityConfig() *pb.CapabilityConfig {
+ return &pb.CapabilityConfig{
+ DefaultConfig: values.Proto(values.EmptyMap()).GetMapValue(),
+ }
+}
+
+func setupForwarderContract(t *testing.T, workflowDonPeers []peer, workflowDonId uint32,
+ configVersion uint32, f uint8,
+ transactOpts *bind.TransactOpts, backend *ethBackend) (common.Address, *forwarder.KeystoneForwarder) {
+ addr, _, fwd, err := forwarder.DeployKeystoneForwarder(transactOpts, backend)
+ require.NoError(t, err)
+ backend.Commit()
+
+ var signers []common.Address
+ for _, p := range workflowDonPeers {
+ signers = append(signers, common.HexToAddress(p.Signer))
+ }
+
+ _, err = fwd.SetConfig(transactOpts, workflowDonId, configVersion, f, signers)
+ require.NoError(t, err)
+ backend.Commit()
+
+ return addr, fwd
+}
+
+func setupConsumerContract(t *testing.T, transactOpts *bind.TransactOpts, backend *ethBackend,
+ forwarderAddress common.Address, workflowOwner string, workflowName string) (common.Address, *feeds_consumer.KeystoneFeedsConsumer) {
+ addr, _, consumer, err := feeds_consumer.DeployKeystoneFeedsConsumer(transactOpts, backend)
+ require.NoError(t, err)
+ backend.Commit()
+
+ var nameBytes [10]byte
+ copy(nameBytes[:], workflowName)
+
+ ownerAddr := common.HexToAddress(workflowOwner)
+
+ _, err = consumer.SetConfig(transactOpts, []common.Address{forwarderAddress}, []common.Address{ownerAddr}, [][10]byte{nameBytes})
+ require.NoError(t, err)
+
+ backend.Commit()
+
+ return addr, consumer
+}
+
+type ethBackend struct {
+ services.StateMachine
+ *backends.SimulatedBackend
+
+ blockTimeProcessingTime time.Duration
+
+ stopCh services.StopChan
+ wg sync.WaitGroup
+}
+
+func setupBlockchain(t *testing.T, initialEth int, blockTimeProcessingTime time.Duration) (*ethBackend, *bind.TransactOpts) {
+ transactOpts := testutils.MustNewSimTransactor(t) // config contract deployer and owner
+ genesisData := core.GenesisAlloc{transactOpts.From: {Balance: assets.Ether(initialEth).ToInt()}}
+ backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil))
+ gethlog.SetDefault(gethlog.NewLogger(gethlog.NewTerminalHandlerWithLevel(os.Stderr, gethlog.LevelWarn, true)))
+ backend.Commit()
+
+ return ðBackend{SimulatedBackend: backend, stopCh: make(services.StopChan),
+ blockTimeProcessingTime: blockTimeProcessingTime}, transactOpts
+}
+
+func (b *ethBackend) Start(ctx context.Context) error {
+ return b.StartOnce("ethBackend", func() error {
+ b.wg.Add(1)
+ go func() {
+ defer b.wg.Done()
+ ticker := time.NewTicker(b.blockTimeProcessingTime)
+ defer ticker.Stop()
+
+ for {
+ select {
+ case <-b.stopCh:
+ return
+ case <-ctx.Done():
+ return
+ case <-ticker.C:
+ b.SimulatedBackend.Commit()
+ }
+ }
+ }()
+
+ return nil
+ })
+}
+
+func (b *ethBackend) Close() error {
+ return b.StopOnce("ethBackend", func() error {
+ close(b.stopCh)
+ b.wg.Wait()
+ return nil
+ })
+}
diff --git a/core/capabilities/integration_tests/mock_dispatcher.go b/core/capabilities/integration_tests/mock_dispatcher.go
new file mode 100644
index 0000000000..f685f0ad2e
--- /dev/null
+++ b/core/capabilities/integration_tests/mock_dispatcher.go
@@ -0,0 +1,195 @@
+package integration_tests
+
+import (
+ "context"
+ "fmt"
+ "sync"
+ "testing"
+ "time"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
+ remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types"
+ p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
+
+ "google.golang.org/protobuf/proto"
+)
+
+// testAsyncMessageBroker backs the dispatchers created for each node in the test and effectively
+// acts as the rageP2P network layer.
+type testAsyncMessageBroker struct {
+ services.StateMachine
+ t *testing.T
+
+ chanBufferSize int
+ stopCh services.StopChan
+ wg sync.WaitGroup
+
+ peerIDToBrokerNode map[p2ptypes.PeerID]*brokerNode
+
+ mux sync.Mutex
+}
+
+func newTestAsyncMessageBroker(t *testing.T, chanBufferSize int) *testAsyncMessageBroker {
+ return &testAsyncMessageBroker{
+ t: t,
+ stopCh: make(services.StopChan),
+ chanBufferSize: chanBufferSize,
+ peerIDToBrokerNode: make(map[p2ptypes.PeerID]*brokerNode),
+ }
+}
+
+func (a *testAsyncMessageBroker) Start(ctx context.Context) error {
+ return a.StartOnce("testAsyncMessageBroker", func() error {
+ return nil
+ })
+}
+
+func (a *testAsyncMessageBroker) Close() error {
+ return a.StopOnce("testAsyncMessageBroker", func() error {
+ close(a.stopCh)
+ a.wg.Wait()
+ return nil
+ })
+}
+
+// NewDispatcherForNode creates a new dispatcher for a node with the given peer ID.
+func (a *testAsyncMessageBroker) NewDispatcherForNode(nodePeerID p2ptypes.PeerID) remotetypes.Dispatcher {
+ return &brokerDispatcher{
+ callerPeerID: nodePeerID,
+ broker: a,
+ }
+}
+
+func (a *testAsyncMessageBroker) HealthReport() map[string]error {
+ return nil
+}
+
+func (a *testAsyncMessageBroker) Name() string {
+ return "testAsyncMessageBroker"
+}
+
+func (a *testAsyncMessageBroker) registerReceiverNode(nodePeerID p2ptypes.PeerID, capabilityId string, capabilityDonID uint32, receiver remotetypes.Receiver) {
+ a.mux.Lock()
+ defer a.mux.Unlock()
+
+ node, ok := a.peerIDToBrokerNode[nodePeerID]
+ if !ok {
+ node = a.newNode()
+ a.peerIDToBrokerNode[nodePeerID] = node
+ }
+
+ node.registerReceiverCh <- ®isterReceiverRequest{
+ receiverKey: receiverKey{
+ capabilityId: capabilityId,
+ donId: capabilityDonID,
+ },
+ receiver: receiver,
+ }
+}
+
+func (a *testAsyncMessageBroker) Send(msg *remotetypes.MessageBody) {
+ peerID := toPeerID(msg.Receiver)
+ node, ok := a.peerIDToBrokerNode[peerID]
+ if !ok {
+ panic(fmt.Sprintf("node not found for peer ID %v", peerID))
+ }
+
+ node.receiveCh <- msg
+}
+
+type brokerNode struct {
+ registerReceiverCh chan *registerReceiverRequest
+ receiveCh chan *remotetypes.MessageBody
+}
+
+type receiverKey struct {
+ capabilityId string
+ donId uint32
+}
+
+type registerReceiverRequest struct {
+ receiverKey
+ receiver remotetypes.Receiver
+}
+
+func (a *testAsyncMessageBroker) newNode() *brokerNode {
+ n := &brokerNode{
+ receiveCh: make(chan *remotetypes.MessageBody, a.chanBufferSize),
+ registerReceiverCh: make(chan *registerReceiverRequest, a.chanBufferSize),
+ }
+
+ a.wg.Add(1)
+ go func() {
+ defer a.wg.Done()
+ receivers := make(map[receiverKey]remotetypes.Receiver)
+ for {
+ select {
+ case <-a.stopCh:
+ return
+ case msg := <-n.receiveCh:
+ k := receiverKey{
+ capabilityId: msg.CapabilityId,
+ donId: msg.CapabilityDonId,
+ }
+
+ r, ok := receivers[k]
+ if !ok {
+ panic(fmt.Sprintf("receiver not found for key %+v", k))
+ }
+
+ r.Receive(tests.Context(a.t), msg)
+ case reg := <-n.registerReceiverCh:
+ receivers[reg.receiverKey] = reg.receiver
+ }
+ }
+ }()
+ return n
+}
+
+func toPeerID(id []byte) p2ptypes.PeerID {
+ return [32]byte(id)
+}
+
+type broker interface {
+ Send(msg *remotetypes.MessageBody)
+}
+
+type brokerDispatcher struct {
+ callerPeerID p2ptypes.PeerID
+ broker broker
+}
+
+func (t *brokerDispatcher) Send(peerID p2ptypes.PeerID, msgBody *remotetypes.MessageBody) error {
+ clonedMsg := proto.Clone(msgBody).(*remotetypes.MessageBody)
+ clonedMsg.Version = 1
+ clonedMsg.Sender = t.callerPeerID[:]
+ clonedMsg.Receiver = peerID[:]
+ clonedMsg.Timestamp = time.Now().UnixMilli()
+ t.broker.Send(clonedMsg)
+ return nil
+}
+
+func (t *brokerDispatcher) SetReceiver(capabilityId string, donId uint32, receiver remotetypes.Receiver) error {
+ t.broker.(*testAsyncMessageBroker).registerReceiverNode(t.callerPeerID, capabilityId, donId, receiver)
+ return nil
+}
+func (t *brokerDispatcher) RemoveReceiver(capabilityId string, donId uint32) {}
+
+func (t *brokerDispatcher) Start(context.Context) error { return nil }
+
+func (t *brokerDispatcher) Close() error {
+ return nil
+}
+
+func (t *brokerDispatcher) Ready() error {
+ return nil
+}
+
+func (t *brokerDispatcher) HealthReport() map[string]error {
+ return nil
+}
+
+func (t *brokerDispatcher) Name() string {
+ return "mockDispatcher"
+}
diff --git a/core/capabilities/integration_tests/mock_libocr.go b/core/capabilities/integration_tests/mock_libocr.go
new file mode 100644
index 0000000000..39c53d48af
--- /dev/null
+++ b/core/capabilities/integration_tests/mock_libocr.go
@@ -0,0 +1,198 @@
+package integration_tests
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "math/rand"
+ "sync"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/libocr/commontypes"
+ "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types"
+ "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3"
+ "github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key"
+)
+
+type libocrNode struct {
+ ocr3types.ReportingPlugin[[]byte]
+ *ocr3.ContractTransmitter
+ key ocr2key.KeyBundle
+}
+
+// mockLibOCR is a mock libocr implementation for testing purposes that simulates libocr protocol rounds without having
+// to setup the libocr network
+type mockLibOCR struct {
+ services.StateMachine
+ t *testing.T
+
+ nodes []*libocrNode
+ f uint8
+ protocolRoundInterval time.Duration
+
+ seqNr uint64
+ outcomeCtx ocr3types.OutcomeContext
+
+ stopCh services.StopChan
+ wg sync.WaitGroup
+}
+
+func newMockLibOCR(t *testing.T, f uint8, protocolRoundInterval time.Duration) *mockLibOCR {
+ return &mockLibOCR{
+ t: t,
+ f: f, outcomeCtx: ocr3types.OutcomeContext{
+ SeqNr: 0,
+ PreviousOutcome: nil,
+ Epoch: 0,
+ Round: 0,
+ },
+ protocolRoundInterval: protocolRoundInterval,
+ stopCh: make(services.StopChan),
+ }
+}
+
+func (m *mockLibOCR) Start(ctx context.Context) error {
+ return m.StartOnce("mockLibOCR", func() error {
+ m.wg.Add(1)
+ go func() {
+ defer m.wg.Done()
+
+ ticker := time.NewTicker(m.protocolRoundInterval)
+ defer ticker.Stop()
+
+ for {
+ select {
+ case <-m.stopCh:
+ return
+ case <-ctx.Done():
+ return
+ case <-ticker.C:
+ err := m.simulateProtocolRound(ctx)
+ if err != nil {
+ require.FailNow(m.t, err.Error())
+ }
+ }
+ }
+ }()
+ return nil
+ })
+}
+
+func (m *mockLibOCR) Close() error {
+ return m.StopOnce("mockLibOCR", func() error {
+ close(m.stopCh)
+ m.wg.Wait()
+ return nil
+ })
+}
+
+func (m *mockLibOCR) AddNode(plugin ocr3types.ReportingPlugin[[]byte], transmitter *ocr3.ContractTransmitter, key ocr2key.KeyBundle) {
+ m.nodes = append(m.nodes, &libocrNode{plugin, transmitter, key})
+}
+
+func (m *mockLibOCR) simulateProtocolRound(ctx context.Context) error {
+ // randomly select a leader
+ leader := m.nodes[rand.Intn(len(m.nodes))]
+
+ // get the query
+ query, err := leader.Query(ctx, m.outcomeCtx)
+ if err != nil {
+ return fmt.Errorf("failed to get query: %w", err)
+ }
+
+ var observations []types.AttributedObservation
+ for oracleID, node := range m.nodes {
+ obs, err2 := node.Observation(ctx, m.outcomeCtx, query)
+ if err2 != nil {
+ return fmt.Errorf("failed to get observation: %w", err)
+ }
+
+ observations = append(observations, types.AttributedObservation{
+ Observation: obs,
+ Observer: commontypes.OracleID(oracleID),
+ })
+ }
+
+ var outcomes []ocr3types.Outcome
+ for _, node := range m.nodes {
+ outcome, err2 := node.Outcome(m.outcomeCtx, query, observations)
+ if err2 != nil {
+ return fmt.Errorf("failed to get outcome: %w", err)
+ }
+
+ if len(outcome) == 0 {
+ return nil // wait until all nodes have an outcome for testing purposes
+ }
+
+ outcomes = append(outcomes, outcome)
+ }
+
+ // if all outcomes are equal proceed to reports
+ for _, outcome := range outcomes {
+ if !bytes.Equal(outcome, outcomes[0]) {
+ return nil
+ }
+ }
+
+ reports, err := leader.Reports(0, outcomes[0])
+ if err != nil {
+ return fmt.Errorf("failed to get reports: %w", err)
+ }
+ for _, report := range reports {
+ // create signatures
+ var signatures []types.AttributedOnchainSignature
+ for i, node := range m.nodes {
+ sig, err := node.key.Sign(types.ReportContext{}, report.Report)
+ if err != nil {
+ return fmt.Errorf("failed to sign report: %w", err)
+ }
+
+ signatures = append(signatures, types.AttributedOnchainSignature{
+ Signer: commontypes.OracleID(i),
+ Signature: sig,
+ })
+
+ if uint8(len(signatures)) == m.f+1 {
+ break
+ }
+ }
+
+ for _, node := range m.nodes {
+ accept, err := node.ShouldAcceptAttestedReport(ctx, m.seqNr, report)
+ if err != nil {
+ return fmt.Errorf("failed to check if report should be accepted: %w", err)
+ }
+ if !accept {
+ continue
+ }
+
+ transmit, err := node.ShouldTransmitAcceptedReport(ctx, m.seqNr, report)
+ if err != nil {
+ return fmt.Errorf("failed to check if report should be transmitted: %w", err)
+ }
+
+ if !transmit {
+ continue
+ }
+
+ err = node.Transmit(ctx, types.ConfigDigest{}, 0, report, signatures)
+ if err != nil {
+ return fmt.Errorf("failed to transmit report: %w", err)
+ }
+ }
+
+ m.seqNr++
+ m.outcomeCtx = ocr3types.OutcomeContext{
+ SeqNr: 0,
+ PreviousOutcome: outcomes[0],
+ }
+ }
+
+ return nil
+}
diff --git a/core/capabilities/integration_tests/mock_trigger.go b/core/capabilities/integration_tests/mock_trigger.go
new file mode 100644
index 0000000000..cb673f54ff
--- /dev/null
+++ b/core/capabilities/integration_tests/mock_trigger.go
@@ -0,0 +1,147 @@
+package integration_tests
+
+import (
+ "context"
+ "fmt"
+ "strconv"
+ "sync"
+ "testing"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities/datastreams"
+ "github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/values"
+)
+
+const triggerID = "streams-trigger@1.0.0"
+
+type reportsSink struct {
+ services.StateMachine
+ triggers []streamsTrigger
+
+ stopCh services.StopChan
+ wg sync.WaitGroup
+}
+
+func newReportsSink() *reportsSink {
+ return &reportsSink{
+ stopCh: make(services.StopChan),
+ }
+}
+
+func (r *reportsSink) Start(ctx context.Context) error {
+ return r.StartOnce("reportsSink", func() error {
+ return nil
+ })
+}
+
+func (r *reportsSink) Close() error {
+ return r.StopOnce("reportsSink", func() error {
+ close(r.stopCh)
+ r.wg.Wait()
+ return nil
+ })
+}
+
+func (r *reportsSink) sendReports(reportList []*datastreams.FeedReport) {
+ for _, trigger := range r.triggers {
+ resp, err := wrapReports(reportList, "1", 12, datastreams.SignersMetadata{})
+ if err != nil {
+ panic(err)
+ }
+ trigger.sendResponse(resp)
+ }
+}
+
+func (r *reportsSink) getNewTrigger(t *testing.T) *streamsTrigger {
+ trigger := streamsTrigger{t: t, toSend: make(chan capabilities.CapabilityResponse, 1000),
+ wg: &r.wg, stopCh: r.stopCh}
+ r.triggers = append(r.triggers, trigger)
+ return &trigger
+}
+
+type streamsTrigger struct {
+ t *testing.T
+ cancel context.CancelFunc
+ toSend chan capabilities.CapabilityResponse
+
+ wg *sync.WaitGroup
+ stopCh services.StopChan
+}
+
+func (s *streamsTrigger) sendResponse(resp capabilities.CapabilityResponse) {
+ s.toSend <- resp
+}
+
+func (s *streamsTrigger) Info(ctx context.Context) (capabilities.CapabilityInfo, error) {
+ return capabilities.MustNewCapabilityInfo(
+ triggerID,
+ capabilities.CapabilityTypeTrigger,
+ "issues a trigger when a report is received.",
+ ), nil
+}
+
+func (s *streamsTrigger) RegisterTrigger(ctx context.Context, request capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) {
+ if s.cancel != nil {
+ s.t.Fatal("trigger already registered")
+ }
+
+ responseCh := make(chan capabilities.CapabilityResponse)
+
+ ctxWithCancel, cancel := context.WithCancel(ctx)
+ s.cancel = cancel
+ s.wg.Add(1)
+ go func() {
+ defer s.wg.Done()
+ select {
+ case <-s.stopCh:
+ return
+ case <-ctxWithCancel.Done():
+ return
+ case resp := <-s.toSend:
+ responseCh <- resp
+ }
+ }()
+
+ return responseCh, nil
+}
+
+func (s *streamsTrigger) UnregisterTrigger(ctx context.Context, request capabilities.CapabilityRequest) error {
+ if s.cancel == nil {
+ s.t.Fatal("trigger not registered")
+ }
+
+ s.cancel()
+ s.cancel = nil
+ return nil
+}
+
+func wrapReports(reportList []*datastreams.FeedReport, eventID string, timestamp int64, meta datastreams.SignersMetadata) (capabilities.CapabilityResponse, error) {
+ val, err := values.Wrap(reportList)
+ if err != nil {
+ return capabilities.CapabilityResponse{}, err
+ }
+
+ metaVal, err := values.Wrap(meta)
+ if err != nil {
+ return capabilities.CapabilityResponse{}, err
+ }
+
+ triggerEvent := capabilities.TriggerEvent{
+ TriggerType: triggerID,
+ ID: eventID,
+ Timestamp: strconv.FormatInt(timestamp, 10),
+ Metadata: metaVal,
+ Payload: val,
+ }
+
+ triggerEventMapValue, err := values.WrapMap(triggerEvent)
+ if err != nil {
+ return capabilities.CapabilityResponse{}, fmt.Errorf("failed to wrap trigger event: %w", err)
+ }
+
+ // Create a new CapabilityResponse with the MercuryTriggerEvent
+ return capabilities.CapabilityResponse{
+ Value: triggerEventMapValue,
+ }, nil
+}
diff --git a/core/capabilities/integration_tests/setup.go b/core/capabilities/integration_tests/setup.go
new file mode 100644
index 0000000000..6347d55878
--- /dev/null
+++ b/core/capabilities/integration_tests/setup.go
@@ -0,0 +1,439 @@
+package integration_tests
+
+import (
+ "context"
+ "crypto/rand"
+ "encoding/hex"
+ "fmt"
+ "math/big"
+ "strconv"
+ "testing"
+ "time"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/mr-tron/base58"
+ "github.com/stretchr/testify/require"
+ "go.uber.org/zap/zapcore"
+
+ "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil"
+ "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types"
+ ocrTypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
+
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/feeds_consumer"
+ "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight"
+
+ commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3"
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities/datastreams"
+ "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest"
+ coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core"
+ v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3"
+
+ "github.com/smartcontractkit/chainlink/v2/core/capabilities"
+ remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
+ "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
+ "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
+ "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key"
+ p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec"
+)
+
+const (
+ // As a default set the logging to info otherwise 10s/100s of MB of logs are created on each test run
+ TestLogLevel = zapcore.InfoLevel
+)
+
+var (
+ workflowName = "abcdef0123"
+ workflowOwnerID = "0100000000000000000000000000000000000001"
+)
+
+type donInfo struct {
+ commoncap.DON
+ keys []ethkey.KeyV2
+ keyBundles []ocr2key.KeyBundle
+ peerIDs []peer
+}
+
+func setupStreamDonsWithTransmissionSchedule(ctx context.Context, t *testing.T, workflowDonInfo donInfo, triggerDonInfo donInfo, targetDonInfo donInfo,
+ feedCount int, deltaStage string, schedule string) (*feeds_consumer.KeystoneFeedsConsumer, []string, *reportsSink) {
+ lggr := logger.TestLogger(t)
+ lggr.SetLogLevel(TestLogLevel)
+
+ ethBlockchain, transactor := setupBlockchain(t, 1000, 1*time.Second)
+ capabilitiesRegistryAddr := setupCapabilitiesRegistryContract(ctx, t, workflowDonInfo.peerIDs, triggerDonInfo.peerIDs, targetDonInfo.peerIDs, transactor, ethBlockchain)
+ forwarderAddr, _ := setupForwarderContract(t, workflowDonInfo.peerIDs, workflowDonInfo.ID, 1, workflowDonInfo.F, transactor, ethBlockchain)
+ consumerAddr, consumer := setupConsumerContract(t, transactor, ethBlockchain, forwarderAddr, workflowOwnerID, workflowName)
+
+ var feedIDs []string
+ for i := 0; i < feedCount; i++ {
+ feedIDs = append(feedIDs, newFeedID(t))
+ }
+
+ sink := newReportsSink()
+
+ libocr := newMockLibOCR(t, workflowDonInfo.F, 1*time.Second)
+ workflowDonNodes, _, _ := createDons(ctx, t, lggr, sink,
+ workflowDonInfo, triggerDonInfo, targetDonInfo,
+ ethBlockchain, capabilitiesRegistryAddr, forwarderAddr,
+ workflowDonInfo.keyBundles, transactor, libocr)
+ for _, node := range workflowDonNodes {
+ addWorkflowJob(t, node, workflowName, workflowOwnerID, feedIDs, consumerAddr, deltaStage, schedule)
+ }
+
+ servicetest.Run(t, ethBlockchain)
+ servicetest.Run(t, libocr)
+ servicetest.Run(t, sink)
+ return consumer, feedIDs, sink
+}
+
+func createDons(ctx context.Context, t *testing.T, lggr logger.Logger, reportsSink *reportsSink,
+ workflowDon donInfo,
+ triggerDon donInfo,
+ targetDon donInfo,
+ simulatedEthBlockchain *ethBackend,
+ capRegistryAddr common.Address,
+ forwarderAddr common.Address,
+ workflowNodeKeyBundles []ocr2key.KeyBundle,
+ transactor *bind.TransactOpts,
+ libocr *mockLibOCR,
+) ([]*cltest.TestApplication, []*cltest.TestApplication, []*cltest.TestApplication) {
+ broker := newTestAsyncMessageBroker(t, 1000)
+
+ var triggerNodes []*cltest.TestApplication
+ for i, triggerPeer := range triggerDon.Members {
+ triggerPeerDispatcher := broker.NewDispatcherForNode(triggerPeer)
+ nodeInfo := commoncap.Node{
+ PeerID: &triggerPeer,
+ }
+
+ capabilityRegistry := capabilities.NewRegistry(lggr)
+ trigger := reportsSink.getNewTrigger(t)
+ err := capabilityRegistry.Add(ctx, trigger)
+ require.NoError(t, err)
+
+ triggerNode := startNewNode(ctx, t, lggr.Named("Trigger-"+strconv.Itoa(i)), nodeInfo, simulatedEthBlockchain, capRegistryAddr, triggerPeerDispatcher,
+ testPeerWrapper{peer: testPeer{triggerPeer}}, capabilityRegistry, nil, transactor,
+ triggerDon.keys[i])
+
+ require.NoError(t, triggerNode.Start(testutils.Context(t)))
+ triggerNodes = append(triggerNodes, triggerNode)
+ }
+
+ var targetNodes []*cltest.TestApplication
+ for i, targetPeer := range targetDon.Members {
+ targetPeerDispatcher := broker.NewDispatcherForNode(targetPeer)
+ nodeInfo := commoncap.Node{
+ PeerID: &targetPeer,
+ }
+
+ capabilityRegistry := capabilities.NewRegistry(lggr)
+
+ targetNode := startNewNode(ctx, t, lggr.Named("Target-"+strconv.Itoa(i)), nodeInfo, simulatedEthBlockchain, capRegistryAddr, targetPeerDispatcher,
+ testPeerWrapper{peer: testPeer{targetPeer}}, capabilityRegistry, &forwarderAddr, transactor,
+ targetDon.keys[i])
+
+ require.NoError(t, targetNode.Start(testutils.Context(t)))
+ targetNodes = append(triggerNodes, targetNode)
+ }
+
+ var workflowNodes []*cltest.TestApplication
+ for i, workflowPeer := range workflowDon.Members {
+ workflowPeerDispatcher := broker.NewDispatcherForNode(workflowPeer)
+ capabilityRegistry := capabilities.NewRegistry(lggr)
+
+ requestTimeout := 10 * time.Minute
+ cfg := ocr3.Config{
+ Logger: lggr,
+ EncoderFactory: evm.NewEVMEncoder,
+ AggregatorFactory: capabilities.NewAggregator,
+ RequestTimeout: &requestTimeout,
+ }
+
+ ocr3Capability := ocr3.NewOCR3(cfg)
+ servicetest.Run(t, ocr3Capability)
+
+ pluginCfg := coretypes.ReportingPluginServiceConfig{}
+ pluginFactory, err := ocr3Capability.NewReportingPluginFactory(ctx, pluginCfg, nil,
+ nil, nil, nil, capabilityRegistry, nil, nil)
+ require.NoError(t, err)
+
+ repConfig := ocr3types.ReportingPluginConfig{
+ F: int(workflowDon.F),
+ }
+ plugin, _, err := pluginFactory.NewReportingPlugin(repConfig)
+ require.NoError(t, err)
+
+ transmitter := ocr3.NewContractTransmitter(lggr, capabilityRegistry, "")
+
+ libocr.AddNode(plugin, transmitter, workflowNodeKeyBundles[i])
+
+ nodeInfo := commoncap.Node{
+ PeerID: &workflowPeer,
+ WorkflowDON: workflowDon.DON,
+ CapabilityDONs: []commoncap.DON{triggerDon.DON, targetDon.DON},
+ }
+
+ workflowNode := startNewNode(ctx, t, lggr.Named("Workflow-"+strconv.Itoa(i)), nodeInfo, simulatedEthBlockchain, capRegistryAddr, workflowPeerDispatcher,
+ testPeerWrapper{peer: testPeer{workflowPeer}}, capabilityRegistry, nil, transactor,
+ workflowDon.keys[i])
+
+ require.NoError(t, workflowNode.Start(testutils.Context(t)))
+ workflowNodes = append(workflowNodes, workflowNode)
+ }
+
+ servicetest.Run(t, broker)
+
+ return workflowNodes, triggerNodes, targetNodes
+}
+
+func startNewNode(ctx context.Context,
+ t *testing.T, lggr logger.Logger, nodeInfo commoncap.Node,
+ backend *ethBackend, capRegistryAddr common.Address,
+ dispatcher remotetypes.Dispatcher,
+ peerWrapper p2ptypes.PeerWrapper,
+ localCapabilities *capabilities.Registry,
+ forwarderAddress *common.Address,
+ transactor *bind.TransactOpts,
+ keyV2 ethkey.KeyV2,
+) *cltest.TestApplication {
+ config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
+ c.Capabilities.ExternalRegistry.ChainID = ptr(fmt.Sprintf("%d", testutils.SimulatedChainID))
+ c.Capabilities.ExternalRegistry.Address = ptr(capRegistryAddr.String())
+ c.Capabilities.Peering.V2.Enabled = ptr(true)
+
+ if forwarderAddress != nil {
+ eip55Address := types.EIP55AddressFromAddress(*forwarderAddress)
+ c.EVM[0].Chain.Workflow.ForwarderAddress = &eip55Address
+ c.EVM[0].Chain.Workflow.FromAddress = &keyV2.EIP55Address
+ }
+
+ c.Feature.FeedsManager = ptr(false)
+ })
+
+ n, err := backend.NonceAt(ctx, transactor.From, nil)
+ require.NoError(t, err)
+
+ tx := cltest.NewLegacyTransaction(
+ n, keyV2.Address,
+ assets.Ether(1).ToInt(),
+ 21000,
+ assets.GWei(1).ToInt(),
+ nil)
+ signedTx, err := transactor.Signer(transactor.From, tx)
+ require.NoError(t, err)
+ err = backend.SendTransaction(ctx, signedTx)
+ require.NoError(t, err)
+ backend.Commit()
+
+ return cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, backend.SimulatedBackend, nodeInfo,
+ dispatcher, peerWrapper, localCapabilities, keyV2, lggr)
+}
+
+type don struct {
+ id uint32
+ numNodes int
+ f uint8
+}
+
+func createDonInfo(t *testing.T, don don) donInfo {
+ keyBundles, peerIDs := getKeyBundlesAndPeerIDs(t, don.numNodes)
+
+ donPeers := make([]p2ptypes.PeerID, len(peerIDs))
+ var donKeys []ethkey.KeyV2
+ for i := 0; i < len(peerIDs); i++ {
+ peerID := p2ptypes.PeerID{}
+ require.NoError(t, peerID.UnmarshalText([]byte(peerIDs[i].PeerID)))
+ donPeers[i] = peerID
+ newKey, err := ethkey.NewV2()
+ require.NoError(t, err)
+ donKeys = append(donKeys, newKey)
+ }
+
+ triggerDonInfo := donInfo{
+ DON: commoncap.DON{
+ ID: don.id,
+ Members: donPeers,
+ F: don.f,
+ },
+ peerIDs: peerIDs,
+ keys: donKeys,
+ keyBundles: keyBundles,
+ }
+ return triggerDonInfo
+}
+
+func createFeedReport(t *testing.T, price *big.Int, observationTimestamp int64,
+ feedIDString string,
+ keyBundles []ocr2key.KeyBundle) *datastreams.FeedReport {
+ reportCtx := ocrTypes.ReportContext{}
+ rawCtx := RawReportContext(reportCtx)
+
+ bytes, err := hex.DecodeString(feedIDString[2:])
+ require.NoError(t, err)
+ var feedIDBytes [32]byte
+ copy(feedIDBytes[:], bytes)
+
+ report := &datastreams.FeedReport{
+ FeedID: feedIDString,
+ FullReport: newReport(t, feedIDBytes, price, observationTimestamp),
+ BenchmarkPrice: price.Bytes(),
+ ObservationTimestamp: observationTimestamp,
+ Signatures: [][]byte{},
+ ReportContext: rawCtx,
+ }
+
+ for _, key := range keyBundles {
+ sig, err := key.Sign(reportCtx, report.FullReport)
+ require.NoError(t, err)
+ report.Signatures = append(report.Signatures, sig)
+ }
+
+ return report
+}
+
+func getKeyBundlesAndPeerIDs(t *testing.T, numNodes int) ([]ocr2key.KeyBundle, []peer) {
+ var keyBundles []ocr2key.KeyBundle
+ var donPeerIDs []peer
+ for i := 0; i < numNodes; i++ {
+ peerID := NewPeerID()
+
+ keyBundle, err := ocr2key.New(chaintype.EVM)
+ require.NoError(t, err)
+ keyBundles = append(keyBundles, keyBundle)
+
+ pk := keyBundle.PublicKey()
+
+ p := peer{
+ PeerID: peerID,
+ Signer: fmt.Sprintf("0x%x", pk),
+ }
+
+ donPeerIDs = append(donPeerIDs, p)
+ }
+ return keyBundles, donPeerIDs
+}
+
+func newFeedID(t *testing.T) string {
+ buf := [32]byte{}
+ _, err := rand.Read(buf[:])
+ require.NoError(t, err)
+ return "0x" + hex.EncodeToString(buf[:])
+}
+
+func newReport(t *testing.T, feedID [32]byte, price *big.Int, timestamp int64) []byte {
+ v3Codec := reportcodec.NewReportCodec(feedID, logger.TestLogger(t))
+ raw, err := v3Codec.BuildReport(v3.ReportFields{
+ BenchmarkPrice: price,
+ Timestamp: uint32(timestamp),
+ Bid: big.NewInt(0),
+ Ask: big.NewInt(0),
+ LinkFee: big.NewInt(0),
+ NativeFee: big.NewInt(0),
+ })
+ require.NoError(t, err)
+ return raw
+}
+
+type testPeerWrapper struct {
+ peer testPeer
+}
+
+func (t testPeerWrapper) Start(ctx context.Context) error {
+ return nil
+}
+
+func (t testPeerWrapper) Close() error {
+ return nil
+}
+
+func (t testPeerWrapper) Ready() error {
+ return nil
+}
+
+func (t testPeerWrapper) HealthReport() map[string]error {
+ return nil
+}
+
+func (t testPeerWrapper) Name() string {
+ return "testPeerWrapper"
+}
+
+func (t testPeerWrapper) GetPeer() p2ptypes.Peer {
+ return t.peer
+}
+
+type testPeer struct {
+ id p2ptypes.PeerID
+}
+
+func (t testPeer) Start(ctx context.Context) error {
+ return nil
+}
+
+func (t testPeer) Close() error {
+ return nil
+}
+
+func (t testPeer) Ready() error {
+ return nil
+}
+
+func (t testPeer) HealthReport() map[string]error {
+ return nil
+}
+
+func (t testPeer) Name() string {
+ return "testPeer"
+}
+
+func (t testPeer) ID() p2ptypes.PeerID {
+ return t.id
+}
+
+func (t testPeer) UpdateConnections(peers map[p2ptypes.PeerID]p2ptypes.StreamConfig) error {
+ return nil
+}
+
+func (t testPeer) Send(peerID p2ptypes.PeerID, msg []byte) error {
+ return nil
+}
+
+func (t testPeer) Receive() <-chan p2ptypes.Message {
+ return nil
+}
+
+func NewPeerID() string {
+ var privKey [32]byte
+ _, err := rand.Read(privKey[:])
+ if err != nil {
+ panic(err)
+ }
+
+ peerID := append(libp2pMagic(), privKey[:]...)
+
+ return base58.Encode(peerID[:])
+}
+
+func libp2pMagic() []byte {
+ return []byte{0x00, 0x24, 0x08, 0x01, 0x12, 0x20}
+}
+
+func ptr[T any](t T) *T { return &t }
+
+func RawReportContext(reportCtx ocrTypes.ReportContext) []byte {
+ rc := evmutil.RawReportContext(reportCtx)
+ flat := []byte{}
+ for _, r := range rc {
+ flat = append(flat, r[:]...)
+ }
+ return flat
+}
diff --git a/core/capabilities/integration_tests/streams_test.go b/core/capabilities/integration_tests/streams_test.go
new file mode 100644
index 0000000000..6216e36c85
--- /dev/null
+++ b/core/capabilities/integration_tests/streams_test.go
@@ -0,0 +1,99 @@
+package integration_tests
+
+import (
+ "context"
+ "encoding/hex"
+ "math/big"
+ "testing"
+ "time"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities/datastreams"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/feeds_consumer"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+ reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/types"
+)
+
+func Test_AllAtOnceTransmissionSchedule(t *testing.T) {
+ ctx := testutils.Context(t)
+
+ // The don IDs set in the below calls are inferred from the order in which the dons are added to the capabilities registry
+ // in the setupCapabilitiesRegistryContract function, should this order change the don IDs will need updating.
+ workflowDonInfo := createDonInfo(t, don{id: 1, numNodes: 5, f: 1})
+ triggerDonInfo := createDonInfo(t, don{id: 2, numNodes: 7, f: 1})
+ targetDonInfo := createDonInfo(t, don{id: 3, numNodes: 4, f: 1})
+
+ consumer, feedIDs, triggerSink := setupStreamDonsWithTransmissionSchedule(ctx, t, workflowDonInfo, triggerDonInfo, targetDonInfo, 3,
+ "2s", "allAtOnce")
+
+ reports := []*datastreams.FeedReport{
+ createFeedReport(t, big.NewInt(1), 5, feedIDs[0], triggerDonInfo.keyBundles),
+ createFeedReport(t, big.NewInt(3), 7, feedIDs[1], triggerDonInfo.keyBundles),
+ createFeedReport(t, big.NewInt(2), 6, feedIDs[2], triggerDonInfo.keyBundles),
+ }
+
+ triggerSink.sendReports(reports)
+
+ waitForConsumerReports(ctx, t, consumer, reports)
+}
+
+func Test_OneAtATimeTransmissionSchedule(t *testing.T) {
+ ctx := testutils.Context(t)
+
+ // The don IDs set in the below calls are inferred from the order in which the dons are added to the capabilities registry
+ // in the setupCapabilitiesRegistryContract function, should this order change the don IDs will need updating.
+ workflowDonInfo := createDonInfo(t, don{id: 1, numNodes: 5, f: 1})
+ triggerDonInfo := createDonInfo(t, don{id: 2, numNodes: 7, f: 1})
+ targetDonInfo := createDonInfo(t, don{id: 3, numNodes: 4, f: 1})
+
+ consumer, feedIDs, triggerSink := setupStreamDonsWithTransmissionSchedule(ctx, t, workflowDonInfo, triggerDonInfo, targetDonInfo, 3,
+ "2s", "oneAtATime")
+
+ reports := []*datastreams.FeedReport{
+ createFeedReport(t, big.NewInt(1), 5, feedIDs[0], triggerDonInfo.keyBundles),
+ createFeedReport(t, big.NewInt(3), 7, feedIDs[1], triggerDonInfo.keyBundles),
+ createFeedReport(t, big.NewInt(2), 6, feedIDs[2], triggerDonInfo.keyBundles),
+ }
+
+ triggerSink.sendReports(reports)
+
+ waitForConsumerReports(ctx, t, consumer, reports)
+}
+
+func waitForConsumerReports(ctx context.Context, t *testing.T, consumer *feeds_consumer.KeystoneFeedsConsumer, triggerFeedReports []*datastreams.FeedReport) {
+ feedsReceived := make(chan *feeds_consumer.KeystoneFeedsConsumerFeedReceived, 1000)
+ feedsSub, err := consumer.WatchFeedReceived(&bind.WatchOpts{}, feedsReceived, nil)
+ require.NoError(t, err)
+
+ feedToReport := map[string]*datastreams.FeedReport{}
+ for _, report := range triggerFeedReports {
+ feedToReport[report.FeedID] = report
+ }
+
+ ctxWithTimeout, cancel := context.WithTimeout(ctx, 5*time.Minute)
+ defer cancel()
+ feedCount := 0
+ for {
+ select {
+ case <-ctxWithTimeout.Done():
+ t.Fatalf("timed out waiting for feed reports, expected %d, received %d", len(triggerFeedReports), feedCount)
+ case err := <-feedsSub.Err():
+ require.NoError(t, err)
+ case feed := <-feedsReceived:
+ feedID := "0x" + hex.EncodeToString(feed.FeedId[:])
+ report := feedToReport[feedID]
+ decodedReport, err := reporttypes.Decode(report.FullReport)
+ require.NoError(t, err)
+ assert.Equal(t, decodedReport.BenchmarkPrice, feed.Price)
+ assert.Equal(t, decodedReport.ObservationsTimestamp, feed.Timestamp)
+
+ feedCount++
+ if feedCount == len(triggerFeedReports) {
+ return
+ }
+ }
+ }
+}
diff --git a/core/capabilities/integration_tests/workflow.go b/core/capabilities/integration_tests/workflow.go
new file mode 100644
index 0000000000..d116a1ec63
--- /dev/null
+++ b/core/capabilities/integration_tests/workflow.go
@@ -0,0 +1,75 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+ "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs"
+)
+
+const hardcodedWorkflow = `
+name: "%s"
+owner: "0x%s"
+triggers:
+ - id: "streams-trigger@1.0.0"
+ config:
+ feedIds:
+%s
+
+consensus:
+ - id: "offchain_reporting@1.0.0"
+ ref: "evm_median"
+ inputs:
+ observations:
+ - "$(trigger.outputs)"
+ config:
+ report_id: "0001"
+ aggregation_method: "data_feeds"
+ aggregation_config:
+ feeds:
+%s
+ encoder: "EVM"
+ encoder_config:
+ abi: "(bytes32 FeedID, uint224 Price, uint32 Timestamp)[] Reports"
+
+targets:
+ - id: "write_geth-testnet@1.0.0"
+ inputs:
+ signed_report: "$(evm_median.outputs)"
+ config:
+ address: "%s"
+ params: ["$(report)"]
+ abi: "receive(report bytes)"
+ deltaStage: %s
+ schedule: %s
+`
+
+func addWorkflowJob(t *testing.T, app *cltest.TestApplication,
+ workflowName string,
+ workflowOwner string,
+ feedIDs []string,
+ consumerAddr common.Address,
+ deltaStage string,
+ schedule string) {
+ triggerFeedIDs := ""
+ for _, feedID := range feedIDs {
+ triggerFeedIDs += fmt.Sprintf(" - \"%s\"\n", feedID)
+ }
+
+ aggregationFeeds := ""
+ for _, feedID := range feedIDs {
+ aggregationFeeds += fmt.Sprintf(" \"%s\":\n deviation: \"0.001\"\n heartbeat: 3600\n", feedID)
+ }
+
+ workflowJobSpec := testspecs.GenerateWorkflowJobSpec(t, fmt.Sprintf(hardcodedWorkflow, workflowName, workflowOwner, triggerFeedIDs, aggregationFeeds,
+ consumerAddr.String(), deltaStage, schedule))
+ job := workflowJobSpec.Job()
+
+ err := app.AddJobV2(testutils.Context(t), &job)
+ require.NoError(t, err)
+}
diff --git a/core/capabilities/launcher.go b/core/capabilities/launcher.go
index 267e32055e..b4ade04127 100644
--- a/core/capabilities/launcher.go
+++ b/core/capabilities/launcher.go
@@ -7,12 +7,9 @@ import (
"strings"
"time"
- "google.golang.org/protobuf/proto"
-
"github.com/smartcontractkit/chainlink-common/pkg/capabilities"
"github.com/smartcontractkit/chainlink-common/pkg/capabilities/triggers"
"github.com/smartcontractkit/chainlink-common/pkg/services"
- "github.com/smartcontractkit/chainlink-common/pkg/types/core"
"github.com/smartcontractkit/libocr/ragep2p"
ragetypes "github.com/smartcontractkit/libocr/ragep2p/types"
@@ -21,7 +18,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/target"
remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/streams"
- kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
"github.com/smartcontractkit/chainlink/v2/core/logger"
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
"github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer"
@@ -46,8 +42,7 @@ type launcher struct {
lggr logger.Logger
peerWrapper p2ptypes.PeerWrapper
dispatcher remotetypes.Dispatcher
- registry core.CapabilitiesRegistry
- localNode capabilities.Node
+ registry *Registry
subServices []services.Service
}
@@ -55,7 +50,7 @@ func NewLauncher(
lggr logger.Logger,
peerWrapper p2ptypes.PeerWrapper,
dispatcher remotetypes.Dispatcher,
- registry core.CapabilitiesRegistry,
+ registry *Registry,
) *launcher {
return &launcher{
lggr: lggr.Named("CapabilitiesLauncher"),
@@ -92,50 +87,8 @@ func (w *launcher) Name() string {
return "CapabilitiesLauncher"
}
-func (w *launcher) LocalNode(ctx context.Context) (capabilities.Node, error) {
- if w.peerWrapper.GetPeer() == nil {
- return w.localNode, errors.New("unable to get local node: peerWrapper hasn't started yet")
- }
-
- if w.localNode.WorkflowDON.ID == 0 {
- return w.localNode, errors.New("unable to get local node: waiting for initial call from syncer")
- }
-
- return w.localNode, nil
-}
-
-func (w *launcher) updateLocalNode(state registrysyncer.State) {
- pid := w.peerWrapper.GetPeer().ID()
-
- var workflowDON capabilities.DON
- capabilityDONs := []capabilities.DON{}
- for _, d := range state.IDsToDONs {
- for _, p := range d.NodeP2PIds {
- if p == pid {
- if d.AcceptsWorkflows {
- if workflowDON.ID == 0 {
- workflowDON = *toDONInfo(d)
- w.lggr.Debug("Workflow DON identified: %+v", workflowDON)
- } else {
- w.lggr.Errorf("Configuration error: node %s belongs to more than one workflowDON", pid)
- }
- }
-
- capabilityDONs = append(capabilityDONs, *toDONInfo(d))
- }
- }
- }
-
- w.localNode = capabilities.Node{
- PeerID: &pid,
- WorkflowDON: workflowDON,
- CapabilityDONs: capabilityDONs,
- }
-}
-
-func (w *launcher) Launch(ctx context.Context, state registrysyncer.State) error {
- w.lggr.Debugw("running capabilities launcher", "state", state)
- w.updateLocalNode(state)
+func (w *launcher) Launch(ctx context.Context, state *registrysyncer.LocalRegistry) error {
+ w.registry.SetLocalRegistry(state)
// Let's start by updating the list of Peers
// We do this by creating a new entry for each node belonging
@@ -143,15 +96,15 @@ func (w *launcher) Launch(ctx context.Context, state registrysyncer.State) error
// We also add the hardcoded peers determined by the NetworkSetup.
allPeers := make(map[ragetypes.PeerID]p2ptypes.StreamConfig)
- publicDONs := []kcr.CapabilitiesRegistryDONInfo{}
+ publicDONs := []registrysyncer.DON{}
for _, d := range state.IDsToDONs {
- if !d.IsPublic {
+ if !d.DON.IsPublic {
continue
}
publicDONs = append(publicDONs, d)
- for _, nid := range d.NodeP2PIds {
+ for _, nid := range d.DON.Members {
allPeers[nid] = defaultStreamConfig
}
}
@@ -171,18 +124,18 @@ func (w *launcher) Launch(ctx context.Context, state registrysyncer.State) error
// We'll also construct a set to record what DONs the current node is a part of,
// regardless of any modifiers (public/acceptsWorkflows etc).
myID := w.peerWrapper.GetPeer().ID()
- myWorkflowDONs := []kcr.CapabilitiesRegistryDONInfo{}
- remoteWorkflowDONs := []kcr.CapabilitiesRegistryDONInfo{}
+ myWorkflowDONs := []registrysyncer.DON{}
+ remoteWorkflowDONs := []registrysyncer.DON{}
myDONs := map[uint32]bool{}
for _, d := range state.IDsToDONs {
- for _, peerID := range d.NodeP2PIds {
+ for _, peerID := range d.Members {
if peerID == myID {
- myDONs[d.Id] = true
+ myDONs[d.ID] = true
}
}
if d.AcceptsWorkflows {
- if myDONs[d.Id] {
+ if myDONs[d.ID] {
myWorkflowDONs = append(myWorkflowDONs, d)
} else {
remoteWorkflowDONs = append(remoteWorkflowDONs, d)
@@ -192,11 +145,11 @@ func (w *launcher) Launch(ctx context.Context, state registrysyncer.State) error
// - remote capability DONs (with IsPublic = true) the current node is a part of.
// These need server-side shims.
- myCapabilityDONs := []kcr.CapabilitiesRegistryDONInfo{}
- remoteCapabilityDONs := []kcr.CapabilitiesRegistryDONInfo{}
+ myCapabilityDONs := []registrysyncer.DON{}
+ remoteCapabilityDONs := []registrysyncer.DON{}
for _, d := range publicDONs {
if len(d.CapabilityConfigurations) > 0 {
- if myDONs[d.Id] {
+ if myDONs[d.ID] {
myCapabilityDONs = append(myCapabilityDONs, d)
} else {
remoteCapabilityDONs = append(remoteCapabilityDONs, d)
@@ -236,14 +189,14 @@ func (w *launcher) Launch(ctx context.Context, state registrysyncer.State) error
return nil
}
-func (w *launcher) addRemoteCapabilities(ctx context.Context, myDON kcr.CapabilitiesRegistryDONInfo, remoteDON kcr.CapabilitiesRegistryDONInfo, state registrysyncer.State) error {
- for _, c := range remoteDON.CapabilityConfigurations {
- capability, ok := state.IDsToCapabilities[c.CapabilityId]
+func (w *launcher) addRemoteCapabilities(ctx context.Context, myDON registrysyncer.DON, remoteDON registrysyncer.DON, state *registrysyncer.LocalRegistry) error {
+ for cid, c := range remoteDON.CapabilityConfigurations {
+ capability, ok := state.IDsToCapabilities[cid]
if !ok {
- return fmt.Errorf("could not find capability matching id %s", c.CapabilityId)
+ return fmt.Errorf("could not find capability matching id %s", cid)
}
- switch toCapabilityType(capability.CapabilityType) {
+ switch capability.CapabilityType {
case capabilities.CapabilityTypeTrigger:
newTriggerFn := func(info capabilities.CapabilityInfo) (capabilityService, error) {
if !strings.HasPrefix(info.ID, "streams-trigger") {
@@ -263,12 +216,6 @@ func (w *launcher) addRemoteCapabilities(ctx context.Context, myDON kcr.Capabili
int(remoteDON.F+1),
w.lggr,
)
- cfg := &remotetypes.RemoteTriggerConfig{}
- cfg.ApplyDefaults()
- err = proto.Unmarshal(c.Config, cfg)
- if err != nil {
- return nil, err
- }
// TODO: We need to implement a custom, Mercury-specific
// aggregator here, because there is no guarantee that
// all trigger events in the workflow will have the same
@@ -276,10 +223,10 @@ func (w *launcher) addRemoteCapabilities(ctx context.Context, myDON kcr.Capabili
// When this is solved, we can move to a generic aggregator
// and remove this.
triggerCap := remote.NewTriggerSubscriber(
- cfg,
+ c.RemoteTriggerConfig,
info,
- *toDONInfo(remoteDON),
- *toDONInfo(myDON),
+ remoteDON.DON,
+ myDON.DON,
w.dispatcher,
aggregator,
w.lggr,
@@ -298,7 +245,7 @@ func (w *launcher) addRemoteCapabilities(ctx context.Context, myDON kcr.Capabili
newTargetFn := func(info capabilities.CapabilityInfo) (capabilityService, error) {
client := target.NewClient(
info,
- *toDONInfo(myDON),
+ myDON.DON,
w.dispatcher,
defaultTargetRequestTimeout,
w.lggr,
@@ -323,24 +270,24 @@ type capabilityService interface {
services.Service
}
-func (w *launcher) addToRegistryAndSetDispatcher(ctx context.Context, capabilityInfo kcr.CapabilitiesRegistryCapabilityInfo, don kcr.CapabilitiesRegistryDONInfo, newCapFn func(info capabilities.CapabilityInfo) (capabilityService, error)) error {
- fullCapID := fmt.Sprintf("%s@%s", capabilityInfo.LabelledName, capabilityInfo.Version)
+func (w *launcher) addToRegistryAndSetDispatcher(ctx context.Context, capability registrysyncer.Capability, don registrysyncer.DON, newCapFn func(info capabilities.CapabilityInfo) (capabilityService, error)) error {
+ capabilityID := capability.ID
info, err := capabilities.NewRemoteCapabilityInfo(
- fullCapID,
- toCapabilityType(capabilityInfo.CapabilityType),
- fmt.Sprintf("Remote Capability for %s", fullCapID),
- toDONInfo(don),
+ capabilityID,
+ capability.CapabilityType,
+ fmt.Sprintf("Remote Capability for %s", capabilityID),
+ &don.DON,
)
if err != nil {
return fmt.Errorf("failed to create remote capability info: %w", err)
}
w.lggr.Debugw("Adding remote capability to registry", "id", info.ID, "don", info.DON)
- capability, err := newCapFn(info)
+ cp, err := newCapFn(info)
if err != nil {
return fmt.Errorf("failed to instantiate capability: %w", err)
}
- err = w.registry.Add(ctx, capability)
+ err = w.registry.Add(ctx, cp)
if err != nil {
// If the capability already exists, then it's either local
// or we've handled this in a previous syncer iteration,
@@ -353,19 +300,19 @@ func (w *launcher) addToRegistryAndSetDispatcher(ctx context.Context, capability
}
err = w.dispatcher.SetReceiver(
- fullCapID,
- don.Id,
- capability,
+ capabilityID,
+ don.ID,
+ cp,
)
if err != nil {
return err
}
- w.lggr.Debugw("Setting receiver for capability", "id", fullCapID, "donID", don.Id)
- err = capability.Start(ctx)
+ w.lggr.Debugw("Setting receiver for capability", "id", capabilityID, "donID", don.ID)
+ err = cp.Start(ctx)
if err != nil {
return fmt.Errorf("failed to start capability: %w", err)
}
- w.subServices = append(w.subServices, capability)
+ w.subServices = append(w.subServices, cp)
return nil
}
@@ -373,32 +320,26 @@ var (
defaultTargetRequestTimeout = time.Minute
)
-func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.PeerID, don kcr.CapabilitiesRegistryDONInfo, state registrysyncer.State, remoteWorkflowDONs []kcr.CapabilitiesRegistryDONInfo) error {
+func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.PeerID, don registrysyncer.DON, state *registrysyncer.LocalRegistry, remoteWorkflowDONs []registrysyncer.DON) error {
idsToDONs := map[uint32]capabilities.DON{}
for _, d := range remoteWorkflowDONs {
- idsToDONs[d.Id] = *toDONInfo(d)
+ idsToDONs[d.ID] = d.DON
}
- for _, c := range don.CapabilityConfigurations {
- capability, ok := state.IDsToCapabilities[c.CapabilityId]
+ for cid, c := range don.CapabilityConfigurations {
+ capability, ok := state.IDsToCapabilities[cid]
if !ok {
- return fmt.Errorf("could not find capability matching id %s", c.CapabilityId)
+ return fmt.Errorf("could not find capability matching id %s", cid)
}
- switch toCapabilityType(capability.CapabilityType) {
+ switch capability.CapabilityType {
case capabilities.CapabilityTypeTrigger:
newTriggerPublisher := func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (receiverService, error) {
- cfg := &remotetypes.RemoteTriggerConfig{}
- cfg.ApplyDefaults()
- err := proto.Unmarshal(c.Config, cfg)
- if err != nil {
- return nil, err
- }
publisher := remote.NewTriggerPublisher(
- cfg,
+ c.RemoteTriggerConfig,
capability.(capabilities.TriggerCapability),
info,
- *toDONInfo(don),
+ don.DON,
idsToDONs,
w.dispatcher,
w.lggr,
@@ -420,7 +361,7 @@ func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.Pee
myPeerID,
capability.(capabilities.TargetCapability),
info,
- *toDONInfo(don),
+ don.DON,
idsToDONs,
w.dispatcher,
defaultTargetRequestTimeout,
@@ -444,18 +385,18 @@ type receiverService interface {
remotetypes.Receiver
}
-func (w *launcher) addReceiver(ctx context.Context, capability kcr.CapabilitiesRegistryCapabilityInfo, don kcr.CapabilitiesRegistryDONInfo, newReceiverFn func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (receiverService, error)) error {
- fullCapID := fmt.Sprintf("%s@%s", capability.LabelledName, capability.Version)
+func (w *launcher) addReceiver(ctx context.Context, capability registrysyncer.Capability, don registrysyncer.DON, newReceiverFn func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (receiverService, error)) error {
+ capID := capability.ID
info, err := capabilities.NewRemoteCapabilityInfo(
- fullCapID,
- toCapabilityType(capability.CapabilityType),
- fmt.Sprintf("Remote Capability for %s", fullCapID),
- toDONInfo(don),
+ capID,
+ capability.CapabilityType,
+ fmt.Sprintf("Remote Capability for %s", capability.ID),
+ &don.DON,
)
if err != nil {
return fmt.Errorf("failed to instantiate remote capability for receiver: %w", err)
}
- underlying, err := w.registry.Get(ctx, fullCapID)
+ underlying, err := w.registry.Get(ctx, capability.ID)
if err != nil {
return fmt.Errorf("failed to get capability from registry: %w", err)
}
@@ -465,12 +406,12 @@ func (w *launcher) addReceiver(ctx context.Context, capability kcr.CapabilitiesR
return fmt.Errorf("failed to instantiate receiver: %w", err)
}
- w.lggr.Debugw("Enabling external access for capability", "id", fullCapID, "donID", don.Id)
- err = w.dispatcher.SetReceiver(fullCapID, don.Id, receiver)
+ w.lggr.Debugw("Enabling external access for capability", "id", capID, "donID", don.ID)
+ err = w.dispatcher.SetReceiver(capID, don.ID, receiver)
if errors.Is(err, remote.ErrReceiverExists) {
// If a receiver already exists, let's log the error for debug purposes, but
// otherwise short-circuit here. We've handled this capability in a previous iteration.
- w.lggr.Debugf("receiver already exists for cap ID %s and don ID %d: %s", fullCapID, don.Id, err)
+ w.lggr.Debugf("receiver already exists for cap ID %s and don ID %d: %s", capID, don.ID, err)
return nil
} else if err != nil {
return fmt.Errorf("failed to set receiver: %w", err)
@@ -485,9 +426,9 @@ func (w *launcher) addReceiver(ctx context.Context, capability kcr.CapabilitiesR
return nil
}
-func signersFor(don kcr.CapabilitiesRegistryDONInfo, state registrysyncer.State) ([][]byte, error) {
+func signersFor(don registrysyncer.DON, state *registrysyncer.LocalRegistry) ([][]byte, error) {
s := [][]byte{}
- for _, nodeID := range don.NodeP2PIds {
+ for _, nodeID := range don.Members {
node, ok := state.IDsToNodes[nodeID]
if !ok {
return nil, fmt.Errorf("could not find node for id %s", nodeID)
@@ -500,33 +441,3 @@ func signersFor(don kcr.CapabilitiesRegistryDONInfo, state registrysyncer.State)
return s, nil
}
-
-func toDONInfo(don kcr.CapabilitiesRegistryDONInfo) *capabilities.DON {
- peerIDs := []p2ptypes.PeerID{}
- for _, p := range don.NodeP2PIds {
- peerIDs = append(peerIDs, p)
- }
-
- return &capabilities.DON{
- ID: don.Id,
- ConfigVersion: don.ConfigCount,
- Members: peerIDs,
- F: don.F,
- }
-}
-
-func toCapabilityType(capabilityType uint8) capabilities.CapabilityType {
- switch capabilityType {
- case 0:
- return capabilities.CapabilityTypeTrigger
- case 1:
- return capabilities.CapabilityTypeAction
- case 2:
- return capabilities.CapabilityTypeConsensus
- case 3:
- return capabilities.CapabilityTypeTarget
- default:
- // Not found
- return capabilities.CapabilityType(-1)
- }
-}
diff --git a/core/capabilities/launcher_test.go b/core/capabilities/launcher_test.go
index d314be6069..fb3e6837d0 100644
--- a/core/capabilities/launcher_test.go
+++ b/core/capabilities/launcher_test.go
@@ -78,7 +78,7 @@ func TestLauncher_WiresUpExternalCapabilities(t *testing.T) {
wrapper := mocks.NewPeerWrapper(t)
wrapper.On("GetPeer").Return(peer)
- nodes := [][32]byte{
+ nodes := []ragetypes.PeerID{
pid,
randomWord(),
randomWord(),
@@ -110,37 +110,31 @@ func TestLauncher_WiresUpExternalCapabilities(t *testing.T) {
// which exposes the streams-trigger and write_chain capabilities.
// We expect a publisher to be wired up with this configuration, and
// no entries should be added to the registry.
- state := registrysyncer.State{
- IDsToDONs: map[registrysyncer.DonID]kcr.CapabilitiesRegistryDONInfo{
+ state := ®istrysyncer.LocalRegistry{
+ IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{
registrysyncer.DonID(dID): {
- Id: dID,
- ConfigCount: uint32(0),
- F: uint8(1),
- IsPublic: true,
- AcceptsWorkflows: true,
- NodeP2PIds: nodes,
- CapabilityConfigurations: []kcr.CapabilitiesRegistryCapabilityConfiguration{
- {
- CapabilityId: triggerCapID,
- Config: []byte(""),
- },
- {
- CapabilityId: targetCapID,
- Config: []byte(""),
- },
+ DON: capabilities.DON{
+ ID: dID,
+ ConfigVersion: uint32(0),
+ F: uint8(1),
+ IsPublic: true,
+ AcceptsWorkflows: true,
+ Members: nodes,
+ },
+ CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{
+ fullTriggerCapID: {},
+ fullTargetID: {},
},
},
},
- IDsToCapabilities: map[registrysyncer.HashedCapabilityID]kcr.CapabilitiesRegistryCapabilityInfo{
- triggerCapID: {
- LabelledName: "streams-trigger",
- Version: "1.0.0",
- CapabilityType: 0,
+ IDsToCapabilities: map[string]registrysyncer.Capability{
+ fullTriggerCapID: {
+ ID: "streams-trigger@1.0.0",
+ CapabilityType: capabilities.CapabilityTypeTrigger,
},
- targetCapID: {
- LabelledName: "write-chain_evm_1",
- Version: "1.0.0",
- CapabilityType: 3,
+ fullTargetID: {
+ ID: "write-chain_evm_1@1.0.0",
+ CapabilityType: capabilities.CapabilityTypeTarget,
},
},
IDsToNodes: map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo{
@@ -201,51 +195,48 @@ func TestSyncer_IgnoresCapabilitiesForPrivateDON(t *testing.T) {
wrapper := mocks.NewPeerWrapper(t)
wrapper.On("GetPeer").Return(peer)
- nodes := [][32]byte{
+ nodes := []ragetypes.PeerID{
pid,
randomWord(),
randomWord(),
randomWord(),
}
- triggerCapID := randomWord()
- targetCapID := randomWord()
dID := uint32(1)
+ triggerID := "streams-trigger@1.0.0"
+ hashedTriggerID := randomWord()
+ targetID := "write-chain_evm_1@1.0.0"
+ hashedTargetID := randomWord()
+
// The below state describes a Workflow DON (AcceptsWorkflows = true),
// which isn't public (IsPublic = false), but hosts the
// the streams-trigger and write_chain capabilities.
// We expect no action to be taken by the syncer.
- state := registrysyncer.State{
- IDsToDONs: map[registrysyncer.DonID]kcr.CapabilitiesRegistryDONInfo{
+ state := ®istrysyncer.LocalRegistry{
+ IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{
registrysyncer.DonID(dID): {
- Id: dID,
- ConfigCount: uint32(0),
- F: uint8(1),
- IsPublic: false,
- AcceptsWorkflows: true,
- NodeP2PIds: nodes,
- CapabilityConfigurations: []kcr.CapabilitiesRegistryCapabilityConfiguration{
- {
- CapabilityId: triggerCapID,
- Config: []byte(""),
- },
- {
- CapabilityId: targetCapID,
- Config: []byte(""),
- },
+ DON: capabilities.DON{
+ ID: dID,
+ ConfigVersion: uint32(0),
+ F: uint8(1),
+ IsPublic: false,
+ AcceptsWorkflows: true,
+ Members: nodes,
+ },
+ CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{
+ triggerID: {},
+ targetID: {},
},
},
},
- IDsToCapabilities: map[registrysyncer.HashedCapabilityID]kcr.CapabilitiesRegistryCapabilityInfo{
- triggerCapID: {
- LabelledName: "streams-trigger",
- Version: "1.0.0",
- CapabilityType: 0,
+ IDsToCapabilities: map[string]registrysyncer.Capability{
+ triggerID: {
+ ID: triggerID,
+ CapabilityType: capabilities.CapabilityTypeTrigger,
},
- targetCapID: {
- LabelledName: "write-chain_evm_1",
- Version: "1.0.0",
- CapabilityType: 3,
+ targetID: {
+ ID: targetID,
+ CapabilityType: capabilities.CapabilityTypeTarget,
},
},
IDsToNodes: map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo{
@@ -253,25 +244,25 @@ func TestSyncer_IgnoresCapabilitiesForPrivateDON(t *testing.T) {
NodeOperatorId: 1,
Signer: randomWord(),
P2pId: nodes[0],
- HashedCapabilityIds: [][32]byte{triggerCapID, targetCapID},
+ HashedCapabilityIds: [][32]byte{hashedTriggerID, hashedTargetID},
},
nodes[1]: {
NodeOperatorId: 1,
Signer: randomWord(),
P2pId: nodes[1],
- HashedCapabilityIds: [][32]byte{triggerCapID, targetCapID},
+ HashedCapabilityIds: [][32]byte{hashedTriggerID, hashedTargetID},
},
nodes[2]: {
NodeOperatorId: 1,
Signer: randomWord(),
P2pId: nodes[2],
- HashedCapabilityIds: [][32]byte{triggerCapID, targetCapID},
+ HashedCapabilityIds: [][32]byte{hashedTriggerID, hashedTargetID},
},
nodes[3]: {
NodeOperatorId: 1,
Signer: randomWord(),
P2pId: nodes[3],
- HashedCapabilityIds: [][32]byte{triggerCapID, targetCapID},
+ HashedCapabilityIds: [][32]byte{hashedTriggerID, hashedTargetID},
},
},
}
@@ -309,14 +300,14 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDON(t *testing.T) {
wrapper := mocks.NewPeerWrapper(t)
wrapper.On("GetPeer").Return(peer)
- workflowDonNodes := [][32]byte{
+ workflowDonNodes := []ragetypes.PeerID{
pid,
randomWord(),
randomWord(),
randomWord(),
}
- capabilityDonNodes := [][32]byte{
+ capabilityDonNodes := []ragetypes.PeerID{
randomWord(),
randomWord(),
randomWord(),
@@ -332,45 +323,48 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDON(t *testing.T) {
// The below state describes a Workflow DON (AcceptsWorkflows = true),
// which exposes the streams-trigger and write_chain capabilities.
// We expect receivers to be wired up and both capabilities to be added to the registry.
- state := registrysyncer.State{
- IDsToDONs: map[registrysyncer.DonID]kcr.CapabilitiesRegistryDONInfo{
+ var rtc capabilities.RemoteTriggerConfig
+ rtc.ApplyDefaults()
+
+ state := ®istrysyncer.LocalRegistry{
+ IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{
registrysyncer.DonID(dID): {
- Id: dID,
- ConfigCount: uint32(0),
- F: uint8(1),
- IsPublic: true,
- AcceptsWorkflows: true,
- NodeP2PIds: workflowDonNodes,
+ DON: capabilities.DON{
+ ID: dID,
+ ConfigVersion: uint32(0),
+ F: uint8(1),
+ IsPublic: true,
+ AcceptsWorkflows: true,
+ Members: workflowDonNodes,
+ },
},
registrysyncer.DonID(capDonID): {
- Id: capDonID,
- ConfigCount: uint32(0),
- F: uint8(1),
- IsPublic: true,
- AcceptsWorkflows: false,
- NodeP2PIds: capabilityDonNodes,
- CapabilityConfigurations: []kcr.CapabilitiesRegistryCapabilityConfiguration{
- {
- CapabilityId: triggerCapID,
- Config: []byte(""),
+ DON: capabilities.DON{
+ ID: capDonID,
+ ConfigVersion: uint32(0),
+ F: uint8(1),
+ IsPublic: true,
+ AcceptsWorkflows: false,
+ Members: capabilityDonNodes,
+ },
+ CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{
+ fullTriggerCapID: {
+ RemoteTriggerConfig: rtc,
},
- {
- CapabilityId: targetCapID,
- Config: []byte(""),
+ fullTargetID: {
+ RemoteTriggerConfig: rtc,
},
},
},
},
- IDsToCapabilities: map[registrysyncer.HashedCapabilityID]kcr.CapabilitiesRegistryCapabilityInfo{
- triggerCapID: {
- LabelledName: "streams-trigger",
- Version: "1.0.0",
- CapabilityType: 0,
+ IDsToCapabilities: map[string]registrysyncer.Capability{
+ fullTriggerCapID: {
+ ID: fullTriggerCapID,
+ CapabilityType: capabilities.CapabilityTypeTrigger,
},
- targetCapID: {
- LabelledName: "write-chain_evm_1",
- Version: "1.0.0",
- CapabilityType: 3,
+ fullTargetID: {
+ ID: fullTargetID,
+ CapabilityType: capabilities.CapabilityTypeTarget,
},
},
IDsToNodes: map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo{
@@ -457,14 +451,14 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDONButIgnoresPrivateCapabilitie
wrapper := mocks.NewPeerWrapper(t)
wrapper.On("GetPeer").Return(peer)
- workflowDonNodes := [][32]byte{
+ workflowDonNodes := []ragetypes.PeerID{
pid,
randomWord(),
randomWord(),
randomWord(),
}
- capabilityDonNodes := [][32]byte{
+ capabilityDonNodes := []ragetypes.PeerID{
randomWord(),
randomWord(),
randomWord(),
@@ -472,6 +466,7 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDONButIgnoresPrivateCapabilitie
}
fullTriggerCapID := "streams-trigger@1.0.0"
+ fullTargetID := "write-chain_evm_1@1.0.0"
triggerCapID := randomWord()
targetCapID := randomWord()
dID := uint32(1)
@@ -480,55 +475,53 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDONButIgnoresPrivateCapabilitie
// The below state describes a Workflow DON (AcceptsWorkflows = true),
// which exposes the streams-trigger and write_chain capabilities.
// We expect receivers to be wired up and both capabilities to be added to the registry.
- state := registrysyncer.State{
- IDsToDONs: map[registrysyncer.DonID]kcr.CapabilitiesRegistryDONInfo{
+ state := ®istrysyncer.LocalRegistry{
+ IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{
registrysyncer.DonID(dID): {
- Id: dID,
- ConfigCount: uint32(0),
- F: uint8(1),
- IsPublic: true,
- AcceptsWorkflows: true,
- NodeP2PIds: workflowDonNodes,
+ DON: capabilities.DON{
+ ID: dID,
+ ConfigVersion: uint32(0),
+ F: uint8(1),
+ IsPublic: true,
+ AcceptsWorkflows: true,
+ Members: workflowDonNodes,
+ },
},
registrysyncer.DonID(triggerCapDonID): {
- Id: triggerCapDonID,
- ConfigCount: uint32(0),
- F: uint8(1),
- IsPublic: true,
- AcceptsWorkflows: false,
- NodeP2PIds: capabilityDonNodes,
- CapabilityConfigurations: []kcr.CapabilitiesRegistryCapabilityConfiguration{
- {
- CapabilityId: triggerCapID,
- Config: []byte(""),
- },
+ DON: capabilities.DON{
+ ID: triggerCapDonID,
+ ConfigVersion: uint32(0),
+ F: uint8(1),
+ IsPublic: true,
+ AcceptsWorkflows: false,
+ Members: capabilityDonNodes,
+ },
+ CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{
+ fullTriggerCapID: {},
},
},
registrysyncer.DonID(targetCapDonID): {
- Id: targetCapDonID,
- ConfigCount: uint32(0),
- F: uint8(1),
- IsPublic: false,
- AcceptsWorkflows: false,
- NodeP2PIds: capabilityDonNodes,
- CapabilityConfigurations: []kcr.CapabilitiesRegistryCapabilityConfiguration{
- {
- CapabilityId: targetCapID,
- Config: []byte(""),
- },
+ DON: capabilities.DON{
+ ID: targetCapDonID,
+ ConfigVersion: uint32(0),
+ F: uint8(1),
+ IsPublic: false,
+ AcceptsWorkflows: false,
+ Members: capabilityDonNodes,
+ },
+ CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{
+ fullTargetID: {},
},
},
},
- IDsToCapabilities: map[registrysyncer.HashedCapabilityID]kcr.CapabilitiesRegistryCapabilityInfo{
- triggerCapID: {
- LabelledName: "streams-trigger",
- Version: "1.0.0",
- CapabilityType: 0,
+ IDsToCapabilities: map[string]registrysyncer.Capability{
+ fullTriggerCapID: {
+ ID: fullTriggerCapID,
+ CapabilityType: capabilities.CapabilityTypeTrigger,
},
- targetCapID: {
- LabelledName: "write-chain_evm_1",
- Version: "1.0.0",
- CapabilityType: 3,
+ fullTargetID: {
+ ID: fullTargetID,
+ CapabilityType: capabilities.CapabilityTypeTarget,
},
},
IDsToNodes: map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo{
@@ -596,103 +589,6 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDONButIgnoresPrivateCapabilitie
require.NoError(t, err)
}
-func toPeerIDs(is [][32]byte) (out []p2ptypes.PeerID) {
- for _, i := range is {
- out = append(out, i)
- }
-
- return out
-}
-
-func TestLauncher_LocalNode(t *testing.T) {
- ctx := tests.Context(t)
- lggr := logger.TestLogger(t)
- registry := NewRegistry(lggr)
- dispatcher := remoteMocks.NewDispatcher(t)
-
- var pid ragetypes.PeerID
- err := pid.UnmarshalText([]byte("12D3KooWBCF1XT5Wi8FzfgNCqRL76Swv8TRU3TiD4QiJm8NMNX7N"))
- require.NoError(t, err)
- peer := mocks.NewPeer(t)
- peer.On("UpdateConnections", mock.Anything).Return(nil)
- peer.On("ID").Return(pid)
- wrapper := mocks.NewPeerWrapper(t)
- wrapper.On("GetPeer").Return(peer)
-
- workflowDonNodes := [][32]byte{
- pid,
- randomWord(),
- randomWord(),
- randomWord(),
- }
-
- dID := uint32(1)
- // The below state describes a Workflow DON (AcceptsWorkflows = true),
- // which exposes the streams-trigger and write_chain capabilities.
- // We expect receivers to be wired up and both capabilities to be added to the registry.
- state := registrysyncer.State{
- IDsToDONs: map[registrysyncer.DonID]kcr.CapabilitiesRegistryDONInfo{
- registrysyncer.DonID(dID): {
- Id: dID,
- ConfigCount: uint32(2),
- F: uint8(1),
- IsPublic: true,
- AcceptsWorkflows: true,
- NodeP2PIds: workflowDonNodes,
- },
- },
- IDsToNodes: map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo{
- workflowDonNodes[0]: {
- NodeOperatorId: 1,
- Signer: randomWord(),
- P2pId: workflowDonNodes[0],
- },
- workflowDonNodes[1]: {
- NodeOperatorId: 1,
- Signer: randomWord(),
- P2pId: workflowDonNodes[1],
- },
- workflowDonNodes[2]: {
- NodeOperatorId: 1,
- Signer: randomWord(),
- P2pId: workflowDonNodes[2],
- },
- workflowDonNodes[3]: {
- NodeOperatorId: 1,
- Signer: randomWord(),
- P2pId: workflowDonNodes[3],
- },
- },
- }
-
- launcher := NewLauncher(
- lggr,
- wrapper,
- dispatcher,
- registry,
- )
-
- err = launcher.Launch(ctx, state)
- require.NoError(t, err)
- defer launcher.Close()
-
- node, err := launcher.LocalNode(ctx)
- require.NoError(t, err)
-
- don := capabilities.DON{
- ID: dID,
- ConfigVersion: 2,
- Members: toPeerIDs(workflowDonNodes),
- F: 1,
- }
- expectedNode := capabilities.Node{
- PeerID: &pid,
- WorkflowDON: don,
- CapabilityDONs: []capabilities.DON{don},
- }
- assert.Equal(t, expectedNode, node)
-}
-
func TestLauncher_SucceedsEvenIfDispatcherAlreadyHasReceiver(t *testing.T) {
ctx := tests.Context(t)
lggr := logger.TestLogger(t)
@@ -716,14 +612,14 @@ func TestLauncher_SucceedsEvenIfDispatcherAlreadyHasReceiver(t *testing.T) {
))
require.NoError(t, registry.Add(ctx, mt))
- workflowDonNodes := [][32]byte{
+ workflowDonNodes := []p2ptypes.PeerID{
randomWord(),
randomWord(),
randomWord(),
randomWord(),
}
- capabilityDonNodes := [][32]byte{
+ capabilityDonNodes := []p2ptypes.PeerID{
pid,
randomWord(),
randomWord(),
@@ -736,36 +632,36 @@ func TestLauncher_SucceedsEvenIfDispatcherAlreadyHasReceiver(t *testing.T) {
// The below state describes a Capability DON (AcceptsWorkflows = true),
// which exposes the streams-trigger and write_chain capabilities.
// We expect receivers to be wired up.
- state := registrysyncer.State{
- IDsToDONs: map[registrysyncer.DonID]kcr.CapabilitiesRegistryDONInfo{
+ state := ®istrysyncer.LocalRegistry{
+ IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{
registrysyncer.DonID(dID): {
- Id: dID,
- ConfigCount: uint32(0),
- F: uint8(1),
- IsPublic: true,
- AcceptsWorkflows: true,
- NodeP2PIds: workflowDonNodes,
+ DON: capabilities.DON{
+ ID: dID,
+ ConfigVersion: uint32(0),
+ F: uint8(1),
+ IsPublic: true,
+ AcceptsWorkflows: true,
+ Members: workflowDonNodes,
+ },
},
registrysyncer.DonID(capDonID): {
- Id: capDonID,
- ConfigCount: uint32(0),
- F: uint8(1),
- IsPublic: true,
- AcceptsWorkflows: false,
- NodeP2PIds: capabilityDonNodes,
- CapabilityConfigurations: []kcr.CapabilitiesRegistryCapabilityConfiguration{
- {
- CapabilityId: triggerCapID,
- Config: []byte(""),
- },
+ DON: capabilities.DON{
+ ID: capDonID,
+ ConfigVersion: uint32(0),
+ F: uint8(1),
+ IsPublic: true,
+ AcceptsWorkflows: false,
+ Members: capabilityDonNodes,
+ },
+ CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{
+ fullTriggerCapID: {},
},
},
},
- IDsToCapabilities: map[registrysyncer.HashedCapabilityID]kcr.CapabilitiesRegistryCapabilityInfo{
- triggerCapID: {
- LabelledName: "streams-trigger",
- Version: "1.0.0",
- CapabilityType: 0,
+ IDsToCapabilities: map[string]registrysyncer.Capability{
+ fullTriggerCapID: {
+ ID: fullTriggerCapID,
+ CapabilityType: capabilities.CapabilityTypeTrigger,
},
},
IDsToNodes: map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo{
diff --git a/core/capabilities/registry.go b/core/capabilities/registry.go
index 4cca25d03c..8a99450c09 100644
--- a/core/capabilities/registry.go
+++ b/core/capabilities/registry.go
@@ -14,16 +14,42 @@ var (
ErrCapabilityAlreadyExists = errors.New("capability already exists")
)
+type metadataRegistry interface {
+ LocalNode(ctx context.Context) (capabilities.Node, error)
+ ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error)
+}
+
// Registry is a struct for the registry of capabilities.
// Registry is safe for concurrent use.
type Registry struct {
- lggr logger.Logger
- m map[string]capabilities.BaseCapability
- mu sync.RWMutex
+ metadataRegistry metadataRegistry
+ lggr logger.Logger
+ m map[string]capabilities.BaseCapability
+ mu sync.RWMutex
+}
+
+func (r *Registry) LocalNode(ctx context.Context) (capabilities.Node, error) {
+ if r.metadataRegistry == nil {
+ return capabilities.Node{}, errors.New("metadataRegistry information not available")
+ }
+
+ return r.metadataRegistry.LocalNode(ctx)
}
-func (r *Registry) GetLocalNode(_ context.Context) (capabilities.Node, error) {
- return capabilities.Node{}, nil
+func (r *Registry) ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) {
+ if r.metadataRegistry == nil {
+ return capabilities.CapabilityConfiguration{}, errors.New("metadataRegistry information not available")
+ }
+
+ return r.metadataRegistry.ConfigForCapability(ctx, capabilityID, donID)
+}
+
+// SetLocalRegistry sets a local copy of the offchain registry for the registry to use.
+// This is only public for testing purposes; the only production use should be from the CapabilitiesLauncher.
+func (r *Registry) SetLocalRegistry(lr metadataRegistry) {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ r.metadataRegistry = lr
}
// Get gets a capability from the registry.
diff --git a/core/capabilities/remote/dispatcher_test.go b/core/capabilities/remote/dispatcher_test.go
index 173972375a..7ea4c2e262 100644
--- a/core/capabilities/remote/dispatcher_test.go
+++ b/core/capabilities/remote/dispatcher_test.go
@@ -8,13 +8,14 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
- commonMocks "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/remote"
remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
"github.com/smartcontractkit/chainlink/v2/core/services/p2p/types/mocks"
+
+ commonMocks "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks"
)
type testReceiver struct {
diff --git a/core/capabilities/remote/target/endtoend_test.go b/core/capabilities/remote/target/endtoend_test.go
index c01b8d99a4..9bbb53d4f6 100644
--- a/core/capabilities/remote/target/endtoend_test.go
+++ b/core/capabilities/remote/target/endtoend_test.go
@@ -371,6 +371,26 @@ type nodeDispatcher struct {
broker broker
}
+func (t *nodeDispatcher) Name() string {
+ return "nodeDispatcher"
+}
+
+func (t *nodeDispatcher) Start(ctx context.Context) error {
+ return nil
+}
+
+func (t *nodeDispatcher) Close() error {
+ return nil
+}
+
+func (t *nodeDispatcher) Ready() error {
+ return nil
+}
+
+func (t *nodeDispatcher) HealthReport() map[string]error {
+ return nil
+}
+
func (t *nodeDispatcher) Send(peerID p2ptypes.PeerID, msgBody *remotetypes.MessageBody) error {
msgBody.Version = 1
msgBody.Sender = t.callerPeerID[:]
diff --git a/core/capabilities/remote/target/request/client_request_test.go b/core/capabilities/remote/target/request/client_request_test.go
index c20c24a550..07f43dbc71 100644
--- a/core/capabilities/remote/target/request/client_request_test.go
+++ b/core/capabilities/remote/target/request/client_request_test.go
@@ -311,6 +311,26 @@ type clientRequestTestDispatcher struct {
msgs chan *types.MessageBody
}
+func (t *clientRequestTestDispatcher) Name() string {
+ return "clientRequestTestDispatcher"
+}
+
+func (t *clientRequestTestDispatcher) Start(ctx context.Context) error {
+ return nil
+}
+
+func (t *clientRequestTestDispatcher) Close() error {
+ return nil
+}
+
+func (t *clientRequestTestDispatcher) Ready() error {
+ return nil
+}
+
+func (t *clientRequestTestDispatcher) HealthReport() map[string]error {
+ return nil
+}
+
func (t *clientRequestTestDispatcher) SetReceiver(capabilityId string, donId uint32, receiver types.Receiver) error {
return nil
}
diff --git a/core/capabilities/remote/target/request/server_request_test.go b/core/capabilities/remote/target/request/server_request_test.go
index 053cba7064..a35725d6b1 100644
--- a/core/capabilities/remote/target/request/server_request_test.go
+++ b/core/capabilities/remote/target/request/server_request_test.go
@@ -190,6 +190,26 @@ type testDispatcher struct {
msgs []*types.MessageBody
}
+func (t *testDispatcher) Name() string {
+ return "testDispatcher"
+}
+
+func (t *testDispatcher) Start(ctx context.Context) error {
+ return nil
+}
+
+func (t *testDispatcher) Close() error {
+ return nil
+}
+
+func (t *testDispatcher) Ready() error {
+ return nil
+}
+
+func (t *testDispatcher) HealthReport() map[string]error {
+ return nil
+}
+
func (t *testDispatcher) SetReceiver(capabilityId string, donId uint32, receiver types.Receiver) error {
return nil
}
diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go
index 7744cfb55e..35ce41118f 100644
--- a/core/capabilities/remote/trigger_publisher.go
+++ b/core/capabilities/remote/trigger_publisher.go
@@ -21,7 +21,7 @@ import (
//
// TriggerPublisher communicates with corresponding TriggerSubscribers on remote nodes.
type triggerPublisher struct {
- config *types.RemoteTriggerConfig
+ config capabilities.RemoteTriggerConfig
underlying commoncap.TriggerCapability
capInfo commoncap.CapabilityInfo
capDonInfo commoncap.DON
@@ -48,7 +48,7 @@ type pubRegState struct {
var _ types.Receiver = &triggerPublisher{}
var _ services.Service = &triggerPublisher{}
-func NewTriggerPublisher(config *types.RemoteTriggerConfig, underlying commoncap.TriggerCapability, capInfo commoncap.CapabilityInfo, capDonInfo commoncap.DON, workflowDONs map[uint32]commoncap.DON, dispatcher types.Dispatcher, lggr logger.Logger) *triggerPublisher {
+func NewTriggerPublisher(config capabilities.RemoteTriggerConfig, underlying commoncap.TriggerCapability, capInfo commoncap.CapabilityInfo, capDonInfo commoncap.DON, workflowDONs map[uint32]commoncap.DON, dispatcher types.Dispatcher, lggr logger.Logger) *triggerPublisher {
config.ApplyDefaults()
return &triggerPublisher{
config: config,
@@ -97,7 +97,7 @@ func (p *triggerPublisher) Receive(_ context.Context, msg *types.MessageBody) {
}
// NOTE: require 2F+1 by default, introduce different strategies later (KS-76)
minRequired := uint32(2*callerDon.F + 1)
- ready, payloads := p.messageCache.Ready(key, minRequired, nowMs-int64(p.config.RegistrationExpiryMs), false)
+ ready, payloads := p.messageCache.Ready(key, minRequired, nowMs-p.config.RegistrationExpiry.Milliseconds(), false)
if !ready {
p.lggr.Debugw("not ready to aggregate yet", "capabilityId", p.capInfo.ID, "workflowId", req.Metadata.WorkflowID, "minRequired", minRequired)
return
@@ -133,7 +133,7 @@ func (p *triggerPublisher) Receive(_ context.Context, msg *types.MessageBody) {
func (p *triggerPublisher) registrationCleanupLoop() {
defer p.wg.Done()
- ticker := time.NewTicker(time.Duration(p.config.RegistrationExpiryMs) * time.Millisecond)
+ ticker := time.NewTicker(p.config.RegistrationExpiry)
defer ticker.Stop()
for {
select {
@@ -144,7 +144,7 @@ func (p *triggerPublisher) registrationCleanupLoop() {
p.mu.RLock()
for key, req := range p.registrations {
callerDon := p.workflowDONs[key.callerDonId]
- ready, _ := p.messageCache.Ready(key, uint32(2*callerDon.F+1), now-int64(p.config.RegistrationExpiryMs), false)
+ ready, _ := p.messageCache.Ready(key, uint32(2*callerDon.F+1), now-p.config.RegistrationExpiry.Milliseconds(), false)
if !ready {
p.lggr.Infow("trigger registration expired", "capabilityId", p.capInfo.ID, "callerDonID", key.callerDonId, "workflowId", key.workflowId)
ctx, cancel := p.stopCh.NewCtx()
diff --git a/core/capabilities/remote/trigger_publisher_test.go b/core/capabilities/remote/trigger_publisher_test.go
index ec38b962ce..1e3000d20c 100644
--- a/core/capabilities/remote/trigger_publisher_test.go
+++ b/core/capabilities/remote/trigger_publisher_test.go
@@ -3,9 +3,11 @@ package remote_test
import (
"context"
"testing"
+ "time"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
"github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/remote"
@@ -40,11 +42,11 @@ func TestTriggerPublisher_Register(t *testing.T) {
}
dispatcher := remoteMocks.NewDispatcher(t)
- config := &remotetypes.RemoteTriggerConfig{
- RegistrationRefreshMs: 100,
- RegistrationExpiryMs: 100_000,
+ config := capabilities.RemoteTriggerConfig{
+ RegistrationRefresh: 100 * time.Millisecond,
+ RegistrationExpiry: 100 * time.Second,
MinResponsesToAggregate: 1,
- MessageExpiryMs: 100_000,
+ MessageExpiry: 100 * time.Second,
}
workflowDONs := map[uint32]commoncap.DON{
workflowDonInfo.ID: workflowDonInfo,
diff --git a/core/capabilities/remote/trigger_subscriber.go b/core/capabilities/remote/trigger_subscriber.go
index 28bdff9c51..0ccbf37c61 100644
--- a/core/capabilities/remote/trigger_subscriber.go
+++ b/core/capabilities/remote/trigger_subscriber.go
@@ -23,7 +23,7 @@ import (
//
// TriggerSubscriber communicates with corresponding TriggerReceivers on remote nodes.
type triggerSubscriber struct {
- config *types.RemoteTriggerConfig
+ config capabilities.RemoteTriggerConfig
capInfo commoncap.CapabilityInfo
capDonInfo capabilities.DON
capDonMembers map[p2ptypes.PeerID]struct{}
@@ -55,7 +55,7 @@ var _ services.Service = &triggerSubscriber{}
// TODO makes this configurable with a default
const defaultSendChannelBufferSize = 1000
-func NewTriggerSubscriber(config *types.RemoteTriggerConfig, capInfo commoncap.CapabilityInfo, capDonInfo capabilities.DON, localDonInfo capabilities.DON, dispatcher types.Dispatcher, aggregator types.Aggregator, lggr logger.Logger) *triggerSubscriber {
+func NewTriggerSubscriber(config capabilities.RemoteTriggerConfig, capInfo commoncap.CapabilityInfo, capDonInfo capabilities.DON, localDonInfo capabilities.DON, dispatcher types.Dispatcher, aggregator types.Aggregator, lggr logger.Logger) *triggerSubscriber {
if aggregator == nil {
lggr.Warnw("no aggregator provided, using default MODE aggregator", "capabilityId", capInfo.ID)
aggregator = NewDefaultModeAggregator(uint32(capDonInfo.F + 1))
@@ -121,7 +121,7 @@ func (s *triggerSubscriber) RegisterTrigger(ctx context.Context, request commonc
func (s *triggerSubscriber) registrationLoop() {
defer s.wg.Done()
- ticker := time.NewTicker(time.Duration(s.config.RegistrationRefreshMs) * time.Millisecond)
+ ticker := time.NewTicker(s.config.RegistrationRefresh)
defer ticker.Stop()
for {
select {
@@ -195,9 +195,9 @@ func (s *triggerSubscriber) Receive(_ context.Context, msg *types.MessageBody) {
nowMs := time.Now().UnixMilli()
s.mu.RLock()
creationTs := s.messageCache.Insert(key, sender, nowMs, msg.Payload)
- ready, payloads := s.messageCache.Ready(key, s.config.MinResponsesToAggregate, nowMs-int64(s.config.MessageExpiryMs), true)
+ ready, payloads := s.messageCache.Ready(key, s.config.MinResponsesToAggregate, nowMs-s.config.MessageExpiry.Milliseconds(), true)
s.mu.RUnlock()
- if nowMs-creationTs > int64(s.config.RegistrationExpiryMs) {
+ if nowMs-creationTs > s.config.RegistrationExpiry.Milliseconds() {
s.lggr.Warnw("received trigger event for an expired ID", "triggerEventID", meta.TriggerEventId, "capabilityId", s.capInfo.ID, "workflowId", workflowId, "sender", sender)
continue
}
@@ -219,7 +219,7 @@ func (s *triggerSubscriber) Receive(_ context.Context, msg *types.MessageBody) {
func (s *triggerSubscriber) eventCleanupLoop() {
defer s.wg.Done()
- ticker := time.NewTicker(time.Duration(s.config.MessageExpiryMs) * time.Millisecond)
+ ticker := time.NewTicker(s.config.MessageExpiry)
defer ticker.Stop()
for {
select {
@@ -227,7 +227,7 @@ func (s *triggerSubscriber) eventCleanupLoop() {
return
case <-ticker.C:
s.mu.Lock()
- s.messageCache.DeleteOlderThan(time.Now().UnixMilli() - int64(s.config.MessageExpiryMs))
+ s.messageCache.DeleteOlderThan(time.Now().UnixMilli() - s.config.MessageExpiry.Milliseconds())
s.mu.Unlock()
}
}
diff --git a/core/capabilities/remote/trigger_subscriber_test.go b/core/capabilities/remote/trigger_subscriber_test.go
index 782b29d41f..93e962215a 100644
--- a/core/capabilities/remote/trigger_subscriber_test.go
+++ b/core/capabilities/remote/trigger_subscriber_test.go
@@ -2,10 +2,12 @@ package remote_test
import (
"testing"
+ "time"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
"github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"
"github.com/smartcontractkit/chainlink-common/pkg/values"
@@ -61,11 +63,11 @@ func TestTriggerSubscriber_RegisterAndReceive(t *testing.T) {
})
// register trigger
- config := &remotetypes.RemoteTriggerConfig{
- RegistrationRefreshMs: 100,
- RegistrationExpiryMs: 100,
+ config := capabilities.RemoteTriggerConfig{
+ RegistrationRefresh: 100 * time.Millisecond,
+ RegistrationExpiry: 100 * time.Second,
MinResponsesToAggregate: 1,
- MessageExpiryMs: 100_000,
+ MessageExpiry: 100 * time.Second,
}
subscriber := remote.NewTriggerSubscriber(config, capInfo, capDonInfo, workflowDonInfo, dispatcher, nil, lggr)
require.NoError(t, subscriber.Start(ctx))
diff --git a/core/capabilities/remote/types/config.go b/core/capabilities/remote/types/config.go
deleted file mode 100644
index bb9e0fa434..0000000000
--- a/core/capabilities/remote/types/config.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package types
-
-const (
- DefaultRegistrationRefreshMs = 30_000
- DefaultRegistrationExpiryMs = 120_000
- DefaultMessageExpiryMs = 120_000
-)
-
-// NOTE: consider splitting this config into values stored in Registry (KS-118)
-// and values defined locally by Capability owners.
-func (c *RemoteTriggerConfig) ApplyDefaults() {
- if c.RegistrationRefreshMs == 0 {
- c.RegistrationRefreshMs = DefaultRegistrationRefreshMs
- }
- if c.RegistrationExpiryMs == 0 {
- c.RegistrationExpiryMs = DefaultRegistrationExpiryMs
- }
- if c.MessageExpiryMs == 0 {
- c.MessageExpiryMs = DefaultMessageExpiryMs
- }
-}
diff --git a/core/capabilities/remote/types/messages.pb.go b/core/capabilities/remote/types/messages.pb.go
index 83e17897db..f5b77b5c15 100644
--- a/core/capabilities/remote/types/messages.pb.go
+++ b/core/capabilities/remote/types/messages.pb.go
@@ -413,77 +413,6 @@ func (x *TriggerEventMetadata) GetWorkflowIds() []string {
return nil
}
-type RemoteTriggerConfig struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- RegistrationRefreshMs uint32 `protobuf:"varint,1,opt,name=registrationRefreshMs,proto3" json:"registrationRefreshMs,omitempty"`
- RegistrationExpiryMs uint32 `protobuf:"varint,2,opt,name=registrationExpiryMs,proto3" json:"registrationExpiryMs,omitempty"`
- MinResponsesToAggregate uint32 `protobuf:"varint,3,opt,name=minResponsesToAggregate,proto3" json:"minResponsesToAggregate,omitempty"`
- MessageExpiryMs uint32 `protobuf:"varint,4,opt,name=messageExpiryMs,proto3" json:"messageExpiryMs,omitempty"`
-}
-
-func (x *RemoteTriggerConfig) Reset() {
- *x = RemoteTriggerConfig{}
- if protoimpl.UnsafeEnabled {
- mi := &file_core_capabilities_remote_types_messages_proto_msgTypes[4]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *RemoteTriggerConfig) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*RemoteTriggerConfig) ProtoMessage() {}
-
-func (x *RemoteTriggerConfig) ProtoReflect() protoreflect.Message {
- mi := &file_core_capabilities_remote_types_messages_proto_msgTypes[4]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use RemoteTriggerConfig.ProtoReflect.Descriptor instead.
-func (*RemoteTriggerConfig) Descriptor() ([]byte, []int) {
- return file_core_capabilities_remote_types_messages_proto_rawDescGZIP(), []int{4}
-}
-
-func (x *RemoteTriggerConfig) GetRegistrationRefreshMs() uint32 {
- if x != nil {
- return x.RegistrationRefreshMs
- }
- return 0
-}
-
-func (x *RemoteTriggerConfig) GetRegistrationExpiryMs() uint32 {
- if x != nil {
- return x.RegistrationExpiryMs
- }
- return 0
-}
-
-func (x *RemoteTriggerConfig) GetMinResponsesToAggregate() uint32 {
- if x != nil {
- return x.MinResponsesToAggregate
- }
- return 0
-}
-
-func (x *RemoteTriggerConfig) GetMessageExpiryMs() uint32 {
- if x != nil {
- return x.MessageExpiryMs
- }
- return 0
-}
-
var File_core_capabilities_remote_types_messages_proto protoreflect.FileDescriptor
var file_core_capabilities_remote_types_messages_proto_rawDesc = []byte{
@@ -543,32 +472,17 @@ var file_core_capabilities_remote_types_messages_proto_rawDesc = []byte{
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45,
0x76, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c,
0x6f, 0x77, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x77, 0x6f,
- 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x73, 0x22, 0xe3, 0x01, 0x0a, 0x13, 0x52, 0x65,
- 0x6d, 0x6f, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x12, 0x34, 0x0a, 0x15, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x15, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
- 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x72, 0x65, 0x67, 0x69, 0x73,
- 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x4d, 0x73, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x4d, 0x73, 0x12, 0x38, 0x0a, 0x17, 0x6d,
- 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x54, 0x6f, 0x41, 0x67, 0x67,
- 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x6d, 0x69,
- 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x54, 0x6f, 0x41, 0x67, 0x67, 0x72,
- 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
- 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x4d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f,
- 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x4d, 0x73, 0x2a,
- 0x76, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00,
- 0x12, 0x15, 0x0a, 0x11, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46,
- 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x41, 0x50, 0x41, 0x42,
- 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10,
- 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x51,
- 0x55, 0x45, 0x53, 0x54, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55,
- 0x54, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f,
- 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x42, 0x20, 0x5a, 0x1e, 0x63, 0x6f, 0x72, 0x65, 0x2f,
- 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x6d,
- 0x6f, 0x74, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x33,
+ 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x73, 0x2a, 0x76, 0x0a, 0x05, 0x45, 0x72, 0x72,
+ 0x6f, 0x72, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x41,
+ 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10,
+ 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x41, 0x50, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f,
+ 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x49,
+ 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x03,
+ 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x04, 0x12, 0x12, 0x0a,
+ 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10,
+ 0x05, 0x42, 0x20, 0x5a, 0x1e, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
+ 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x74, 0x79,
+ 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -584,14 +498,13 @@ func file_core_capabilities_remote_types_messages_proto_rawDescGZIP() []byte {
}
var file_core_capabilities_remote_types_messages_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_core_capabilities_remote_types_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
+var file_core_capabilities_remote_types_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_core_capabilities_remote_types_messages_proto_goTypes = []any{
(Error)(0), // 0: remote.Error
(*Message)(nil), // 1: remote.Message
(*MessageBody)(nil), // 2: remote.MessageBody
(*TriggerRegistrationMetadata)(nil), // 3: remote.TriggerRegistrationMetadata
(*TriggerEventMetadata)(nil), // 4: remote.TriggerEventMetadata
- (*RemoteTriggerConfig)(nil), // 5: remote.RemoteTriggerConfig
}
var file_core_capabilities_remote_types_messages_proto_depIdxs = []int32{
0, // 0: remote.MessageBody.error:type_name -> remote.Error
@@ -658,18 +571,6 @@ func file_core_capabilities_remote_types_messages_proto_init() {
return nil
}
}
- file_core_capabilities_remote_types_messages_proto_msgTypes[4].Exporter = func(v any, i int) any {
- switch v := v.(*RemoteTriggerConfig); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
}
file_core_capabilities_remote_types_messages_proto_msgTypes[1].OneofWrappers = []any{
(*MessageBody_TriggerRegistrationMetadata)(nil),
@@ -681,7 +582,7 @@ func file_core_capabilities_remote_types_messages_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_core_capabilities_remote_types_messages_proto_rawDesc,
NumEnums: 1,
- NumMessages: 5,
+ NumMessages: 4,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/core/capabilities/remote/types/messages.proto b/core/capabilities/remote/types/messages.proto
index 4855892f9f..7726538e8d 100644
--- a/core/capabilities/remote/types/messages.proto
+++ b/core/capabilities/remote/types/messages.proto
@@ -49,10 +49,3 @@ message TriggerEventMetadata {
string trigger_event_id = 1;
repeated string workflow_ids = 2;
}
-
-message RemoteTriggerConfig {
- uint32 registrationRefreshMs = 1;
- uint32 registrationExpiryMs = 2;
- uint32 minResponsesToAggregate = 3;
- uint32 messageExpiryMs = 4;
-}
diff --git a/core/capabilities/remote/types/mocks/dispatcher.go b/core/capabilities/remote/types/mocks/dispatcher.go
index a73fa7e362..422198ffc1 100644
--- a/core/capabilities/remote/types/mocks/dispatcher.go
+++ b/core/capabilities/remote/types/mocks/dispatcher.go
@@ -3,9 +3,12 @@
package mocks
import (
- types "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types"
+ context "context"
+
ragep2ptypes "github.com/smartcontractkit/libocr/ragep2p/types"
mock "github.com/stretchr/testify/mock"
+
+ types "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types"
)
// Dispatcher is an autogenerated mock type for the Dispatcher type
@@ -21,6 +24,188 @@ func (_m *Dispatcher) EXPECT() *Dispatcher_Expecter {
return &Dispatcher_Expecter{mock: &_m.Mock}
}
+// Close provides a mock function with given fields:
+func (_m *Dispatcher) Close() error {
+ ret := _m.Called()
+
+ if len(ret) == 0 {
+ panic("no return value specified for Close")
+ }
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func() error); ok {
+ r0 = rf()
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// Dispatcher_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close'
+type Dispatcher_Close_Call struct {
+ *mock.Call
+}
+
+// Close is a helper method to define mock.On call
+func (_e *Dispatcher_Expecter) Close() *Dispatcher_Close_Call {
+ return &Dispatcher_Close_Call{Call: _e.mock.On("Close")}
+}
+
+func (_c *Dispatcher_Close_Call) Run(run func()) *Dispatcher_Close_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *Dispatcher_Close_Call) Return(_a0 error) *Dispatcher_Close_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Dispatcher_Close_Call) RunAndReturn(run func() error) *Dispatcher_Close_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// HealthReport provides a mock function with given fields:
+func (_m *Dispatcher) HealthReport() map[string]error {
+ ret := _m.Called()
+
+ if len(ret) == 0 {
+ panic("no return value specified for HealthReport")
+ }
+
+ var r0 map[string]error
+ if rf, ok := ret.Get(0).(func() map[string]error); ok {
+ r0 = rf()
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(map[string]error)
+ }
+ }
+
+ return r0
+}
+
+// Dispatcher_HealthReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HealthReport'
+type Dispatcher_HealthReport_Call struct {
+ *mock.Call
+}
+
+// HealthReport is a helper method to define mock.On call
+func (_e *Dispatcher_Expecter) HealthReport() *Dispatcher_HealthReport_Call {
+ return &Dispatcher_HealthReport_Call{Call: _e.mock.On("HealthReport")}
+}
+
+func (_c *Dispatcher_HealthReport_Call) Run(run func()) *Dispatcher_HealthReport_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *Dispatcher_HealthReport_Call) Return(_a0 map[string]error) *Dispatcher_HealthReport_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Dispatcher_HealthReport_Call) RunAndReturn(run func() map[string]error) *Dispatcher_HealthReport_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// Name provides a mock function with given fields:
+func (_m *Dispatcher) Name() string {
+ ret := _m.Called()
+
+ if len(ret) == 0 {
+ panic("no return value specified for Name")
+ }
+
+ var r0 string
+ if rf, ok := ret.Get(0).(func() string); ok {
+ r0 = rf()
+ } else {
+ r0 = ret.Get(0).(string)
+ }
+
+ return r0
+}
+
+// Dispatcher_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name'
+type Dispatcher_Name_Call struct {
+ *mock.Call
+}
+
+// Name is a helper method to define mock.On call
+func (_e *Dispatcher_Expecter) Name() *Dispatcher_Name_Call {
+ return &Dispatcher_Name_Call{Call: _e.mock.On("Name")}
+}
+
+func (_c *Dispatcher_Name_Call) Run(run func()) *Dispatcher_Name_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *Dispatcher_Name_Call) Return(_a0 string) *Dispatcher_Name_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Dispatcher_Name_Call) RunAndReturn(run func() string) *Dispatcher_Name_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// Ready provides a mock function with given fields:
+func (_m *Dispatcher) Ready() error {
+ ret := _m.Called()
+
+ if len(ret) == 0 {
+ panic("no return value specified for Ready")
+ }
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func() error); ok {
+ r0 = rf()
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// Dispatcher_Ready_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Ready'
+type Dispatcher_Ready_Call struct {
+ *mock.Call
+}
+
+// Ready is a helper method to define mock.On call
+func (_e *Dispatcher_Expecter) Ready() *Dispatcher_Ready_Call {
+ return &Dispatcher_Ready_Call{Call: _e.mock.On("Ready")}
+}
+
+func (_c *Dispatcher_Ready_Call) Run(run func()) *Dispatcher_Ready_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *Dispatcher_Ready_Call) Return(_a0 error) *Dispatcher_Ready_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Dispatcher_Ready_Call) RunAndReturn(run func() error) *Dispatcher_Ready_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// RemoveReceiver provides a mock function with given fields: capabilityId, donId
func (_m *Dispatcher) RemoveReceiver(capabilityId string, donId uint32) {
_m.Called(capabilityId, donId)
@@ -150,6 +335,52 @@ func (_c *Dispatcher_SetReceiver_Call) RunAndReturn(run func(string, uint32, typ
return _c
}
+// Start provides a mock function with given fields: _a0
+func (_m *Dispatcher) Start(_a0 context.Context) error {
+ ret := _m.Called(_a0)
+
+ if len(ret) == 0 {
+ panic("no return value specified for Start")
+ }
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func(context.Context) error); ok {
+ r0 = rf(_a0)
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// Dispatcher_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start'
+type Dispatcher_Start_Call struct {
+ *mock.Call
+}
+
+// Start is a helper method to define mock.On call
+// - _a0 context.Context
+func (_e *Dispatcher_Expecter) Start(_a0 interface{}) *Dispatcher_Start_Call {
+ return &Dispatcher_Start_Call{Call: _e.mock.On("Start", _a0)}
+}
+
+func (_c *Dispatcher_Start_Call) Run(run func(_a0 context.Context)) *Dispatcher_Start_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context))
+ })
+ return _c
+}
+
+func (_c *Dispatcher_Start_Call) Return(_a0 error) *Dispatcher_Start_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Dispatcher_Start_Call) RunAndReturn(run func(context.Context) error) *Dispatcher_Start_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// NewDispatcher creates a new instance of Dispatcher. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewDispatcher(t interface {
diff --git a/core/capabilities/remote/types/types.go b/core/capabilities/remote/types/types.go
index d15e2a2824..3629fc06fe 100644
--- a/core/capabilities/remote/types/types.go
+++ b/core/capabilities/remote/types/types.go
@@ -8,6 +8,7 @@ import (
"context"
commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
+ "github.com/smartcontractkit/chainlink-common/pkg/services"
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
)
@@ -19,6 +20,7 @@ const (
)
type Dispatcher interface {
+ services.Service
SetReceiver(capabilityId string, donId uint32, receiver Receiver) error
RemoveReceiver(capabilityId string, donId uint32)
Send(peerID p2ptypes.PeerID, msgBody *MessageBody) error
diff --git a/core/capabilities/streams/trigger_test.go b/core/capabilities/streams/trigger_test.go
index 6d8c9a27c1..cb4cfaa36b 100644
--- a/core/capabilities/streams/trigger_test.go
+++ b/core/capabilities/streams/trigger_test.go
@@ -87,7 +87,7 @@ func TestStreamsTrigger(t *testing.T) {
Members: capMembers,
F: uint8(F),
}
- config := &remotetypes.RemoteTriggerConfig{
+ config := capabilities.RemoteTriggerConfig{
MinResponsesToAggregate: uint32(F + 1),
}
subscriber := remote.NewTriggerSubscriber(config, capInfo, capDonInfo, capabilities.DON{}, nil, agg, lggr)
diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go
index da2de59a8a..330f15872d 100644
--- a/core/capabilities/targets/write_target.go
+++ b/core/capabilities/targets/write_target.go
@@ -29,6 +29,7 @@ type WriteTarget struct {
cw commontypes.ChainWriter
forwarderAddress string
capabilities.CapabilityInfo
+
lggr logger.Logger
bound bool
@@ -132,7 +133,7 @@ func (cap *WriteTarget) Execute(ctx context.Context, request capabilities.Capabi
}
var transmitter common.Address
if err = cap.cr.GetLatestValue(ctx, "forwarder", "getTransmitter", primitives.Unconfirmed, queryInputs, &transmitter); err != nil {
- return nil, err
+ return nil, fmt.Errorf("failed to getTransmitter latest value: %w", err)
}
if transmitter != common.HexToAddress("0x0") {
cap.lggr.Infow("WriteTarget report already onchain - returning without a tranmission attempt", "executionID", request.Metadata.WorkflowExecutionID)
diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go
index d1985c4287..0bea1816a8 100644
--- a/core/cmd/shell_local_test.go
+++ b/core/cmd/shell_local_test.go
@@ -11,6 +11,7 @@ import (
commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
+ "github.com/smartcontractkit/chainlink/v2/core/capabilities"
"github.com/smartcontractkit/chainlink/v2/common/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm"
@@ -44,8 +45,9 @@ import (
func genTestEVMRelayers(t *testing.T, opts legacyevm.ChainRelayExtenderConfig, ks evmrelayer.CSAETHKeystore) *chainlink.CoreRelayerChainInteroperators {
f := chainlink.RelayerFactory{
- Logger: opts.Logger,
- LoopRegistry: plugins.NewLoopRegistry(opts.Logger, opts.AppConfig.Tracing()),
+ Logger: opts.Logger,
+ LoopRegistry: plugins.NewLoopRegistry(opts.Logger, opts.AppConfig.Tracing()),
+ CapabilitiesRegistry: capabilities.NewRegistry(opts.Logger),
}
relayers, err := chainlink.NewCoreRelayerChainInteroperators(chainlink.InitEVM(testutils.Context(t), f, chainlink.EVMFactoryConfig{
diff --git a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go
index 2f98ae1623..aa8cf0bd86 100644
--- a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go
+++ b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go
@@ -36,15 +36,15 @@ type TermsOfServiceAllowListConfig struct {
}
var TermsOfServiceAllowListMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"initialAllowedSenders\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"initialBlockedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"allowedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getBlockedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"blockedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60806040523480156200001157600080fd5b5060405162001a1e38038062001a1e8339810160408190526200003491620004d9565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620001d4565b505050620000d2836200027f60201b60201c565b60005b8251811015620001255762000111838281518110620000f857620000f8620005a8565b602002602001015160026200030660201b90919060201c565b506200011d81620005be565b9050620000d5565b5060005b8151811015620001ca57620001658282815181106200014c576200014c620005a8565b602002602001015160026200032660201b90919060201c565b156200018457604051638129bbcd60e01b815260040160405180910390fd5b620001b68282815181106200019d576200019d620005a8565b602002602001015160046200030660201b90919060201c565b50620001c281620005be565b905062000129565b50505050620005e6565b336001600160a01b038216036200022e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200028962000349565b805160068054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b60006200031d836001600160a01b038416620003a7565b90505b92915050565b6001600160a01b038116600090815260018301602052604081205415156200031d565b6000546001600160a01b03163314620003a55760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000818152600183016020526040812054620003f05750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000320565b50600062000320565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200042757600080fd5b919050565b600082601f8301126200043e57600080fd5b815160206001600160401b03808311156200045d576200045d620003f9565b8260051b604051601f19603f83011681018181108482111715620004855762000485620003f9565b604052938452858101830193838101925087851115620004a457600080fd5b83870191505b84821015620004ce57620004be826200040f565b83529183019190830190620004aa565b979650505050505050565b60008060008385036080811215620004f057600080fd5b6040811215620004ff57600080fd5b50604080519081016001600160401b038082118383101715620005265762000526620003f9565b816040528651915081151582146200053d57600080fd5b8183526200054e602088016200040f565b60208401526040870151929550808311156200056957600080fd5b62000577888489016200042c565b945060608701519250808311156200058e57600080fd5b50506200059e868287016200042c565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600060018201620005df57634e487b7160e01b600052601160045260246000fd5b5060010190565b61142880620005f66000396000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c8063817ef62e116100b2578063a39b06e311610081578063c3f909d411610066578063c3f909d4146102c3578063cc7ebf4914610322578063f2fde38b1461032a57600080fd5b8063a39b06e314610237578063a5e1d61d146102b057600080fd5b8063817ef62e146101e157806382184c7b146101e957806389f9a2c4146101fc5780638da5cb5b1461020f57600080fd5b80633908c4d4116100ee5780633908c4d41461018e57806347663acb146101a35780636b14daf8146101b657806379ba5097146101d957600080fd5b806301a05958146101205780630a8c9c2414610146578063181f5a771461016657806320229a861461017b575b600080fd5b61012861033d565b60405167ffffffffffffffff90911681526020015b60405180910390f35b610159610154366004610fc4565b61034e565b60405161013d9190610ff7565b61016e6104aa565b60405161013d9190611051565b610159610189366004610fc4565b6104c6565b6101a161019c3660046110e1565b61062c565b005b6101a16101b1366004611142565b6108d7565b6101c96101c436600461115d565b610938565b604051901515815260200161013d565b6101a1610962565b610159610a64565b6101a16101f7366004611142565b610a70565b6101a161020a36600461120f565b610ad6565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161013d565b6102a2610245366004611298565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60405190815260200161013d565b6101c96102be366004611142565b610b91565b60408051808201825260008082526020918201528151808301835260065460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff61010090920482169284019283528451908152915116918101919091520161013d565b610128610bb1565b6101a1610338366004611142565b610bbd565b60006103496004610bd1565b905090565b60608167ffffffffffffffff168367ffffffffffffffff16118061038557506103776002610bd1565b8267ffffffffffffffff1610155b156103bc576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103c683836112f1565b6103d1906001611312565b67ffffffffffffffff1667ffffffffffffffff8111156103f3576103f36111e0565b60405190808252806020026020018201604052801561041c578160200160208202803683370190505b50905060005b61042c84846112f1565b67ffffffffffffffff1681116104a25761045b6104538267ffffffffffffffff8716611333565b600290610bdb565b82828151811061046d5761046d611346565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015261049b81611375565b9050610422565b505b92915050565b6040518060600160405280602c81526020016113f0602c913981565b60608167ffffffffffffffff168367ffffffffffffffff1611806104fd57506104ef6004610bd1565b8267ffffffffffffffff1610155b8061050f575061050d6004610bd1565b155b15610546576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61055083836112f1565b61055b906001611312565b67ffffffffffffffff1667ffffffffffffffff81111561057d5761057d6111e0565b6040519080825280602002602001820160405280156105a6578160200160208202803683370190505b50905060005b6105b684846112f1565b67ffffffffffffffff1681116104a2576105e56105dd8267ffffffffffffffff8716611333565b600490610bdb565b8282815181106105f7576105f7611346565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015261062581611375565b90506105ac565b610637600485610be7565b1561066e576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206006546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa1580156107a2573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff861614158061083e57503373ffffffffffffffffffffffffffffffffffffffff87161480159061083e5750333b155b15610875576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610880600286610c16565b156108cf5760405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a15b505050505050565b6108df610c38565b6108ea600482610cbb565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b906020015b60405180910390a150565b60065460009060ff1661094d5750600161095b565b610958600285610be7565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146109e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606103496002610cdd565b610a78610c38565b610a83600282610cbb565b50610a8f600482610c16565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e19060200161092d565b610ade610c38565b805160068054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910161092d565b60065460009060ff16610ba657506000919050565b6104a4600483610be7565b60006103496002610bd1565b610bc5610c38565b610bce81610cea565b50565b60006104a4825490565b600061095b8383610ddf565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561095b565b600061095b8373ffffffffffffffffffffffffffffffffffffffff8416610e09565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016109df565b565b600061095b8373ffffffffffffffffffffffffffffffffffffffff8416610e58565b6060600061095b83610f4b565b3373ffffffffffffffffffffffffffffffffffffffff821603610d69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016109df565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110610df657610df6611346565b9060005260206000200154905092915050565b6000818152600183016020526040812054610e50575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104a4565b5060006104a4565b60008181526001830160205260408120548015610f41576000610e7c6001836113ad565b8554909150600090610e90906001906113ad565b9050818114610ef5576000866000018281548110610eb057610eb0611346565b9060005260206000200154905080876000018481548110610ed357610ed3611346565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610f0657610f066113c0565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104a4565b60009150506104a4565b606081600001805480602002602001604051908101604052809291908181526020018280548015610f9b57602002820191906000526020600020905b815481526020019060010190808311610f87575b50505050509050919050565b803567ffffffffffffffff81168114610fbf57600080fd5b919050565b60008060408385031215610fd757600080fd5b610fe083610fa7565b9150610fee60208401610fa7565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561104557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611013565b50909695505050505050565b600060208083528351808285015260005b8181101561107e57858101830151858201604001528201611062565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610fbf57600080fd5b600080600080600060a086880312156110f957600080fd5b611102866110bd565b9450611110602087016110bd565b93506040860135925060608601359150608086013560ff8116811461113457600080fd5b809150509295509295909350565b60006020828403121561115457600080fd5b61095b826110bd565b60008060006040848603121561117257600080fd5b61117b846110bd565b9250602084013567ffffffffffffffff8082111561119857600080fd5b818601915086601f8301126111ac57600080fd5b8135818111156111bb57600080fd5b8760208285010111156111cd57600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006040828403121561122157600080fd5b6040516040810181811067ffffffffffffffff8211171561126b577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528235801515811461127e57600080fd5b815261128c602084016110bd565b60208201529392505050565b600080604083850312156112ab57600080fd5b6112b4836110bd565b9150610fee602084016110bd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8281168282160390808211156104a2576104a26112c2565b67ffffffffffffffff8181168382160190808211156104a2576104a26112c2565b808201808211156104a4576104a46112c2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036113a6576113a66112c2565b5060010190565b818103818111156104a4576104a46112c2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"initialAllowedSenders\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"initialBlockedSenders\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"previousToSContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoPreviousToSContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"allowedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getBlockedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"blockedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"previousSendersToAdd\",\"type\":\"address[]\"}],\"name\":\"migratePreviouslyAllowedSenders\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x60806040523480156200001157600080fd5b5060405162001d5338038062001d53833981016040819052620000349162000525565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620001f5565b505050620000d284620002a060201b60201c565b60005b8351811015620001255762000111848281518110620000f857620000f8620005eb565b602002602001015160036200032760201b90919060201c565b506200011d8162000601565b9050620000d5565b5060005b8251811015620001ca57620001658382815181106200014c576200014c620005eb565b602002602001015160036200034760201b90919060201c565b156200018457604051638129bbcd60e01b815260040160405180910390fd5b620001b68382815181106200019d576200019d620005eb565b602002602001015160056200032760201b90919060201c565b50620001c28162000601565b905062000129565b50600280546001600160a01b0319166001600160a01b03929092169190911790555062000629915050565b336001600160a01b038216036200024f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620002aa6200036a565b805160078054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b60006200033e836001600160a01b038416620003c8565b90505b92915050565b6001600160a01b038116600090815260018301602052604081205415156200033e565b6000546001600160a01b03163314620003c65760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000818152600183016020526040812054620004115750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000341565b50600062000341565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200045557620004556200041a565b60405290565b80516001600160a01b03811681146200047357600080fd5b919050565b600082601f8301126200048a57600080fd5b815160206001600160401b0380831115620004a957620004a96200041a565b8260051b604051601f19603f83011681018181108482111715620004d157620004d16200041a565b604052938452858101830193838101925087851115620004f057600080fd5b83870191505b848210156200051a576200050a826200045b565b83529183019190830190620004f6565b979650505050505050565b60008060008084860360a08112156200053d57600080fd5b60408112156200054c57600080fd5b506200055762000430565b855180151581146200056857600080fd5b815262000578602087016200045b565b602082015260408601519094506001600160401b03808211156200059b57600080fd5b620005a98883890162000478565b94506060870151915080821115620005c057600080fd5b50620005cf8782880162000478565b925050620005e0608086016200045b565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b6000600182016200062257634e487b7160e01b600052601160045260246000fd5b5060010190565b61171a80620006396000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c8063817ef62e116100b2578063a39b06e311610081578063c3f909d411610066578063c3f909d4146102f1578063cc7ebf4914610350578063f2fde38b1461035857600080fd5b8063a39b06e314610265578063a5e1d61d146102de57600080fd5b8063817ef62e1461020f57806382184c7b1461021757806389f9a2c41461022a5780638da5cb5b1461023d57600080fd5b80633908c4d4116101095780634e10a5b3116100ee5780634e10a5b3146101d15780636b14daf8146101e457806379ba50971461020757600080fd5b80633908c4d4146101a957806347663acb146101be57600080fd5b806301a059581461013b5780630a8c9c2414610161578063181f5a771461018157806320229a8614610196575b600080fd5b61014361036b565b60405167ffffffffffffffff90911681526020015b60405180910390f35b61017461016f3660046111bb565b61037c565b60405161015891906111ee565b6101896104d8565b6040516101589190611248565b6101746101a43660046111bb565b6104f4565b6101bc6101b73660046112d8565b61065a565b005b6101bc6101cc366004611339565b610905565b6101bc6101df3660046113d2565b610966565b6101f76101f236600461147f565b610b2f565b6040519015158152602001610158565b6101bc610b59565b610174610c5b565b6101bc610225366004611339565b610c67565b6101bc610238366004611510565b610ccd565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610158565b6102d061027336600461156d565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b604051908152602001610158565b6101f76102ec366004611339565b610d88565b60408051808201825260008082526020918201528151808301835260075460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff610100909204821692840192835284519081529151169181019190915201610158565b610143610da8565b6101bc610366366004611339565b610db4565b60006103776005610dc8565b905090565b60608167ffffffffffffffff168367ffffffffffffffff1611806103b357506103a56003610dc8565b8267ffffffffffffffff1610155b156103ea576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103f483836115c6565b6103ff9060016115e7565b67ffffffffffffffff1667ffffffffffffffff81111561042157610421611354565b60405190808252806020026020018201604052801561044a578160200160208202803683370190505b50905060005b61045a84846115c6565b67ffffffffffffffff1681116104d0576104896104818267ffffffffffffffff8716611608565b600390610dd2565b82828151811061049b5761049b61161b565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526104c98161164a565b9050610450565b505b92915050565b6040518060600160405280602c81526020016116e2602c913981565b60608167ffffffffffffffff168367ffffffffffffffff16118061052b575061051d6005610dc8565b8267ffffffffffffffff1610155b8061053d575061053b6005610dc8565b155b15610574576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61057e83836115c6565b6105899060016115e7565b67ffffffffffffffff1667ffffffffffffffff8111156105ab576105ab611354565b6040519080825280602002602001820160405280156105d4578160200160208202803683370190505b50905060005b6105e484846115c6565b67ffffffffffffffff1681116104d05761061361060b8267ffffffffffffffff8716611608565b600590610dd2565b8282815181106106255761062561161b565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526106538161164a565b90506105da565b610665600585610dde565b1561069c576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206007546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa1580156107d0573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614610827576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff861614158061086c57503373ffffffffffffffffffffffffffffffffffffffff87161480159061086c5750333b155b156108a3576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108ae600386610e0d565b156108fd5760405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a15b505050505050565b61090d610e2f565b610918600582610eb2565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b906020015b60405180910390a150565b61096e610e2f565b60025473ffffffffffffffffffffffffffffffffffffffff166109bd576040517fb25f406700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025473ffffffffffffffffffffffffffffffffffffffff1660005b8251811015610b2a578173ffffffffffffffffffffffffffffffffffffffff16636b14daf8848381518110610a1057610a1061161b565b6020908102919091010151604080517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260006044820152606401602060405180830381865afa158015610a91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab59190611682565b15610b1a57610ae7838281518110610acf57610acf61161b565b60200260200101516005610dde90919063ffffffff16565b610b1a57610b18838281518110610b0057610b0061161b565b60200260200101516003610e0d90919063ffffffff16565b505b610b238161164a565b90506109d9565b505050565b60075460009060ff16610b4457506001610b52565b610b4f600385610dde565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610bdf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606103776003610ed4565b610c6f610e2f565b610c7a600382610eb2565b50610c86600582610e0d565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e19060200161095b565b610cd5610e2f565b805160078054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910161095b565b60075460009060ff16610d9d57506000919050565b6104d2600583610dde565b60006103776003610dc8565b610dbc610e2f565b610dc581610ee1565b50565b60006104d2825490565b6000610b528383610fd6565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b52565b6000610b528373ffffffffffffffffffffffffffffffffffffffff8416611000565b60005473ffffffffffffffffffffffffffffffffffffffff163314610eb0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610bd6565b565b6000610b528373ffffffffffffffffffffffffffffffffffffffff841661104f565b60606000610b5283611142565b3373ffffffffffffffffffffffffffffffffffffffff821603610f60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610bd6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110610fed57610fed61161b565b9060005260206000200154905092915050565b6000818152600183016020526040812054611047575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104d2565b5060006104d2565b6000818152600183016020526040812054801561113857600061107360018361169f565b85549091506000906110879060019061169f565b90508181146110ec5760008660000182815481106110a7576110a761161b565b90600052602060002001549050808760000184815481106110ca576110ca61161b565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806110fd576110fd6116b2565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104d2565b60009150506104d2565b60608160000180548060200260200160405190810160405280929190818152602001828054801561119257602002820191906000526020600020905b81548152602001906001019080831161117e575b50505050509050919050565b803567ffffffffffffffff811681146111b657600080fd5b919050565b600080604083850312156111ce57600080fd5b6111d78361119e565b91506111e56020840161119e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561123c57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161120a565b50909695505050505050565b600060208083528351808285015260005b8181101561127557858101830151858201604001528201611259565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b657600080fd5b600080600080600060a086880312156112f057600080fd5b6112f9866112b4565b9450611307602087016112b4565b93506040860135925060608601359150608086013560ff8116811461132b57600080fd5b809150509295509295909350565b60006020828403121561134b57600080fd5b610b52826112b4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113ca576113ca611354565b604052919050565b600060208083850312156113e557600080fd5b823567ffffffffffffffff808211156113fd57600080fd5b818501915085601f83011261141157600080fd5b81358181111561142357611423611354565b8060051b9150611434848301611383565b818152918301840191848101908884111561144e57600080fd5b938501935b8385101561147357611464856112b4565b82529385019390850190611453565b98975050505050505050565b60008060006040848603121561149457600080fd5b61149d846112b4565b9250602084013567ffffffffffffffff808211156114ba57600080fd5b818601915086601f8301126114ce57600080fd5b8135818111156114dd57600080fd5b8760208285010111156114ef57600080fd5b6020830194508093505050509250925092565b8015158114610dc557600080fd5b60006040828403121561152257600080fd5b6040516040810181811067ffffffffffffffff8211171561154557611545611354565b604052823561155381611502565b8152611561602084016112b4565b60208201529392505050565b6000806040838503121561158057600080fd5b611589836112b4565b91506111e5602084016112b4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8281168282160390808211156104d0576104d0611597565b67ffffffffffffffff8181168382160190808211156104d0576104d0611597565b808201808211156104d2576104d2611597565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361167b5761167b611597565b5060010190565b60006020828403121561169457600080fd5b8151610b5281611502565b818103818111156104d2576104d2611597565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e31a164736f6c6343000813000a",
}
var TermsOfServiceAllowListABI = TermsOfServiceAllowListMetaData.ABI
var TermsOfServiceAllowListBin = TermsOfServiceAllowListMetaData.Bin
-func DeployTermsOfServiceAllowList(auth *bind.TransactOpts, backend bind.ContractBackend, config TermsOfServiceAllowListConfig, initialAllowedSenders []common.Address, initialBlockedSenders []common.Address) (common.Address, *types.Transaction, *TermsOfServiceAllowList, error) {
+func DeployTermsOfServiceAllowList(auth *bind.TransactOpts, backend bind.ContractBackend, config TermsOfServiceAllowListConfig, initialAllowedSenders []common.Address, initialBlockedSenders []common.Address, previousToSContract common.Address) (common.Address, *types.Transaction, *TermsOfServiceAllowList, error) {
parsed, err := TermsOfServiceAllowListMetaData.GetAbi()
if err != nil {
return common.Address{}, nil, nil, err
@@ -53,7 +53,7 @@ func DeployTermsOfServiceAllowList(auth *bind.TransactOpts, backend bind.Contrac
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
}
- address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TermsOfServiceAllowListBin), backend, config, initialAllowedSenders, initialBlockedSenders)
+ address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TermsOfServiceAllowListBin), backend, config, initialAllowedSenders, initialBlockedSenders, previousToSContract)
if err != nil {
return common.Address{}, nil, nil, err
}
@@ -454,6 +454,18 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorSession) BlockS
return _TermsOfServiceAllowList.Contract.BlockSender(&_TermsOfServiceAllowList.TransactOpts, sender)
}
+func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactor) MigratePreviouslyAllowedSenders(opts *bind.TransactOpts, previousSendersToAdd []common.Address) (*types.Transaction, error) {
+ return _TermsOfServiceAllowList.contract.Transact(opts, "migratePreviouslyAllowedSenders", previousSendersToAdd)
+}
+
+func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) MigratePreviouslyAllowedSenders(previousSendersToAdd []common.Address) (*types.Transaction, error) {
+ return _TermsOfServiceAllowList.Contract.MigratePreviouslyAllowedSenders(&_TermsOfServiceAllowList.TransactOpts, previousSendersToAdd)
+}
+
+func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorSession) MigratePreviouslyAllowedSenders(previousSendersToAdd []common.Address) (*types.Transaction, error) {
+ return _TermsOfServiceAllowList.Contract.MigratePreviouslyAllowedSenders(&_TermsOfServiceAllowList.TransactOpts, previousSendersToAdd)
+}
+
func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
return _TermsOfServiceAllowList.contract.Transact(opts, "transferOwnership", to)
}
@@ -1307,6 +1319,8 @@ type TermsOfServiceAllowListInterface interface {
BlockSender(opts *bind.TransactOpts, sender common.Address) (*types.Transaction, error)
+ MigratePreviouslyAllowedSenders(opts *bind.TransactOpts, previousSendersToAdd []common.Address) (*types.Transaction, error)
+
TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
UnblockSender(opts *bind.TransactOpts, sender common.Address) (*types.Transaction, error)
diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt
index 83ea4d13b6..5153e4055f 100644
--- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt
+++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt
@@ -1,6 +1,6 @@
GETH_VERSION: 1.13.8
functions: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.bin 3c972870b0afeb6d73a29ebb182f24956a2cebb127b21c4f867d1ecf19a762db
-functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin 268de8b3c061b53a1a2a1ccc0149eff68545959e29cd41b5f2e9f5dab19075cf
+functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin 6581a3e82c8a6b5532addb8278ff520d18f38c2be4ac07ed0ad9ccc2e6825e48
functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77
functions_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca
functions_client_example: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b
diff --git a/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go b/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go
index bb92001085..c345a86569 100644
--- a/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go
+++ b/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go
@@ -87,7 +87,7 @@ type CapabilitiesRegistryNodeParams struct {
var CapabilitiesRegistryMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityIsDeprecated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"CapabilityRequiredByDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"DONDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONNode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"nodeCount\",\"type\":\"uint256\"}],\"name\":\"InvalidFaultTolerance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"InvalidNodeCapabilities\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"InvalidNodeP2PId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotSupportCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfCapabilitiesDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfWorkflowDON\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilitiesRegistry.Capability[]\",\"name\":\"capabilities\",\"type\":\"tuple[]\"}],\"name\":\"addCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"addDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"addNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"deprecateCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityConfigs\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"getDON\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"getHashedCapabilityId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo\",\"name\":\"nodeInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodeOperators\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodes\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"donIds\",\"type\":\"uint32[]\"}],\"name\":\"removeDONs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"removedNodeP2PIds\",\"type\":\"bytes32[]\"}],\"name\":\"removeNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"updateDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"updateNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x6080604052600e80546001600160401b0319166401000000011790553480156200002857600080fd5b503380600081620000805760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000b357620000b381620000bc565b50505062000167565b336001600160a01b03821603620001165760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000077565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6150f680620001776000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80635e65e309116100ee5780638da5cb5b11610097578063d8bc7b6811610071578063d8bc7b68146103f6578063ddbe4f8214610409578063e29581aa1461041e578063f2fde38b1461043357600080fd5b80638da5cb5b1461039b5780639cb7c5f4146103c3578063d59a79f6146103e357600080fd5b806373ac22b4116100c857806373ac22b41461036d57806379ba50971461038057806386fa42461461038857600080fd5b80635e65e3091461033257806366acaa3314610345578063715f52951461035a57600080fd5b8063235374051161015b578063398f377311610135578063398f3773146102cb5780633f2a13c9146102de57806350c946fe146102ff5780635d83d9671461031f57600080fd5b80632353740514610285578063275459f2146102a55780632c01a1e8146102b857600080fd5b80631d05394c1161018c5780631d05394c1461023b578063214502431461025057806322bdbcbc1461026557600080fd5b80630fe5800a146101b357806312570011146101d9578063181f5a77146101fc575b600080fd5b6101c66101c1366004613e8b565b610446565b6040519081526020015b60405180910390f35b6101ec6101e7366004613eef565b61047a565b60405190151581526020016101d0565b604080518082018252601a81527f4361706162696c6974696573526567697374727920312e302e30000000000000602082015290516101d09190613f76565b61024e610249366004613fce565b610487565b005b61025861069c565b6040516101d09190614150565b6102786102733660046141eb565b6107f9565b6040516101d09190614243565b6102986102933660046141eb565b6108e6565b6040516101d09190614256565b61024e6102b3366004613fce565b61092a565b61024e6102c6366004613fce565b610a01565b61024e6102d9366004613fce565b610c9d565b6102f16102ec366004614269565b610e5c565b6040516101d0929190614293565b61031261030d366004613eef565b611048565b6040516101d09190614358565b61024e61032d366004613fce565b611122565b61024e610340366004613fce565b611217565b61034d61193f565b6040516101d0919061436b565b61024e610368366004613fce565b611b22565b61024e61037b366004613fce565b611bd4565b61024e6120a2565b61024e6103963660046143e0565b61219f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d0565b6103d66103d1366004613eef565b6124df565b6040516101d0919061452f565b61024e6103f1366004614561565b61271a565b61024e610404366004614616565b6127e3565b6104116128ad565b6040516101d091906146bb565b6104266129a1565b6040516101d09190614730565b61024e6104413660046147c9565b612aaa565b6000828260405160200161045b929190614293565b6040516020818303038152906040528051906020012090505b92915050565b6000610474600583612abe565b61048f612ad9565b60005b818110156106975760008383838181106104ae576104ae6147e4565b90506020020160208101906104c391906141eb565b63ffffffff8181166000908152600d60209081526040808320805464010000000081049095168085526001820190935290832094955093909290916a010000000000000000000090910460ff16905b61051b83612b5c565b8110156105bb57811561057157600c60006105368584612b66565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556105b3565b6105b18663ffffffff16600c60006105928588612b6690919063ffffffff16565b8152602001908152602001600020600401612b7290919063ffffffff16565b505b600101610512565b508354640100000000900463ffffffff16600003610612576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024015b60405180910390fd5b63ffffffff85166000818152600d6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffff00000000000000000000001690558051938452908301919091527ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a15050505050806001019050610492565b505050565b600e54606090640100000000900463ffffffff1660006106bd600183614842565b63ffffffff1667ffffffffffffffff8111156106db576106db613d25565b60405190808252806020026020018201604052801561076257816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816106f95790505b509050600060015b8363ffffffff168163ffffffff1610156107d65763ffffffff8082166000908152600d602052604090205416156107ce576107a481612b7e565b8383815181106107b6576107b66147e4565b6020026020010181905250816107cb9061485f565b91505b60010161076a565b506107e2600184614842565b63ffffffff1681146107f2578082525b5092915050565b60408051808201909152600081526060602082015263ffffffff82166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161085d90614897565b80601f016020809104026020016040519081016040528092919081815260200182805461088990614897565b80156108d65780601f106108ab576101008083540402835291602001916108d6565b820191906000526020600020905b8154815290600101906020018083116108b957829003601f168201915b5050505050815250509050919050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c081019190915261047482612b7e565b610932612ad9565b60005b63ffffffff811682111561069757600083838363ffffffff1681811061095d5761095d6147e4565b905060200201602081019061097291906141eb565b63ffffffff81166000908152600b6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559192506109bd6001830182613cb8565b505060405163ffffffff8216907fa59268ca81d40429e65ccea5385b59cf2d3fc6519371dee92f8eb1dae5107a7a90600090a2506109fa816148ea565b9050610935565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110610a3b57610a3b6147e4565b602090810292909201356000818152600c90935260409092206001810154929350919050610a98576040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260048101839052602401610609565b6000610aa682600401612b5c565b1115610afb57610ab96004820184612b66565b6040517f60a6d89800000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101839052604401610609565b805468010000000000000000900463ffffffff1615610b635780546040517f60b9df730000000000000000000000000000000000000000000000000000000081526801000000000000000090910463ffffffff16600482015260248101839052604401610609565b83158015610b9d5750805463ffffffff166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15610bd6576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6001810154610be790600790612b72565b506002810154610bf990600990612b72565b506000828152600c6020526040812080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101829055600281018290559060048201818181610c4e8282613cf2565b5050505050507f5254e609a97bab37b7cc79fe128f85c097bd6015c6e1624ae0ba392eb975320582604051610c8591815260200190565b60405180910390a15050600101610a1f565b50505050565b610ca5612ad9565b60005b81811015610697576000838383818110610cc457610cc46147e4565b9050602002810190610cd6919061490d565b610cdf9061494b565b805190915073ffffffffffffffffffffffffffffffffffffffff16610d30576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815263ffffffff9095166000818152600b909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251919290916001820190610dbc9082614a05565b5050600e8054909150600090610dd79063ffffffff166148ea565b91906101000a81548163ffffffff021916908363ffffffff160217905550816000015173ffffffffffffffffffffffffffffffffffffffff168163ffffffff167f78e94ca80be2c30abc061b99e7eb8583b1254781734b1e3ce339abb57da2fe8e8460200151604051610e4a9190613f76565b60405180910390a35050600101610ca8565b63ffffffff8083166000908152600d60209081526040808320805464010000000090049094168084526001909401825280832085845260030190915281208054606093849390929091610eae90614897565b80601f0160208091040260200160405190810160405280929190818152602001828054610eda90614897565b8015610f275780601f10610efc57610100808354040283529160200191610f27565b820191906000526020600020905b815481529060010190602001808311610f0a57829003601f168201915b5050506000888152600260208190526040909120015492935060609262010000900473ffffffffffffffffffffffffffffffffffffffff1615915061103a905057600086815260026020819052604091829020015490517f8318ed5d00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526201000090910473ffffffffffffffffffffffffffffffffffffffff1690638318ed5d90602401600060405180830381865afa158015610ff1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110379190810190614b1f565b90505b9093509150505b9250929050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c08101919091526040805160e0810182526000848152600c6020908152838220805463ffffffff8082168652640100000000820481168487018190526801000000000000000090920416858701526001820154606086015260028201546080860152835260030190529190912060a08201906110f790612e49565b815260200161111a600c6000868152602001908152602001600020600401612e49565b905292915050565b61112a612ad9565b60005b81811015610697576000838383818110611149576111496147e4565b905060200201359050611166816003612abe90919063ffffffff16565b61119f576040517fe181733f00000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b6111aa600582612e56565b6111e3576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b60405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a25060010161112d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110611251576112516147e4565b90506020028101906112639190614b8d565b61126c90614bc1565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff1682526001810180549596509394919390928401916112c290614897565b80601f01602080910402602001604051908101604052809291908181526020018280546112ee90614897565b801561133b5780601f106113105761010080835404028352916020019161133b565b820191906000526020600020905b81548152906001019060200180831161131e57829003601f168201915b50505050508152505090508315801561136b5750805173ffffffffffffffffffffffffffffffffffffffff163314155b156113a4576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c6020522060018101546113f85782604001516040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6020830151611433576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001810154602084015181146114b457602084015161145490600790612abe565b1561148b576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084015160018301556114a0600782612b72565b5060208401516114b290600790612e56565b505b606084015180516000036114f657806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b8254600090849060049061151790640100000000900463ffffffff166148ea565b91906101000a81548163ffffffff021916908363ffffffff1602179055905060005b82518110156115fc5761156f838281518110611557576115576147e4565b60200260200101516003612abe90919063ffffffff16565b6115a757826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b6115f38382815181106115bc576115bc6147e4565b60200260200101518660030160008563ffffffff1663ffffffff168152602001908152602001600020612e5690919063ffffffff16565b50600101611539565b50835468010000000000000000900463ffffffff16801561175d5763ffffffff8082166000908152600d60209081526040808320805464010000000090049094168352600190930181528282206002018054845181840281018401909552808552929392909183018282801561169157602002820191906000526020600020905b81548152602001906001019080831161167d575b5050505050905060005b815181101561175a576116f08282815181106116b9576116b96147e4565b60200260200101518860030160008763ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b61175257818181518110611706576117066147e4565b6020026020010151836040517f03dcd86200000000000000000000000000000000000000000000000000000000815260040161060992919091825263ffffffff16602082015260400190565b60010161169b565b50505b600061176b86600401612e49565b905060005b81518163ffffffff1610156118b1576000828263ffffffff1681518110611799576117996147e4565b60209081029190910181015163ffffffff8082166000908152600d8452604080822080546401000000009004909316825260019092018452818120600201805483518187028101870190945280845293955090939192909183018282801561182057602002820191906000526020600020905b81548152602001906001019080831161180c575b5050505050905060005b815181101561189d5761187f828281518110611848576118486147e4565b60200260200101518b60030160008a63ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b61189557818181518110611706576117066147e4565b60010161182a565b505050806118aa906148ea565b9050611770565b50875186547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90911690811787556040808a0151600289018190556020808c01518351928352908201527f4b5b465e22eea0c3d40c30e936643245b80d19b2dcf75788c0699fe8d8db645b910160405180910390a25050505050505050806001019050611235565b600e5460609063ffffffff166000611958600183614842565b63ffffffff1667ffffffffffffffff81111561197657611976613d25565b6040519080825280602002602001820160405280156119bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816119945790505b509050600060015b8363ffffffff168163ffffffff161015611b0c5763ffffffff81166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611b045763ffffffff81166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191611a5890614897565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8490614897565b8015611ad15780601f10611aa657610100808354040283529160200191611ad1565b820191906000526020600020905b815481529060010190602001808311611ab457829003601f168201915b505050505081525050838381518110611aec57611aec6147e4565b602002602001018190525081611b019061485f565b91505b6001016119c4565b50600e546107e29060019063ffffffff16614842565b611b2a612ad9565b60005b81811015610697576000838383818110611b4957611b496147e4565b9050602002810190611b5b9190614cd8565b611b6490614d1b565b90506000611b7a82600001518360200151610446565b9050611b87600382612e56565b611bc0576040517febf5255100000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b611bca8183612e62565b5050600101611b2d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110611c0e57611c0e6147e4565b9050602002810190611c209190614b8d565b611c2990614bc1565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191611c7f90614897565b80601f0160208091040260200160405190810160405280929190818152602001828054611cab90614897565b8015611cf85780601f10611ccd57610100808354040283529160200191611cf8565b820191906000526020600020905b815481529060010190602001808311611cdb57829003601f168201915b50505091909252505081519192505073ffffffffffffffffffffffffffffffffffffffff16611d5e5781516040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff9091166004820152602401610609565b83158015611d835750805173ffffffffffffffffffffffffffffffffffffffff163314155b15611dbc576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c60205220600181015415611e115782604001516040517f5461848300000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6040830151611e545782604001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b60208301511580611e7157506020830151611e7190600790612abe565b15611ea8576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608301518051600003611eea57806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b81548290600490611f0890640100000000900463ffffffff166148ea565b82546101009290920a63ffffffff818102199093169183160217909155825464010000000090041660005b8251811015611fde57611f51838281518110611557576115576147e4565b611f8957826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b611fd5838281518110611f9e57611f9e6147e4565b60200260200101518560030160008563ffffffff1663ffffffff168152602001908152602001600020612e5690919063ffffffff16565b50600101611f33565b50845183547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff918216178455604086015160028501556020860151600185018190556120349160079190612e5616565b50604085015161204690600990612e56565b50845160408087015160208089015183519283529082015263ffffffff909216917f74becb12a5e8fd0e98077d02dfba8f647c9670c9df177e42c2418cf17a636f05910160405180910390a25050505050806001019050611bf2565b60015473ffffffffffffffffffffffffffffffffffffffff163314612123576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610609565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b8281146121e2576040517fab8b67c60000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610609565b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156124d757600086868381811061221a5761221a6147e4565b905060200201602081019061222f91906141eb565b63ffffffff81166000908152600b6020526040902080549192509073ffffffffffffffffffffffffffffffffffffffff1661229e576040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602401610609565b60008686858181106122b2576122b26147e4565b90506020028101906122c4919061490d565b6122cd9061494b565b805190915073ffffffffffffffffffffffffffffffffffffffff1661231e576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16331480159061235b57503373ffffffffffffffffffffffffffffffffffffffff861614155b15612394576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b8051825473ffffffffffffffffffffffffffffffffffffffff908116911614158061241057506020808201516040516123cd9201613f76565b60405160208183030381529060405280519060200120826001016040516020016123f79190614dc1565b6040516020818303038152906040528051906020012014155b156124c957805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020810151600183019061246a9082614a05565b50806000015173ffffffffffffffffffffffffffffffffffffffff168363ffffffff167f86f41145bde5dd7f523305452e4aad3685508c181432ec733d5f345009358a2883602001516040516124c09190613f76565b60405180910390a35b5050508060010190506121fe565b505050505050565b6125206040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b6040805160e0810182528381526000848152600260209081529290208054919283019161254c90614897565b80601f016020809104026020016040519081016040528092919081815260200182805461257890614897565b80156125c55780601f1061259a576101008083540402835291602001916125c5565b820191906000526020600020905b8154815290600101906020018083116125a857829003601f168201915b505050505081526020016002600085815260200190815260200160002060010180546125f090614897565b80601f016020809104026020016040519081016040528092919081815260200182805461261c90614897565b80156126695780601f1061263e57610100808354040283529160200191612669565b820191906000526020600020905b81548152906001019060200180831161264c57829003601f168201915b50505091835250506000848152600260208181526040909220015491019060ff16600381111561269b5761269b61444c565b815260008481526002602081815260409092200154910190610100900460ff1660018111156126cc576126cc61444c565b81526000848152600260208181526040928390209091015462010000900473ffffffffffffffffffffffffffffffffffffffff169083015201612710600585612abe565b1515905292915050565b612722612ad9565b63ffffffff8089166000908152600d6020526040812054640100000000900490911690819003612786576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff8a166004820152602401610609565b6127d8888888886040518060a001604052808f63ffffffff168152602001876127ae906148ea565b97508763ffffffff1681526020018a1515815260200189151581526020018860ff168152506130f6565b505050505050505050565b6127eb612ad9565b600e805460009164010000000090910463ffffffff1690600461280d836148ea565b82546101009290920a63ffffffff81810219909316918316021790915581166000818152600d602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001684179055815160a08101835292835260019083015286151590820152841515606082015260ff841660808201529091506128a39089908990899089906130f6565b5050505050505050565b606060006128bb6003612e49565b90506000815167ffffffffffffffff8111156128d9576128d9613d25565b60405190808252806020026020018201604052801561294b57816020015b6129386040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b8152602001906001900390816128f75790505b50905060005b82518110156107f25761297c83828151811061296f5761296f6147e4565b60200260200101516124df565b82828151811061298e5761298e6147e4565b6020908102919091010152600101612951565b606060006129af6009612e49565b90506000815167ffffffffffffffff8111156129cd576129cd613d25565b604051908082528060200260200182016040528015612a5457816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816129eb5790505b50905060005b82518110156107f257612a85838281518110612a7857612a786147e4565b6020026020010151611048565b828281518110612a9757612a976147e4565b6020908102919091010152600101612a5a565b612ab2612ad9565b612abb8161391a565b50565b600081815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610609565b565b6000610474825490565b6000612ad28383613a0f565b6000612ad28383613a39565b6040805160e0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840181905260c084015263ffffffff8581168352600d8252848320805464010000000090049091168084526001909101825284832060028101805487518186028101860190985280885295969295919493909190830182828015612c2f57602002820191906000526020600020905b815481526020019060010190808311612c1b575b505050505090506000815167ffffffffffffffff811115612c5257612c52613d25565b604051908082528060200260200182016040528015612c9857816020015b604080518082019091526000815260606020820152815260200190600190039081612c705790505b50905060005b8151811015612db0576040518060400160405280848381518110612cc457612cc46147e4565b60200260200101518152602001856003016000868581518110612ce957612ce96147e4565b602002602001015181526020019081526020016000208054612d0a90614897565b80601f0160208091040260200160405190810160405280929190818152602001828054612d3690614897565b8015612d835780601f10612d5857610100808354040283529160200191612d83565b820191906000526020600020905b815481529060010190602001808311612d6657829003601f168201915b5050505050815250828281518110612d9d57612d9d6147e4565b6020908102919091010152600101612c9e565b506040805160e08101825263ffffffff8089166000818152600d6020818152868320548086168752948b168187015260ff680100000000000000008604811697870197909752690100000000000000000085048716151560608701529290915290526a010000000000000000000090049091161515608082015260a08101612e3785612e49565b81526020019190915295945050505050565b60606000612ad283613b2c565b6000612ad28383613b88565b608081015173ffffffffffffffffffffffffffffffffffffffff1615612fb057608081015173ffffffffffffffffffffffffffffffffffffffff163b1580612f5b575060808101516040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f78bea72100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff909116906301ffc9a790602401602060405180830381865afa158015612f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f599190614e6f565b155b15612fb05760808101516040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610609565b600082815260026020526040902081518291908190612fcf9082614a05565b5060208201516001820190612fe49082614a05565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156130265761302661444c565b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010083600181111561306d5761306d61444c565b0217905550608091909101516002909101805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff90921691909117905560405182907f04f0a9bcf3f3a3b42a4d7ca081119755f82ebe43e0d30c8f7292c4fe0dc4a2ae90600090a25050565b805163ffffffff9081166000908152600d602090815260408083208286015190941683526001909301905220608082015160ff161580613148575060808201518590613143906001614e8c565b60ff16115b156131915760808201516040517f25b4d61800000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101869052604401610609565b6001826020015163ffffffff16111561327957815163ffffffff166000908152600d6020908152604082209084015160019182019183916131d29190614842565b63ffffffff1663ffffffff168152602001908152602001600020905060005b6131fa82612b5c565b81101561327657613229846000015163ffffffff16600c60006105928587600001612b6690919063ffffffff16565b50600c60006132388484612b66565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556001016131f1565b50505b60005b858110156134b3576132a9878783818110613299576132996147e4565b8592602090910201359050612e56565b61330a5782518787838181106132c1576132c16147e4565b6040517f636e405700000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b82606001511561346157825163ffffffff16600c6000898985818110613332576133326147e4565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff16148015906133ac5750600c600088888481811061337d5761337d6147e4565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff1615155b1561340e5782518787838181106133c5576133c56147e4565b6040517f60b9df7300000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8251600c6000898985818110613426576134266147e4565b90506020020135815260200190815260200160002060000160086101000a81548163ffffffff021916908363ffffffff1602179055506134ab565b82516134a99063ffffffff16600c60008a8a86818110613483576134836147e4565b905060200201358152602001908152602001600020600401612e5690919063ffffffff16565b505b60010161327c565b5060005b8381101561378f57368585838181106134d2576134d26147e4565b90506020028101906134e4919061490d565b90506134f260038235612abe565b61352b576040517fe181733f00000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b61353760058235612abe565b15613571576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b803560009081526003840160205260408120805461358e90614897565b905011156135da5783516040517f3927d08000000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015281356024820152604401610609565b60005b878110156136e4576136818235600c60008c8c86818110613600576136006147e4565b9050602002013581526020019081526020016000206003016000600c60008e8e88818110613630576136306147e4565b90506020020135815260200190815260200160002060000160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b6136dc57888882818110613697576136976147e4565b6040517fa7e792500000000000000000000000000000000000000000000000000000000081526020909102929092013560048301525082356024820152604401610609565b6001016135dd565b506002830180546001810182556000918252602091829020833591015561370d90820182614ea5565b8235600090815260038601602052604090209161372b919083614f0a565b50835160208086015161378692918435908c908c9061374c90880188614ea5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613bd792505050565b506001016134b7565b50604080830151835163ffffffff9081166000908152600d602090815284822080549415156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff90951694909417909355606086015186518316825284822080549115156a0100000000000000000000027fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff9092169190911790556080860151865183168252848220805460ff9290921668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff909216919091179055918501805186518316845292849020805493909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9093169290921790558351905191517ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c15817036519261390a929163ffffffff92831681529116602082015260400190565b60405180910390a1505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613999576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610609565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613a2657613a266147e4565b9060005260206000200154905092915050565b60008181526001830160205260408120548015613b22576000613a5d600183615025565b8554909150600090613a7190600190615025565b9050818114613ad6576000866000018281548110613a9157613a916147e4565b9060005260206000200154905080876000018481548110613ab457613ab46147e4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613ae757613ae7615038565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610474565b6000915050610474565b606081600001805480602002602001604051908101604052809291908181526020018280548015613b7c57602002820191906000526020600020905b815481526020019060010190808311613b68575b50505050509050919050565b6000818152600183016020526040812054613bcf57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610474565b506000610474565b6000848152600260208190526040909120015462010000900473ffffffffffffffffffffffffffffffffffffffff16156124d757600084815260026020819052604091829020015490517ffba64a7c0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169063fba64a7c90613c7e908690869086908b908d90600401615067565b600060405180830381600087803b158015613c9857600080fd5b505af1158015613cac573d6000803e3d6000fd5b50505050505050505050565b508054613cc490614897565b6000825580601f10613cd4575050565b601f016020900490600052602060002090810190612abb9190613d0c565b5080546000825590600052602060002090810190612abb91905b5b80821115613d215760008155600101613d0d565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613d7757613d77613d25565b60405290565b60405160a0810167ffffffffffffffff81118282101715613d7757613d77613d25565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613de757613de7613d25565b604052919050565b600067ffffffffffffffff821115613e0957613e09613d25565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e4657600080fd5b8135613e59613e5482613def565b613da0565b818152846020838601011115613e6e57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613e9e57600080fd5b823567ffffffffffffffff80821115613eb657600080fd5b613ec286838701613e35565b93506020850135915080821115613ed857600080fd5b50613ee585828601613e35565b9150509250929050565b600060208284031215613f0157600080fd5b5035919050565b60005b83811015613f23578181015183820152602001613f0b565b50506000910152565b60008151808452613f44816020860160208601613f08565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612ad26020830184613f2c565b60008083601f840112613f9b57600080fd5b50813567ffffffffffffffff811115613fb357600080fd5b6020830191508360208260051b850101111561104157600080fd5b60008060208385031215613fe157600080fd5b823567ffffffffffffffff811115613ff857600080fd5b61400485828601613f89565b90969095509350505050565b60008151808452602080850194506020840160005b8381101561404157815187529582019590820190600101614025565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b848110156140c9578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051845284015160408585018190526140b581860183613f2c565b9a86019a9450505090830190600101614069565b5090979650505050505050565b600063ffffffff8083511684528060208401511660208501525060ff604083015116604084015260608201511515606084015260808201511515608084015260a082015160e060a085015261412e60e0850182614010565b905060c083015184820360c0860152614147828261404c565b95945050505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526141b38583516140d6565b94509285019290850190600101614179565b5092979650505050505050565b803563ffffffff811681146141e657600080fd5b919050565b6000602082840312156141fd57600080fd5b612ad2826141d2565b73ffffffffffffffffffffffffffffffffffffffff8151168252600060208201516040602085015261423b6040850182613f2c565b949350505050565b602081526000612ad26020830184614206565b602081526000612ad260208301846140d6565b6000806040838503121561427c57600080fd5b614285836141d2565b946020939093013593505050565b6040815260006142a66040830185613f2c565b82810360208401526141478185613f2c565b600063ffffffff808351168452602081818501511681860152816040850151166040860152606084015160608601526080840151608086015260a0840151915060e060a086015261430c60e0860183614010565b60c08581015187830391880191909152805180835290830193506000918301905b8083101561434d578451825293830193600192909201919083019061432d565b509695505050505050565b602081526000612ad260208301846142b8565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526143ce858351614206565b94509285019290850190600101614394565b600080600080604085870312156143f657600080fd5b843567ffffffffffffffff8082111561440e57600080fd5b61441a88838901613f89565b9096509450602087013591508082111561443357600080fd5b5061444087828801613f89565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b805182526000602082015160e0602085015261449a60e0850182613f2c565b9050604083015184820360408601526144b38282613f2c565b9150506060830151600481106144cb576144cb61444c565b60608501526080830151600281106144e5576144e561444c565b8060808601525060a083015161451360a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015161452760c086018215159052565b509392505050565b602081526000612ad2602083018461447b565b8015158114612abb57600080fd5b803560ff811681146141e657600080fd5b60008060008060008060008060c0898b03121561457d57600080fd5b614586896141d2565b9750602089013567ffffffffffffffff808211156145a357600080fd5b6145af8c838d01613f89565b909950975060408b01359150808211156145c857600080fd5b506145d58b828c01613f89565b90965094505060608901356145e981614542565b925060808901356145f981614542565b915061460760a08a01614550565b90509295985092959890939650565b600080600080600080600060a0888a03121561463157600080fd5b873567ffffffffffffffff8082111561464957600080fd5b6146558b838c01613f89565b909950975060208a013591508082111561466e57600080fd5b5061467b8a828b01613f89565b909650945050604088013561468f81614542565b9250606088013561469f81614542565b91506146ad60808901614550565b905092959891949750929550565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261471e85835161447b565b945092850192908501906001016146e4565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526147938583516142b8565b94509285019290850190600101614759565b803573ffffffffffffffffffffffffffffffffffffffff811681146141e657600080fd5b6000602082840312156147db57600080fd5b612ad2826147a5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8281168282160390808211156107f2576107f2614813565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361489057614890614813565b5060010190565b600181811c908216806148ab57607f821691505b6020821081036148e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600063ffffffff80831681810361490357614903614813565b6001019392505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261494157600080fd5b9190910192915050565b60006040823603121561495d57600080fd5b6040516040810167ffffffffffffffff828210818311171561498157614981613d25565b8160405261498e856147a5565b835260208501359150808211156149a457600080fd5b506149b136828601613e35565b60208301525092915050565b601f821115610697576000816000526020600020601f850160051c810160208610156149e65750805b601f850160051c820191505b818110156124d7578281556001016149f2565b815167ffffffffffffffff811115614a1f57614a1f613d25565b614a3381614a2d8454614897565b846149bd565b602080601f831160018114614a865760008415614a505750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556124d7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614ad357888601518255948401946001909101908401614ab4565b5085821015614b0f57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215614b3157600080fd5b815167ffffffffffffffff811115614b4857600080fd5b8201601f81018413614b5957600080fd5b8051614b67613e5482613def565b818152856020838501011115614b7c57600080fd5b614147826020830160208601613f08565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261494157600080fd5b600060808236031215614bd357600080fd5b614bdb613d54565b614be4836141d2565b81526020808401358183015260408401356040830152606084013567ffffffffffffffff80821115614c1557600080fd5b9085019036601f830112614c2857600080fd5b813581811115614c3a57614c3a613d25565b8060051b9150614c4b848301613da0565b8181529183018401918481019036841115614c6557600080fd5b938501935b83851015614c8357843582529385019390850190614c6a565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614ccc57835183529284019291840191600101614cb0565b50909695505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261494157600080fd5b8035600281106141e657600080fd5b600060a08236031215614d2d57600080fd5b614d35613d7d565b823567ffffffffffffffff80821115614d4d57600080fd5b614d5936838701613e35565b83526020850135915080821115614d6f57600080fd5b50614d7c36828601613e35565b602083015250604083013560048110614d9457600080fd5b6040820152614da560608401614d0c565b6060820152614db6608084016147a5565b608082015292915050565b6000602080835260008454614dd581614897565b8060208701526040600180841660008114614df75760018114614e3157614e61565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550614e61565b89600052602060002060005b85811015614e585781548b8201860152908301908801614e3d565b8a016040019650505b509398975050505050505050565b600060208284031215614e8157600080fd5b8151612ad281614542565b60ff818116838216019081111561047457610474614813565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614eda57600080fd5b83018035915067ffffffffffffffff821115614ef557600080fd5b60200191503681900382131561104157600080fd5b67ffffffffffffffff831115614f2257614f22613d25565b614f3683614f308354614897565b836149bd565b6000601f841160018114614f885760008515614f525750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561501e565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614fd75786850135825560209485019460019092019101614fb7565b5086821015615012577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8181038181111561047457610474614813565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6080815284608082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8611156150a057600080fd5b8560051b808860a0850137820182810360a090810160208501526150c690820187613f2c565b91505063ffffffff8085166040840152808416606084015250969550505050505056fea164736f6c6343000818000a",
+ Bin: "0x6080604052600e80546001600160401b0319166401000000011790553480156200002857600080fd5b503380600081620000805760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000b357620000b381620000bc565b50505062000167565b336001600160a01b03821603620001165760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000077565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6150f680620001776000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80635e65e309116100ee5780638da5cb5b11610097578063d8bc7b6811610071578063d8bc7b68146103f6578063ddbe4f8214610409578063e29581aa1461041e578063f2fde38b1461043357600080fd5b80638da5cb5b1461039b5780639cb7c5f4146103c3578063d59a79f6146103e357600080fd5b806373ac22b4116100c857806373ac22b41461036d57806379ba50971461038057806386fa42461461038857600080fd5b80635e65e3091461033257806366acaa3314610345578063715f52951461035a57600080fd5b8063235374051161015b578063398f377311610135578063398f3773146102cb5780633f2a13c9146102de57806350c946fe146102ff5780635d83d9671461031f57600080fd5b80632353740514610285578063275459f2146102a55780632c01a1e8146102b857600080fd5b80631d05394c1161018c5780631d05394c1461023b578063214502431461025057806322bdbcbc1461026557600080fd5b80630fe5800a146101b357806312570011146101d9578063181f5a77146101fc575b600080fd5b6101c66101c1366004613e8b565b610446565b6040519081526020015b60405180910390f35b6101ec6101e7366004613eef565b61047a565b60405190151581526020016101d0565b604080518082018252601a81527f4361706162696c6974696573526567697374727920312e302e30000000000000602082015290516101d09190613f76565b61024e610249366004613fce565b610487565b005b61025861069c565b6040516101d09190614150565b6102786102733660046141eb565b6107f9565b6040516101d09190614243565b6102986102933660046141eb565b6108e6565b6040516101d09190614256565b61024e6102b3366004613fce565b61092a565b61024e6102c6366004613fce565b610a01565b61024e6102d9366004613fce565b610c9d565b6102f16102ec366004614269565b610e5c565b6040516101d0929190614293565b61031261030d366004613eef565b611048565b6040516101d09190614358565b61024e61032d366004613fce565b611122565b61024e610340366004613fce565b611217565b61034d61193f565b6040516101d0919061436b565b61024e610368366004613fce565b611b22565b61024e61037b366004613fce565b611bd4565b61024e6120a2565b61024e6103963660046143e0565b61219f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d0565b6103d66103d1366004613eef565b6124df565b6040516101d0919061452f565b61024e6103f1366004614561565b61271a565b61024e610404366004614616565b6127e3565b6104116128ad565b6040516101d091906146bb565b6104266129a1565b6040516101d09190614730565b61024e6104413660046147c9565b612aaa565b6000828260405160200161045b929190614293565b6040516020818303038152906040528051906020012090505b92915050565b6000610474600583612abe565b61048f612ad9565b60005b818110156106975760008383838181106104ae576104ae6147e4565b90506020020160208101906104c391906141eb565b63ffffffff8181166000908152600d60209081526040808320805464010000000081049095168085526001820190935290832094955093909290916a010000000000000000000090910460ff16905b61051b83612b5c565b8110156105bb57811561057157600c60006105368584612b66565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556105b3565b6105b18663ffffffff16600c60006105928588612b6690919063ffffffff16565b8152602001908152602001600020600401612b7290919063ffffffff16565b505b600101610512565b508354640100000000900463ffffffff16600003610612576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024015b60405180910390fd5b63ffffffff85166000818152600d6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffff00000000000000000000001690558051938452908301919091527ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a15050505050806001019050610492565b505050565b600e54606090640100000000900463ffffffff1660006106bd600183614842565b63ffffffff1667ffffffffffffffff8111156106db576106db613d25565b60405190808252806020026020018201604052801561076257816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816106f95790505b509050600060015b8363ffffffff168163ffffffff1610156107d65763ffffffff8082166000908152600d602052604090205416156107ce576107a481612b7e565b8383815181106107b6576107b66147e4565b6020026020010181905250816107cb9061485f565b91505b60010161076a565b506107e2600184614842565b63ffffffff1681146107f2578082525b5092915050565b60408051808201909152600081526060602082015263ffffffff82166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161085d90614897565b80601f016020809104026020016040519081016040528092919081815260200182805461088990614897565b80156108d65780601f106108ab576101008083540402835291602001916108d6565b820191906000526020600020905b8154815290600101906020018083116108b957829003601f168201915b5050505050815250509050919050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c081019190915261047482612b7e565b610932612ad9565b60005b63ffffffff811682111561069757600083838363ffffffff1681811061095d5761095d6147e4565b905060200201602081019061097291906141eb565b63ffffffff81166000908152600b6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559192506109bd6001830182613cb8565b505060405163ffffffff8216907fa59268ca81d40429e65ccea5385b59cf2d3fc6519371dee92f8eb1dae5107a7a90600090a2506109fa816148ea565b9050610935565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110610a3b57610a3b6147e4565b602090810292909201356000818152600c90935260409092206001810154929350919050610a98576040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260048101839052602401610609565b6000610aa682600401612b5c565b1115610afb57610ab96004820184612b66565b6040517f60a6d89800000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101839052604401610609565b805468010000000000000000900463ffffffff1615610b635780546040517f60b9df730000000000000000000000000000000000000000000000000000000081526801000000000000000090910463ffffffff16600482015260248101839052604401610609565b83158015610b9d5750805463ffffffff166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15610bd6576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6001810154610be790600790612b72565b506002810154610bf990600990612b72565b506000828152600c6020526040812080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101829055600281018290559060048201818181610c4e8282613cf2565b5050505050507f5254e609a97bab37b7cc79fe128f85c097bd6015c6e1624ae0ba392eb975320582604051610c8591815260200190565b60405180910390a15050600101610a1f565b50505050565b610ca5612ad9565b60005b81811015610697576000838383818110610cc457610cc46147e4565b9050602002810190610cd6919061490d565b610cdf9061494b565b805190915073ffffffffffffffffffffffffffffffffffffffff16610d30576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815263ffffffff9095166000818152600b909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251919290916001820190610dbc9082614a05565b5050600e8054909150600090610dd79063ffffffff166148ea565b91906101000a81548163ffffffff021916908363ffffffff160217905550816000015173ffffffffffffffffffffffffffffffffffffffff168163ffffffff167f78e94ca80be2c30abc061b99e7eb8583b1254781734b1e3ce339abb57da2fe8e8460200151604051610e4a9190613f76565b60405180910390a35050600101610ca8565b63ffffffff8083166000908152600d60209081526040808320805464010000000090049094168084526001909401825280832085845260030190915281208054606093849390929091610eae90614897565b80601f0160208091040260200160405190810160405280929190818152602001828054610eda90614897565b8015610f275780601f10610efc57610100808354040283529160200191610f27565b820191906000526020600020905b815481529060010190602001808311610f0a57829003601f168201915b5050506000888152600260208190526040909120015492935060609262010000900473ffffffffffffffffffffffffffffffffffffffff1615915061103a905057600086815260026020819052604091829020015490517f8318ed5d00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526201000090910473ffffffffffffffffffffffffffffffffffffffff1690638318ed5d90602401600060405180830381865afa158015610ff1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110379190810190614b1f565b90505b9093509150505b9250929050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c08101919091526040805160e0810182526000848152600c6020908152838220805463ffffffff8082168652640100000000820481168487018190526801000000000000000090920416858701526001820154606086015260028201546080860152835260030190529190912060a08201906110f790612e49565b815260200161111a600c6000868152602001908152602001600020600401612e49565b905292915050565b61112a612ad9565b60005b81811015610697576000838383818110611149576111496147e4565b905060200201359050611166816003612abe90919063ffffffff16565b61119f576040517fe181733f00000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b6111aa600582612e56565b6111e3576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b60405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a25060010161112d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110611251576112516147e4565b90506020028101906112639190614b8d565b61126c90614bc1565b6040808201516000908152600c6020908152828220805463ffffffff168352600b82528383208451808601909552805473ffffffffffffffffffffffffffffffffffffffff16855260018101805496975091959394939092840191906112d190614897565b80601f01602080910402602001604051908101604052809291908181526020018280546112fd90614897565b801561134a5780601f1061131f5761010080835404028352916020019161134a565b820191906000526020600020905b81548152906001019060200180831161132d57829003601f168201915b50505091909252505050600183015490915061139a5782604001516040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b841580156113bf5750805173ffffffffffffffffffffffffffffffffffffffff163314155b156113f8576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6020830151611433576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001820154602084015181146114b457602084015161145490600790612abe565b1561148b576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084015160018401556114a0600782612b72565b5060208401516114b290600790612e56565b505b606084015180516000036114f657806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b8354600090859060049061151790640100000000900463ffffffff166148ea565b91906101000a81548163ffffffff021916908363ffffffff1602179055905060005b82518110156115fc5761156f838281518110611557576115576147e4565b60200260200101516003612abe90919063ffffffff16565b6115a757826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b6115f38382815181106115bc576115bc6147e4565b60200260200101518760030160008563ffffffff1663ffffffff168152602001908152602001600020612e5690919063ffffffff16565b50600101611539565b50845468010000000000000000900463ffffffff16801561175d5763ffffffff8082166000908152600d60209081526040808320805464010000000090049094168352600190930181528282206002018054845181840281018401909552808552929392909183018282801561169157602002820191906000526020600020905b81548152602001906001019080831161167d575b5050505050905060005b815181101561175a576116f08282815181106116b9576116b96147e4565b60200260200101518960030160008763ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b61175257818181518110611706576117066147e4565b6020026020010151836040517f03dcd86200000000000000000000000000000000000000000000000000000000815260040161060992919091825263ffffffff16602082015260400190565b60010161169b565b50505b600061176b87600401612e49565b905060005b81518163ffffffff1610156118b1576000828263ffffffff1681518110611799576117996147e4565b60209081029190910181015163ffffffff8082166000908152600d8452604080822080546401000000009004909316825260019092018452818120600201805483518187028101870190945280845293955090939192909183018282801561182057602002820191906000526020600020905b81548152602001906001019080831161180c575b5050505050905060005b815181101561189d5761187f828281518110611848576118486147e4565b60200260200101518c60030160008a63ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b61189557818181518110611706576117066147e4565b60010161182a565b505050806118aa906148ea565b9050611770565b50875187547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90911690811788556040808a015160028a018190556020808c01518351928352908201527f4b5b465e22eea0c3d40c30e936643245b80d19b2dcf75788c0699fe8d8db645b910160405180910390a25050505050505050806001019050611235565b600e5460609063ffffffff166000611958600183614842565b63ffffffff1667ffffffffffffffff81111561197657611976613d25565b6040519080825280602002602001820160405280156119bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816119945790505b509050600060015b8363ffffffff168163ffffffff161015611b0c5763ffffffff81166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611b045763ffffffff81166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191611a5890614897565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8490614897565b8015611ad15780601f10611aa657610100808354040283529160200191611ad1565b820191906000526020600020905b815481529060010190602001808311611ab457829003601f168201915b505050505081525050838381518110611aec57611aec6147e4565b602002602001018190525081611b019061485f565b91505b6001016119c4565b50600e546107e29060019063ffffffff16614842565b611b2a612ad9565b60005b81811015610697576000838383818110611b4957611b496147e4565b9050602002810190611b5b9190614cd8565b611b6490614d1b565b90506000611b7a82600001518360200151610446565b9050611b87600382612e56565b611bc0576040517febf5255100000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b611bca8183612e62565b5050600101611b2d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110611c0e57611c0e6147e4565b9050602002810190611c209190614b8d565b611c2990614bc1565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191611c7f90614897565b80601f0160208091040260200160405190810160405280929190818152602001828054611cab90614897565b8015611cf85780601f10611ccd57610100808354040283529160200191611cf8565b820191906000526020600020905b815481529060010190602001808311611cdb57829003601f168201915b50505091909252505081519192505073ffffffffffffffffffffffffffffffffffffffff16611d5e5781516040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff9091166004820152602401610609565b83158015611d835750805173ffffffffffffffffffffffffffffffffffffffff163314155b15611dbc576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c60205220600181015415611e115782604001516040517f5461848300000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6040830151611e545782604001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b60208301511580611e7157506020830151611e7190600790612abe565b15611ea8576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608301518051600003611eea57806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b81548290600490611f0890640100000000900463ffffffff166148ea565b82546101009290920a63ffffffff818102199093169183160217909155825464010000000090041660005b8251811015611fde57611f51838281518110611557576115576147e4565b611f8957826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b611fd5838281518110611f9e57611f9e6147e4565b60200260200101518560030160008563ffffffff1663ffffffff168152602001908152602001600020612e5690919063ffffffff16565b50600101611f33565b50845183547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff918216178455604086015160028501556020860151600185018190556120349160079190612e5616565b50604085015161204690600990612e56565b50845160408087015160208089015183519283529082015263ffffffff909216917f74becb12a5e8fd0e98077d02dfba8f647c9670c9df177e42c2418cf17a636f05910160405180910390a25050505050806001019050611bf2565b60015473ffffffffffffffffffffffffffffffffffffffff163314612123576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610609565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b8281146121e2576040517fab8b67c60000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610609565b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156124d757600086868381811061221a5761221a6147e4565b905060200201602081019061222f91906141eb565b63ffffffff81166000908152600b6020526040902080549192509073ffffffffffffffffffffffffffffffffffffffff1661229e576040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602401610609565b60008686858181106122b2576122b26147e4565b90506020028101906122c4919061490d565b6122cd9061494b565b805190915073ffffffffffffffffffffffffffffffffffffffff1661231e576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815473ffffffffffffffffffffffffffffffffffffffff16331480159061235b57503373ffffffffffffffffffffffffffffffffffffffff861614155b15612394576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b8051825473ffffffffffffffffffffffffffffffffffffffff908116911614158061241057506020808201516040516123cd9201613f76565b60405160208183030381529060405280519060200120826001016040516020016123f79190614dc1565b6040516020818303038152906040528051906020012014155b156124c957805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020810151600183019061246a9082614a05565b50806000015173ffffffffffffffffffffffffffffffffffffffff168363ffffffff167f86f41145bde5dd7f523305452e4aad3685508c181432ec733d5f345009358a2883602001516040516124c09190613f76565b60405180910390a35b5050508060010190506121fe565b505050505050565b6125206040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b6040805160e0810182528381526000848152600260209081529290208054919283019161254c90614897565b80601f016020809104026020016040519081016040528092919081815260200182805461257890614897565b80156125c55780601f1061259a576101008083540402835291602001916125c5565b820191906000526020600020905b8154815290600101906020018083116125a857829003601f168201915b505050505081526020016002600085815260200190815260200160002060010180546125f090614897565b80601f016020809104026020016040519081016040528092919081815260200182805461261c90614897565b80156126695780601f1061263e57610100808354040283529160200191612669565b820191906000526020600020905b81548152906001019060200180831161264c57829003601f168201915b50505091835250506000848152600260208181526040909220015491019060ff16600381111561269b5761269b61444c565b815260008481526002602081815260409092200154910190610100900460ff1660018111156126cc576126cc61444c565b81526000848152600260208181526040928390209091015462010000900473ffffffffffffffffffffffffffffffffffffffff169083015201612710600585612abe565b1515905292915050565b612722612ad9565b63ffffffff8089166000908152600d6020526040812054640100000000900490911690819003612786576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff8a166004820152602401610609565b6127d8888888886040518060a001604052808f63ffffffff168152602001876127ae906148ea565b97508763ffffffff1681526020018a1515815260200189151581526020018860ff168152506130f6565b505050505050505050565b6127eb612ad9565b600e805460009164010000000090910463ffffffff1690600461280d836148ea565b82546101009290920a63ffffffff81810219909316918316021790915581166000818152600d602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001684179055815160a08101835292835260019083015286151590820152841515606082015260ff841660808201529091506128a39089908990899089906130f6565b5050505050505050565b606060006128bb6003612e49565b90506000815167ffffffffffffffff8111156128d9576128d9613d25565b60405190808252806020026020018201604052801561294b57816020015b6129386040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b8152602001906001900390816128f75790505b50905060005b82518110156107f25761297c83828151811061296f5761296f6147e4565b60200260200101516124df565b82828151811061298e5761298e6147e4565b6020908102919091010152600101612951565b606060006129af6009612e49565b90506000815167ffffffffffffffff8111156129cd576129cd613d25565b604051908082528060200260200182016040528015612a5457816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816129eb5790505b50905060005b82518110156107f257612a85838281518110612a7857612a786147e4565b6020026020010151611048565b828281518110612a9757612a976147e4565b6020908102919091010152600101612a5a565b612ab2612ad9565b612abb8161391a565b50565b600081815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610609565b565b6000610474825490565b6000612ad28383613a0f565b6000612ad28383613a39565b6040805160e0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840181905260c084015263ffffffff8581168352600d8252848320805464010000000090049091168084526001909101825284832060028101805487518186028101860190985280885295969295919493909190830182828015612c2f57602002820191906000526020600020905b815481526020019060010190808311612c1b575b505050505090506000815167ffffffffffffffff811115612c5257612c52613d25565b604051908082528060200260200182016040528015612c9857816020015b604080518082019091526000815260606020820152815260200190600190039081612c705790505b50905060005b8151811015612db0576040518060400160405280848381518110612cc457612cc46147e4565b60200260200101518152602001856003016000868581518110612ce957612ce96147e4565b602002602001015181526020019081526020016000208054612d0a90614897565b80601f0160208091040260200160405190810160405280929190818152602001828054612d3690614897565b8015612d835780601f10612d5857610100808354040283529160200191612d83565b820191906000526020600020905b815481529060010190602001808311612d6657829003601f168201915b5050505050815250828281518110612d9d57612d9d6147e4565b6020908102919091010152600101612c9e565b506040805160e08101825263ffffffff8089166000818152600d6020818152868320548086168752948b168187015260ff680100000000000000008604811697870197909752690100000000000000000085048716151560608701529290915290526a010000000000000000000090049091161515608082015260a08101612e3785612e49565b81526020019190915295945050505050565b60606000612ad283613b2c565b6000612ad28383613b88565b608081015173ffffffffffffffffffffffffffffffffffffffff1615612fb057608081015173ffffffffffffffffffffffffffffffffffffffff163b1580612f5b575060808101516040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f78bea72100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff909116906301ffc9a790602401602060405180830381865afa158015612f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f599190614e6f565b155b15612fb05760808101516040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610609565b600082815260026020526040902081518291908190612fcf9082614a05565b5060208201516001820190612fe49082614a05565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156130265761302661444c565b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010083600181111561306d5761306d61444c565b0217905550608091909101516002909101805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff90921691909117905560405182907f04f0a9bcf3f3a3b42a4d7ca081119755f82ebe43e0d30c8f7292c4fe0dc4a2ae90600090a25050565b805163ffffffff9081166000908152600d602090815260408083208286015190941683526001909301905220608082015160ff161580613148575060808201518590613143906001614e8c565b60ff16115b156131915760808201516040517f25b4d61800000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101869052604401610609565b6001826020015163ffffffff16111561327957815163ffffffff166000908152600d6020908152604082209084015160019182019183916131d29190614842565b63ffffffff1663ffffffff168152602001908152602001600020905060005b6131fa82612b5c565b81101561327657613229846000015163ffffffff16600c60006105928587600001612b6690919063ffffffff16565b50600c60006132388484612b66565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556001016131f1565b50505b60005b858110156134b3576132a9878783818110613299576132996147e4565b8592602090910201359050612e56565b61330a5782518787838181106132c1576132c16147e4565b6040517f636e405700000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b82606001511561346157825163ffffffff16600c6000898985818110613332576133326147e4565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff16148015906133ac5750600c600088888481811061337d5761337d6147e4565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff1615155b1561340e5782518787838181106133c5576133c56147e4565b6040517f60b9df7300000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8251600c6000898985818110613426576134266147e4565b90506020020135815260200190815260200160002060000160086101000a81548163ffffffff021916908363ffffffff1602179055506134ab565b82516134a99063ffffffff16600c60008a8a86818110613483576134836147e4565b905060200201358152602001908152602001600020600401612e5690919063ffffffff16565b505b60010161327c565b5060005b8381101561378f57368585838181106134d2576134d26147e4565b90506020028101906134e4919061490d565b90506134f260038235612abe565b61352b576040517fe181733f00000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b61353760058235612abe565b15613571576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b803560009081526003840160205260408120805461358e90614897565b905011156135da5783516040517f3927d08000000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015281356024820152604401610609565b60005b878110156136e4576136818235600c60008c8c86818110613600576136006147e4565b9050602002013581526020019081526020016000206003016000600c60008e8e88818110613630576136306147e4565b90506020020135815260200190815260200160002060000160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b6136dc57888882818110613697576136976147e4565b6040517fa7e792500000000000000000000000000000000000000000000000000000000081526020909102929092013560048301525082356024820152604401610609565b6001016135dd565b506002830180546001810182556000918252602091829020833591015561370d90820182614ea5565b8235600090815260038601602052604090209161372b919083614f0a565b50835160208086015161378692918435908c908c9061374c90880188614ea5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613bd792505050565b506001016134b7565b50604080830151835163ffffffff9081166000908152600d602090815284822080549415156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff90951694909417909355606086015186518316825284822080549115156a0100000000000000000000027fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff9092169190911790556080860151865183168252848220805460ff9290921668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff909216919091179055918501805186518316845292849020805493909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9093169290921790558351905191517ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c15817036519261390a929163ffffffff92831681529116602082015260400190565b60405180910390a1505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613999576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610609565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613a2657613a266147e4565b9060005260206000200154905092915050565b60008181526001830160205260408120548015613b22576000613a5d600183615025565b8554909150600090613a7190600190615025565b9050818114613ad6576000866000018281548110613a9157613a916147e4565b9060005260206000200154905080876000018481548110613ab457613ab46147e4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613ae757613ae7615038565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610474565b6000915050610474565b606081600001805480602002602001604051908101604052809291908181526020018280548015613b7c57602002820191906000526020600020905b815481526020019060010190808311613b68575b50505050509050919050565b6000818152600183016020526040812054613bcf57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610474565b506000610474565b6000848152600260208190526040909120015462010000900473ffffffffffffffffffffffffffffffffffffffff16156124d757600084815260026020819052604091829020015490517ffba64a7c0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169063fba64a7c90613c7e908690869086908b908d90600401615067565b600060405180830381600087803b158015613c9857600080fd5b505af1158015613cac573d6000803e3d6000fd5b50505050505050505050565b508054613cc490614897565b6000825580601f10613cd4575050565b601f016020900490600052602060002090810190612abb9190613d0c565b5080546000825590600052602060002090810190612abb91905b5b80821115613d215760008155600101613d0d565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613d7757613d77613d25565b60405290565b60405160a0810167ffffffffffffffff81118282101715613d7757613d77613d25565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613de757613de7613d25565b604052919050565b600067ffffffffffffffff821115613e0957613e09613d25565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e4657600080fd5b8135613e59613e5482613def565b613da0565b818152846020838601011115613e6e57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613e9e57600080fd5b823567ffffffffffffffff80821115613eb657600080fd5b613ec286838701613e35565b93506020850135915080821115613ed857600080fd5b50613ee585828601613e35565b9150509250929050565b600060208284031215613f0157600080fd5b5035919050565b60005b83811015613f23578181015183820152602001613f0b565b50506000910152565b60008151808452613f44816020860160208601613f08565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612ad26020830184613f2c565b60008083601f840112613f9b57600080fd5b50813567ffffffffffffffff811115613fb357600080fd5b6020830191508360208260051b850101111561104157600080fd5b60008060208385031215613fe157600080fd5b823567ffffffffffffffff811115613ff857600080fd5b61400485828601613f89565b90969095509350505050565b60008151808452602080850194506020840160005b8381101561404157815187529582019590820190600101614025565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b848110156140c9578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051845284015160408585018190526140b581860183613f2c565b9a86019a9450505090830190600101614069565b5090979650505050505050565b600063ffffffff8083511684528060208401511660208501525060ff604083015116604084015260608201511515606084015260808201511515608084015260a082015160e060a085015261412e60e0850182614010565b905060c083015184820360c0860152614147828261404c565b95945050505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526141b38583516140d6565b94509285019290850190600101614179565b5092979650505050505050565b803563ffffffff811681146141e657600080fd5b919050565b6000602082840312156141fd57600080fd5b612ad2826141d2565b73ffffffffffffffffffffffffffffffffffffffff8151168252600060208201516040602085015261423b6040850182613f2c565b949350505050565b602081526000612ad26020830184614206565b602081526000612ad260208301846140d6565b6000806040838503121561427c57600080fd5b614285836141d2565b946020939093013593505050565b6040815260006142a66040830185613f2c565b82810360208401526141478185613f2c565b600063ffffffff808351168452602081818501511681860152816040850151166040860152606084015160608601526080840151608086015260a0840151915060e060a086015261430c60e0860183614010565b60c08581015187830391880191909152805180835290830193506000918301905b8083101561434d578451825293830193600192909201919083019061432d565b509695505050505050565b602081526000612ad260208301846142b8565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526143ce858351614206565b94509285019290850190600101614394565b600080600080604085870312156143f657600080fd5b843567ffffffffffffffff8082111561440e57600080fd5b61441a88838901613f89565b9096509450602087013591508082111561443357600080fd5b5061444087828801613f89565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b805182526000602082015160e0602085015261449a60e0850182613f2c565b9050604083015184820360408601526144b38282613f2c565b9150506060830151600481106144cb576144cb61444c565b60608501526080830151600281106144e5576144e561444c565b8060808601525060a083015161451360a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015161452760c086018215159052565b509392505050565b602081526000612ad2602083018461447b565b8015158114612abb57600080fd5b803560ff811681146141e657600080fd5b60008060008060008060008060c0898b03121561457d57600080fd5b614586896141d2565b9750602089013567ffffffffffffffff808211156145a357600080fd5b6145af8c838d01613f89565b909950975060408b01359150808211156145c857600080fd5b506145d58b828c01613f89565b90965094505060608901356145e981614542565b925060808901356145f981614542565b915061460760a08a01614550565b90509295985092959890939650565b600080600080600080600060a0888a03121561463157600080fd5b873567ffffffffffffffff8082111561464957600080fd5b6146558b838c01613f89565b909950975060208a013591508082111561466e57600080fd5b5061467b8a828b01613f89565b909650945050604088013561468f81614542565b9250606088013561469f81614542565b91506146ad60808901614550565b905092959891949750929550565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261471e85835161447b565b945092850192908501906001016146e4565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526147938583516142b8565b94509285019290850190600101614759565b803573ffffffffffffffffffffffffffffffffffffffff811681146141e657600080fd5b6000602082840312156147db57600080fd5b612ad2826147a5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8281168282160390808211156107f2576107f2614813565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361489057614890614813565b5060010190565b600181811c908216806148ab57607f821691505b6020821081036148e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600063ffffffff80831681810361490357614903614813565b6001019392505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261494157600080fd5b9190910192915050565b60006040823603121561495d57600080fd5b6040516040810167ffffffffffffffff828210818311171561498157614981613d25565b8160405261498e856147a5565b835260208501359150808211156149a457600080fd5b506149b136828601613e35565b60208301525092915050565b601f821115610697576000816000526020600020601f850160051c810160208610156149e65750805b601f850160051c820191505b818110156124d7578281556001016149f2565b815167ffffffffffffffff811115614a1f57614a1f613d25565b614a3381614a2d8454614897565b846149bd565b602080601f831160018114614a865760008415614a505750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556124d7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614ad357888601518255948401946001909101908401614ab4565b5085821015614b0f57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215614b3157600080fd5b815167ffffffffffffffff811115614b4857600080fd5b8201601f81018413614b5957600080fd5b8051614b67613e5482613def565b818152856020838501011115614b7c57600080fd5b614147826020830160208601613f08565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261494157600080fd5b600060808236031215614bd357600080fd5b614bdb613d54565b614be4836141d2565b81526020808401358183015260408401356040830152606084013567ffffffffffffffff80821115614c1557600080fd5b9085019036601f830112614c2857600080fd5b813581811115614c3a57614c3a613d25565b8060051b9150614c4b848301613da0565b8181529183018401918481019036841115614c6557600080fd5b938501935b83851015614c8357843582529385019390850190614c6a565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614ccc57835183529284019291840191600101614cb0565b50909695505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261494157600080fd5b8035600281106141e657600080fd5b600060a08236031215614d2d57600080fd5b614d35613d7d565b823567ffffffffffffffff80821115614d4d57600080fd5b614d5936838701613e35565b83526020850135915080821115614d6f57600080fd5b50614d7c36828601613e35565b602083015250604083013560048110614d9457600080fd5b6040820152614da560608401614d0c565b6060820152614db6608084016147a5565b608082015292915050565b6000602080835260008454614dd581614897565b8060208701526040600180841660008114614df75760018114614e3157614e61565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550614e61565b89600052602060002060005b85811015614e585781548b8201860152908301908801614e3d565b8a016040019650505b509398975050505050505050565b600060208284031215614e8157600080fd5b8151612ad281614542565b60ff818116838216019081111561047457610474614813565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614eda57600080fd5b83018035915067ffffffffffffffff821115614ef557600080fd5b60200191503681900382131561104157600080fd5b67ffffffffffffffff831115614f2257614f22613d25565b614f3683614f308354614897565b836149bd565b6000601f841160018114614f885760008515614f525750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561501e565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614fd75786850135825560209485019460019092019101614fb7565b5086821015615012577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8181038181111561047457610474614813565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6080815284608082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8611156150a057600080fd5b8560051b808860a0850137820182810360a090810160208501526150c690820187613f2c565b91505063ffffffff8085166040840152808416606084015250969550505050505056fea164736f6c6343000818000a",
}
var CapabilitiesRegistryABI = CapabilitiesRegistryMetaData.ABI
diff --git a/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go b/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go
new file mode 100644
index 0000000000..2951835c8d
--- /dev/null
+++ b/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go
@@ -0,0 +1,756 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package feeds_consumer
+
+import (
+ "errors"
+ "fmt"
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated"
+)
+
+var (
+ _ = errors.New
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+ _ = abi.ConvertType
+)
+
+var KeystoneFeedsConsumerMetaData = &bind.MetaData{
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"}],\"name\":\"UnauthorizedWorkflowName\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"}],\"name\":\"UnauthorizedWorkflowOwner\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint224\",\"name\":\"price\",\"type\":\"uint224\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"name\":\"FeedReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"getPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_allowedSendersList\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_allowedWorkflowOwnersList\",\"type\":\"address[]\"},{\"internalType\":\"bytes10[]\",\"name\":\"_allowedWorkflowNamesList\",\"type\":\"bytes10[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611281806101576000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063805f21321161005b578063805f2132146101ab5780638da5cb5b146101be578063e3401711146101e6578063f2fde38b146101f957600080fd5b806301ffc9a71461008257806331d98b3f146100ec57806379ba5097146101a1575b600080fd5b6100d7610090366004610dd4565b7fffffffff00000000000000000000000000000000000000000000000000000000167f805f2132000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b6101686100fa366004610e1d565b6000908152600260209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168084527c010000000000000000000000000000000000000000000000000000000090910463ffffffff169290910182905291565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909316835263ffffffff9091166020830152016100e3565b6101a961020c565b005b6101a96101b9366004610e7f565b61030e565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e3565b6101a96101f4366004610f30565b61068d565b6101a9610207366004610fca565b610acd565b60015473ffffffffffffffffffffffffffffffffffffffff163314610292576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3360009081526004602052604090205460ff16610359576040517f3fcc3f17000000000000000000000000000000000000000000000000000000008152336004820152602401610289565b60008061039b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ae192505050565b7fffffffffffffffffffff000000000000000000000000000000000000000000008216600090815260086020526040902054919350915060ff1661042f576040517f4b942f800000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffff0000000000000000000000000000000000000000000083166004820152602401610289565b73ffffffffffffffffffffffffffffffffffffffff811660009081526006602052604090205460ff166104a6576040517fbf24162300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610289565b60006104b4848601866110a7565b905060005b81518110156106835760405180604001604052808383815181106104df576104df6111b9565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152602001838381518110610520576105206111b9565b60200260200101516040015163ffffffff168152506002600084848151811061054b5761054b6111b9565b602090810291909101810151518252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905581518290829081106105cd576105cd6111b9565b6020026020010151600001517f2c30f5cb3caf4239d0f994ce539d7ef24817fa550169c388e3a110f02e40197d83838151811061060c5761060c6111b9565b60200260200101516020015184848151811061062a5761062a6111b9565b6020026020010151604001516040516106739291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a26001016104b9565b5050505050505050565b610695610af7565b60005b60035463ffffffff821610156107365760006004600060038463ffffffff16815481106106c7576106c76111b9565b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905561072f816111e8565b9050610698565b5060005b63ffffffff81168611156107de5760016004600089898563ffffffff16818110610766576107666111b9565b905060200201602081019061077b9190610fca565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556107d7816111e8565b905061073a565b506107eb60038787610c6f565b5060005b60055463ffffffff8216101561088d5760006006600060058463ffffffff168154811061081e5761081e6111b9565b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055610886816111e8565b90506107ef565b5060005b63ffffffff81168411156109355760016006600087878563ffffffff168181106108bd576108bd6111b9565b90506020020160208101906108d29190610fca565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905561092e816111e8565b9050610891565b5061094260058585610c6f565b5060005b60075463ffffffff82161015610a035760006008600060078463ffffffff1681548110610975576109756111b9565b600091825260208083206003808404909101549206600a026101000a90910460b01b7fffffffffffffffffffff00000000000000000000000000000000000000000000168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556109fc816111e8565b9050610946565b5060005b63ffffffff8116821115610ab75760016008600085858563ffffffff16818110610a3357610a336111b9565b9050602002016020810190610a489190611232565b7fffffffffffffffffffff00000000000000000000000000000000000000000000168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055610ab0816111e8565b9050610a07565b50610ac460078383610cf7565b50505050505050565b610ad5610af7565b610ade81610b7a565b50565b6040810151604a90910151909160609190911c90565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610289565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610bf9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610289565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610ce7579160200282015b82811115610ce75781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190610c8f565b50610cf3929150610dbf565b5090565b82805482825590600052602060002090600201600390048101928215610ce75791602002820160005b83821115610d8057833575ffffffffffffffffffffffffffffffffffffffffffff191683826101000a81548169ffffffffffffffffffff021916908360b01c02179055509260200192600a01602081600901049283019260010302610d20565b8015610db65782816101000a81549069ffffffffffffffffffff0219169055600a01602081600901049283019260010302610d80565b5050610cf39291505b5b80821115610cf35760008155600101610dc0565b600060208284031215610de657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e1657600080fd5b9392505050565b600060208284031215610e2f57600080fd5b5035919050565b60008083601f840112610e4857600080fd5b50813567ffffffffffffffff811115610e6057600080fd5b602083019150836020828501011115610e7857600080fd5b9250929050565b60008060008060408587031215610e9557600080fd5b843567ffffffffffffffff80821115610ead57600080fd5b610eb988838901610e36565b90965094506020870135915080821115610ed257600080fd5b50610edf87828801610e36565b95989497509550505050565b60008083601f840112610efd57600080fd5b50813567ffffffffffffffff811115610f1557600080fd5b6020830191508360208260051b8501011115610e7857600080fd5b60008060008060008060608789031215610f4957600080fd5b863567ffffffffffffffff80821115610f6157600080fd5b610f6d8a838b01610eeb565b90985096506020890135915080821115610f8657600080fd5b610f928a838b01610eeb565b90965094506040890135915080821115610fab57600080fd5b50610fb889828a01610eeb565b979a9699509497509295939492505050565b600060208284031215610fdc57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610e1657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561105257611052611000565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561109f5761109f611000565b604052919050565b600060208083850312156110ba57600080fd5b823567ffffffffffffffff808211156110d257600080fd5b818501915085601f8301126110e657600080fd5b8135818111156110f8576110f8611000565b611106848260051b01611058565b8181528481019250606091820284018501918883111561112557600080fd5b938501935b828510156111ad5780858a0312156111425760008081fd5b61114a61102f565b85358152868601357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461117d5760008081fd5b8188015260408681013563ffffffff8116811461119a5760008081fd5b908201528452938401939285019261112a565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103611228577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001019392505050565b60006020828403121561124457600080fd5b81357fffffffffffffffffffff0000000000000000000000000000000000000000000081168114610e1657600080fdfea164736f6c6343000818000a",
+}
+
+var KeystoneFeedsConsumerABI = KeystoneFeedsConsumerMetaData.ABI
+
+var KeystoneFeedsConsumerBin = KeystoneFeedsConsumerMetaData.Bin
+
+func DeployKeystoneFeedsConsumer(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *KeystoneFeedsConsumer, error) {
+ parsed, err := KeystoneFeedsConsumerMetaData.GetAbi()
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ if parsed == nil {
+ return common.Address{}, nil, nil, errors.New("GetABI returned nil")
+ }
+
+ address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(KeystoneFeedsConsumerBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &KeystoneFeedsConsumer{address: address, abi: *parsed, KeystoneFeedsConsumerCaller: KeystoneFeedsConsumerCaller{contract: contract}, KeystoneFeedsConsumerTransactor: KeystoneFeedsConsumerTransactor{contract: contract}, KeystoneFeedsConsumerFilterer: KeystoneFeedsConsumerFilterer{contract: contract}}, nil
+}
+
+type KeystoneFeedsConsumer struct {
+ address common.Address
+ abi abi.ABI
+ KeystoneFeedsConsumerCaller
+ KeystoneFeedsConsumerTransactor
+ KeystoneFeedsConsumerFilterer
+}
+
+type KeystoneFeedsConsumerCaller struct {
+ contract *bind.BoundContract
+}
+
+type KeystoneFeedsConsumerTransactor struct {
+ contract *bind.BoundContract
+}
+
+type KeystoneFeedsConsumerFilterer struct {
+ contract *bind.BoundContract
+}
+
+type KeystoneFeedsConsumerSession struct {
+ Contract *KeystoneFeedsConsumer
+ CallOpts bind.CallOpts
+ TransactOpts bind.TransactOpts
+}
+
+type KeystoneFeedsConsumerCallerSession struct {
+ Contract *KeystoneFeedsConsumerCaller
+ CallOpts bind.CallOpts
+}
+
+type KeystoneFeedsConsumerTransactorSession struct {
+ Contract *KeystoneFeedsConsumerTransactor
+ TransactOpts bind.TransactOpts
+}
+
+type KeystoneFeedsConsumerRaw struct {
+ Contract *KeystoneFeedsConsumer
+}
+
+type KeystoneFeedsConsumerCallerRaw struct {
+ Contract *KeystoneFeedsConsumerCaller
+}
+
+type KeystoneFeedsConsumerTransactorRaw struct {
+ Contract *KeystoneFeedsConsumerTransactor
+}
+
+func NewKeystoneFeedsConsumer(address common.Address, backend bind.ContractBackend) (*KeystoneFeedsConsumer, error) {
+ abi, err := abi.JSON(strings.NewReader(KeystoneFeedsConsumerABI))
+ if err != nil {
+ return nil, err
+ }
+ contract, err := bindKeystoneFeedsConsumer(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &KeystoneFeedsConsumer{address: address, abi: abi, KeystoneFeedsConsumerCaller: KeystoneFeedsConsumerCaller{contract: contract}, KeystoneFeedsConsumerTransactor: KeystoneFeedsConsumerTransactor{contract: contract}, KeystoneFeedsConsumerFilterer: KeystoneFeedsConsumerFilterer{contract: contract}}, nil
+}
+
+func NewKeystoneFeedsConsumerCaller(address common.Address, caller bind.ContractCaller) (*KeystoneFeedsConsumerCaller, error) {
+ contract, err := bindKeystoneFeedsConsumer(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &KeystoneFeedsConsumerCaller{contract: contract}, nil
+}
+
+func NewKeystoneFeedsConsumerTransactor(address common.Address, transactor bind.ContractTransactor) (*KeystoneFeedsConsumerTransactor, error) {
+ contract, err := bindKeystoneFeedsConsumer(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &KeystoneFeedsConsumerTransactor{contract: contract}, nil
+}
+
+func NewKeystoneFeedsConsumerFilterer(address common.Address, filterer bind.ContractFilterer) (*KeystoneFeedsConsumerFilterer, error) {
+ contract, err := bindKeystoneFeedsConsumer(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &KeystoneFeedsConsumerFilterer{contract: contract}, nil
+}
+
+func bindKeystoneFeedsConsumer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := KeystoneFeedsConsumerMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _KeystoneFeedsConsumer.Contract.KeystoneFeedsConsumerCaller.contract.Call(opts, result, method, params...)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.KeystoneFeedsConsumerTransactor.contract.Transfer(opts)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.KeystoneFeedsConsumerTransactor.contract.Transact(opts, method, params...)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _KeystoneFeedsConsumer.Contract.contract.Call(opts, result, method, params...)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.contract.Transfer(opts)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.contract.Transact(opts, method, params...)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerCaller) GetPrice(opts *bind.CallOpts, feedId [32]byte) (*big.Int, uint32, error) {
+ var out []interface{}
+ err := _KeystoneFeedsConsumer.contract.Call(opts, &out, "getPrice", feedId)
+
+ if err != nil {
+ return *new(*big.Int), *new(uint32), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+ out1 := *abi.ConvertType(out[1], new(uint32)).(*uint32)
+
+ return out0, out1, err
+
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerSession) GetPrice(feedId [32]byte) (*big.Int, uint32, error) {
+ return _KeystoneFeedsConsumer.Contract.GetPrice(&_KeystoneFeedsConsumer.CallOpts, feedId)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerCallerSession) GetPrice(feedId [32]byte) (*big.Int, uint32, error) {
+ return _KeystoneFeedsConsumer.Contract.GetPrice(&_KeystoneFeedsConsumer.CallOpts, feedId)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _KeystoneFeedsConsumer.contract.Call(opts, &out, "owner")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerSession) Owner() (common.Address, error) {
+ return _KeystoneFeedsConsumer.Contract.Owner(&_KeystoneFeedsConsumer.CallOpts)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerCallerSession) Owner() (common.Address, error) {
+ return _KeystoneFeedsConsumer.Contract.Owner(&_KeystoneFeedsConsumer.CallOpts)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) {
+ var out []interface{}
+ err := _KeystoneFeedsConsumer.contract.Call(opts, &out, "supportsInterface", interfaceId)
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerSession) SupportsInterface(interfaceId [4]byte) (bool, error) {
+ return _KeystoneFeedsConsumer.Contract.SupportsInterface(&_KeystoneFeedsConsumer.CallOpts, interfaceId)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) {
+ return _KeystoneFeedsConsumer.Contract.SupportsInterface(&_KeystoneFeedsConsumer.CallOpts, interfaceId)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.contract.Transact(opts, "acceptOwnership")
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerSession) AcceptOwnership() (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.AcceptOwnership(&_KeystoneFeedsConsumer.TransactOpts)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactorSession) AcceptOwnership() (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.AcceptOwnership(&_KeystoneFeedsConsumer.TransactOpts)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactor) OnReport(opts *bind.TransactOpts, metadata []byte, rawReport []byte) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.contract.Transact(opts, "onReport", metadata, rawReport)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerSession) OnReport(metadata []byte, rawReport []byte) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.OnReport(&_KeystoneFeedsConsumer.TransactOpts, metadata, rawReport)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactorSession) OnReport(metadata []byte, rawReport []byte) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.OnReport(&_KeystoneFeedsConsumer.TransactOpts, metadata, rawReport)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactor) SetConfig(opts *bind.TransactOpts, _allowedSendersList []common.Address, _allowedWorkflowOwnersList []common.Address, _allowedWorkflowNamesList [][10]byte) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.contract.Transact(opts, "setConfig", _allowedSendersList, _allowedWorkflowOwnersList, _allowedWorkflowNamesList)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerSession) SetConfig(_allowedSendersList []common.Address, _allowedWorkflowOwnersList []common.Address, _allowedWorkflowNamesList [][10]byte) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.SetConfig(&_KeystoneFeedsConsumer.TransactOpts, _allowedSendersList, _allowedWorkflowOwnersList, _allowedWorkflowNamesList)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactorSession) SetConfig(_allowedSendersList []common.Address, _allowedWorkflowOwnersList []common.Address, _allowedWorkflowNamesList [][10]byte) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.SetConfig(&_KeystoneFeedsConsumer.TransactOpts, _allowedSendersList, _allowedWorkflowOwnersList, _allowedWorkflowNamesList)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.contract.Transact(opts, "transferOwnership", to)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.TransferOwnership(&_KeystoneFeedsConsumer.TransactOpts, to)
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
+ return _KeystoneFeedsConsumer.Contract.TransferOwnership(&_KeystoneFeedsConsumer.TransactOpts, to)
+}
+
+type KeystoneFeedsConsumerFeedReceivedIterator struct {
+ Event *KeystoneFeedsConsumerFeedReceived
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *KeystoneFeedsConsumerFeedReceivedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(KeystoneFeedsConsumerFeedReceived)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(KeystoneFeedsConsumerFeedReceived)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *KeystoneFeedsConsumerFeedReceivedIterator) Error() error {
+ return it.fail
+}
+
+func (it *KeystoneFeedsConsumerFeedReceivedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type KeystoneFeedsConsumerFeedReceived struct {
+ FeedId [32]byte
+ Price *big.Int
+ Timestamp uint32
+ Raw types.Log
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerFilterer) FilterFeedReceived(opts *bind.FilterOpts, feedId [][32]byte) (*KeystoneFeedsConsumerFeedReceivedIterator, error) {
+
+ var feedIdRule []interface{}
+ for _, feedIdItem := range feedId {
+ feedIdRule = append(feedIdRule, feedIdItem)
+ }
+
+ logs, sub, err := _KeystoneFeedsConsumer.contract.FilterLogs(opts, "FeedReceived", feedIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &KeystoneFeedsConsumerFeedReceivedIterator{contract: _KeystoneFeedsConsumer.contract, event: "FeedReceived", logs: logs, sub: sub}, nil
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerFilterer) WatchFeedReceived(opts *bind.WatchOpts, sink chan<- *KeystoneFeedsConsumerFeedReceived, feedId [][32]byte) (event.Subscription, error) {
+
+ var feedIdRule []interface{}
+ for _, feedIdItem := range feedId {
+ feedIdRule = append(feedIdRule, feedIdItem)
+ }
+
+ logs, sub, err := _KeystoneFeedsConsumer.contract.WatchLogs(opts, "FeedReceived", feedIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(KeystoneFeedsConsumerFeedReceived)
+ if err := _KeystoneFeedsConsumer.contract.UnpackLog(event, "FeedReceived", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerFilterer) ParseFeedReceived(log types.Log) (*KeystoneFeedsConsumerFeedReceived, error) {
+ event := new(KeystoneFeedsConsumerFeedReceived)
+ if err := _KeystoneFeedsConsumer.contract.UnpackLog(event, "FeedReceived", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type KeystoneFeedsConsumerOwnershipTransferRequestedIterator struct {
+ Event *KeystoneFeedsConsumerOwnershipTransferRequested
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *KeystoneFeedsConsumerOwnershipTransferRequestedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(KeystoneFeedsConsumerOwnershipTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(KeystoneFeedsConsumerOwnershipTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *KeystoneFeedsConsumerOwnershipTransferRequestedIterator) Error() error {
+ return it.fail
+}
+
+func (it *KeystoneFeedsConsumerOwnershipTransferRequestedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type KeystoneFeedsConsumerOwnershipTransferRequested struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeystoneFeedsConsumerOwnershipTransferRequestedIterator, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _KeystoneFeedsConsumer.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &KeystoneFeedsConsumerOwnershipTransferRequestedIterator{contract: _KeystoneFeedsConsumer.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeystoneFeedsConsumerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _KeystoneFeedsConsumer.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(KeystoneFeedsConsumerOwnershipTransferRequested)
+ if err := _KeystoneFeedsConsumer.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerFilterer) ParseOwnershipTransferRequested(log types.Log) (*KeystoneFeedsConsumerOwnershipTransferRequested, error) {
+ event := new(KeystoneFeedsConsumerOwnershipTransferRequested)
+ if err := _KeystoneFeedsConsumer.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type KeystoneFeedsConsumerOwnershipTransferredIterator struct {
+ Event *KeystoneFeedsConsumerOwnershipTransferred
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *KeystoneFeedsConsumerOwnershipTransferredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(KeystoneFeedsConsumerOwnershipTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(KeystoneFeedsConsumerOwnershipTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *KeystoneFeedsConsumerOwnershipTransferredIterator) Error() error {
+ return it.fail
+}
+
+func (it *KeystoneFeedsConsumerOwnershipTransferredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type KeystoneFeedsConsumerOwnershipTransferred struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeystoneFeedsConsumerOwnershipTransferredIterator, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _KeystoneFeedsConsumer.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &KeystoneFeedsConsumerOwnershipTransferredIterator{contract: _KeystoneFeedsConsumer.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *KeystoneFeedsConsumerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _KeystoneFeedsConsumer.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(KeystoneFeedsConsumerOwnershipTransferred)
+ if err := _KeystoneFeedsConsumer.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerFilterer) ParseOwnershipTransferred(log types.Log) (*KeystoneFeedsConsumerOwnershipTransferred, error) {
+ event := new(KeystoneFeedsConsumerOwnershipTransferred)
+ if err := _KeystoneFeedsConsumer.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumer) ParseLog(log types.Log) (generated.AbigenLog, error) {
+ switch log.Topics[0] {
+ case _KeystoneFeedsConsumer.abi.Events["FeedReceived"].ID:
+ return _KeystoneFeedsConsumer.ParseFeedReceived(log)
+ case _KeystoneFeedsConsumer.abi.Events["OwnershipTransferRequested"].ID:
+ return _KeystoneFeedsConsumer.ParseOwnershipTransferRequested(log)
+ case _KeystoneFeedsConsumer.abi.Events["OwnershipTransferred"].ID:
+ return _KeystoneFeedsConsumer.ParseOwnershipTransferred(log)
+
+ default:
+ return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
+ }
+}
+
+func (KeystoneFeedsConsumerFeedReceived) Topic() common.Hash {
+ return common.HexToHash("0x2c30f5cb3caf4239d0f994ce539d7ef24817fa550169c388e3a110f02e40197d")
+}
+
+func (KeystoneFeedsConsumerOwnershipTransferRequested) Topic() common.Hash {
+ return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
+}
+
+func (KeystoneFeedsConsumerOwnershipTransferred) Topic() common.Hash {
+ return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
+}
+
+func (_KeystoneFeedsConsumer *KeystoneFeedsConsumer) Address() common.Address {
+ return _KeystoneFeedsConsumer.address
+}
+
+type KeystoneFeedsConsumerInterface interface {
+ GetPrice(opts *bind.CallOpts, feedId [32]byte) (*big.Int, uint32, error)
+
+ Owner(opts *bind.CallOpts) (common.Address, error)
+
+ SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error)
+
+ AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
+
+ OnReport(opts *bind.TransactOpts, metadata []byte, rawReport []byte) (*types.Transaction, error)
+
+ SetConfig(opts *bind.TransactOpts, _allowedSendersList []common.Address, _allowedWorkflowOwnersList []common.Address, _allowedWorkflowNamesList [][10]byte) (*types.Transaction, error)
+
+ TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
+
+ FilterFeedReceived(opts *bind.FilterOpts, feedId [][32]byte) (*KeystoneFeedsConsumerFeedReceivedIterator, error)
+
+ WatchFeedReceived(opts *bind.WatchOpts, sink chan<- *KeystoneFeedsConsumerFeedReceived, feedId [][32]byte) (event.Subscription, error)
+
+ ParseFeedReceived(log types.Log) (*KeystoneFeedsConsumerFeedReceived, error)
+
+ FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeystoneFeedsConsumerOwnershipTransferRequestedIterator, error)
+
+ WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeystoneFeedsConsumerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
+
+ ParseOwnershipTransferRequested(log types.Log) (*KeystoneFeedsConsumerOwnershipTransferRequested, error)
+
+ FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeystoneFeedsConsumerOwnershipTransferredIterator, error)
+
+ WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *KeystoneFeedsConsumerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
+
+ ParseOwnershipTransferred(log types.Log) (*KeystoneFeedsConsumerOwnershipTransferred, error)
+
+ ParseLog(log types.Log) (generated.AbigenLog, error)
+
+ Address() common.Address
+}
diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt
index 4051f95020..40cf539277 100644
--- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt
+++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt
@@ -1,4 +1,5 @@
GETH_VERSION: 1.13.8
-capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin 3a082f0307411f41c30db26e61d59adcd5b003141a5aa8fe79d7779619028e26
+capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin 6d2e3aa3a6f3aed2cf24b613743bb9ae4b9558f48a6864dc03b8b0ebb37235e3
+feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin 8c3a2b18a80be41e7c40d2bc3a4c8d1b5e18d55c1fd20ad5af68cebb66109fc5
forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin dc98a86a3775ead987b79d5b6079ee0e26f31c0626032bdd6508f986e2423227
ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 8bf0f53f222efce7143dea6134552eb26ea1eef845407b4475a0d79b7d7ba9f8
diff --git a/core/gethwrappers/keystone/go_generate.go b/core/gethwrappers/keystone/go_generate.go
index 36b27852ad..79f49264b3 100644
--- a/core/gethwrappers/keystone/go_generate.go
+++ b/core/gethwrappers/keystone/go_generate.go
@@ -7,3 +7,4 @@ package gethwrappers
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin KeystoneForwarder forwarder
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin OCR3Capability ocr3_capability
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin CapabilitiesRegistry capabilities_registry
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin KeystoneFeedsConsumer feeds_consumer
diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go
index 508dde86a0..12491300bf 100644
--- a/core/internal/cltest/cltest.go
+++ b/core/internal/cltest/cltest.go
@@ -37,6 +37,10 @@ import (
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting/types"
+ "github.com/smartcontractkit/chainlink/v2/core/capabilities"
+ remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types"
+ p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
+
"github.com/smartcontractkit/chainlink-common/pkg/loop"
"github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
@@ -316,6 +320,31 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn
auditLogger = audit.NoopLogger
}
+ var capabilitiesRegistry *capabilities.Registry
+ capabilitiesRegistry = capabilities.NewRegistry(lggr)
+ for _, dep := range flagsAndDeps {
+ registry, _ := dep.(*capabilities.Registry)
+ if registry != nil {
+ capabilitiesRegistry = registry
+ }
+ }
+
+ var dispatcher remotetypes.Dispatcher
+ for _, dep := range flagsAndDeps {
+ dispatcher, _ = dep.(remotetypes.Dispatcher)
+ if dispatcher != nil {
+ break
+ }
+ }
+
+ var peerWrapper p2ptypes.PeerWrapper
+ for _, dep := range flagsAndDeps {
+ peerWrapper, _ = dep.(p2ptypes.PeerWrapper)
+ if peerWrapper != nil {
+ break
+ }
+ }
+
url := cfg.Database().URL()
db, err := pg.NewConnection(url.String(), cfg.Database().Dialect(), cfg.Database())
require.NoError(t, err)
@@ -354,10 +383,11 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn
})
relayerFactory := chainlink.RelayerFactory{
- Logger: lggr,
- LoopRegistry: loopRegistry,
- GRPCOpts: loop.GRPCOpts{},
- MercuryPool: mercuryPool,
+ Logger: lggr,
+ LoopRegistry: loopRegistry,
+ GRPCOpts: loop.GRPCOpts{},
+ MercuryPool: mercuryPool,
+ CapabilitiesRegistry: capabilitiesRegistry,
}
evmOpts := chainlink.EVMFactoryConfig{
@@ -409,6 +439,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn
}
initOps = append(initOps, chainlink.InitStarknet(testCtx, relayerFactory, starkCfg))
}
+
relayChainInterops, err := chainlink.NewCoreRelayerChainInteroperators(initOps...)
if err != nil {
t.Fatal(err)
@@ -429,7 +460,11 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn
SecretGenerator: MockSecretGenerator{},
LoopRegistry: plugins.NewLoopRegistry(lggr, nil),
MercuryPool: mercuryPool,
+ CapabilitiesRegistry: capabilitiesRegistry,
+ CapabilitiesDispatcher: dispatcher,
+ CapabilitiesPeerWrapper: peerWrapper,
})
+
require.NoError(t, err)
app := appInstance.(*chainlink.ChainlinkApplication)
ta := &TestApplication{
diff --git a/core/internal/mocks/prometheus_backend.go b/core/internal/mocks/prometheus_backend.go
new file mode 100644
index 0000000000..d02f7062cb
--- /dev/null
+++ b/core/internal/mocks/prometheus_backend.go
@@ -0,0 +1,204 @@
+// Code generated by mockery v2.43.2. DO NOT EDIT.
+
+package mocks
+
+import (
+ big "math/big"
+
+ mock "github.com/stretchr/testify/mock"
+)
+
+// PrometheusBackend is an autogenerated mock type for the PrometheusBackend type
+type PrometheusBackend struct {
+ mock.Mock
+}
+
+type PrometheusBackend_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *PrometheusBackend) EXPECT() *PrometheusBackend_Expecter {
+ return &PrometheusBackend_Expecter{mock: &_m.Mock}
+}
+
+// SetMaxUnconfirmedAge provides a mock function with given fields: _a0, _a1
+func (_m *PrometheusBackend) SetMaxUnconfirmedAge(_a0 *big.Int, _a1 float64) {
+ _m.Called(_a0, _a1)
+}
+
+// PrometheusBackend_SetMaxUnconfirmedAge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedAge'
+type PrometheusBackend_SetMaxUnconfirmedAge_Call struct {
+ *mock.Call
+}
+
+// SetMaxUnconfirmedAge is a helper method to define mock.On call
+// - _a0 *big.Int
+// - _a1 float64
+func (_e *PrometheusBackend_Expecter) SetMaxUnconfirmedAge(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetMaxUnconfirmedAge_Call {
+ return &PrometheusBackend_SetMaxUnconfirmedAge_Call{Call: _e.mock.On("SetMaxUnconfirmedAge", _a0, _a1)}
+}
+
+func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) Run(run func(_a0 *big.Int, _a1 float64)) *PrometheusBackend_SetMaxUnconfirmedAge_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(*big.Int), args[1].(float64))
+ })
+ return _c
+}
+
+func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) Return() *PrometheusBackend_SetMaxUnconfirmedAge_Call {
+ _c.Call.Return()
+ return _c
+}
+
+func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) RunAndReturn(run func(*big.Int, float64)) *PrometheusBackend_SetMaxUnconfirmedAge_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// SetMaxUnconfirmedBlocks provides a mock function with given fields: _a0, _a1
+func (_m *PrometheusBackend) SetMaxUnconfirmedBlocks(_a0 *big.Int, _a1 int64) {
+ _m.Called(_a0, _a1)
+}
+
+// PrometheusBackend_SetMaxUnconfirmedBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedBlocks'
+type PrometheusBackend_SetMaxUnconfirmedBlocks_Call struct {
+ *mock.Call
+}
+
+// SetMaxUnconfirmedBlocks is a helper method to define mock.On call
+// - _a0 *big.Int
+// - _a1 int64
+func (_e *PrometheusBackend_Expecter) SetMaxUnconfirmedBlocks(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call {
+ return &PrometheusBackend_SetMaxUnconfirmedBlocks_Call{Call: _e.mock.On("SetMaxUnconfirmedBlocks", _a0, _a1)}
+}
+
+func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) Run(run func(_a0 *big.Int, _a1 int64)) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(*big.Int), args[1].(int64))
+ })
+ return _c
+}
+
+func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) Return() *PrometheusBackend_SetMaxUnconfirmedBlocks_Call {
+ _c.Call.Return()
+ return _c
+}
+
+func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) RunAndReturn(run func(*big.Int, int64)) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// SetPipelineRunsQueued provides a mock function with given fields: n
+func (_m *PrometheusBackend) SetPipelineRunsQueued(n int) {
+ _m.Called(n)
+}
+
+// PrometheusBackend_SetPipelineRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineRunsQueued'
+type PrometheusBackend_SetPipelineRunsQueued_Call struct {
+ *mock.Call
+}
+
+// SetPipelineRunsQueued is a helper method to define mock.On call
+// - n int
+func (_e *PrometheusBackend_Expecter) SetPipelineRunsQueued(n interface{}) *PrometheusBackend_SetPipelineRunsQueued_Call {
+ return &PrometheusBackend_SetPipelineRunsQueued_Call{Call: _e.mock.On("SetPipelineRunsQueued", n)}
+}
+
+func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) Run(run func(n int)) *PrometheusBackend_SetPipelineRunsQueued_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(int))
+ })
+ return _c
+}
+
+func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) Return() *PrometheusBackend_SetPipelineRunsQueued_Call {
+ _c.Call.Return()
+ return _c
+}
+
+func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) RunAndReturn(run func(int)) *PrometheusBackend_SetPipelineRunsQueued_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// SetPipelineTaskRunsQueued provides a mock function with given fields: n
+func (_m *PrometheusBackend) SetPipelineTaskRunsQueued(n int) {
+ _m.Called(n)
+}
+
+// PrometheusBackend_SetPipelineTaskRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineTaskRunsQueued'
+type PrometheusBackend_SetPipelineTaskRunsQueued_Call struct {
+ *mock.Call
+}
+
+// SetPipelineTaskRunsQueued is a helper method to define mock.On call
+// - n int
+func (_e *PrometheusBackend_Expecter) SetPipelineTaskRunsQueued(n interface{}) *PrometheusBackend_SetPipelineTaskRunsQueued_Call {
+ return &PrometheusBackend_SetPipelineTaskRunsQueued_Call{Call: _e.mock.On("SetPipelineTaskRunsQueued", n)}
+}
+
+func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) Run(run func(n int)) *PrometheusBackend_SetPipelineTaskRunsQueued_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(int))
+ })
+ return _c
+}
+
+func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) Return() *PrometheusBackend_SetPipelineTaskRunsQueued_Call {
+ _c.Call.Return()
+ return _c
+}
+
+func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) RunAndReturn(run func(int)) *PrometheusBackend_SetPipelineTaskRunsQueued_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// SetUnconfirmedTransactions provides a mock function with given fields: _a0, _a1
+func (_m *PrometheusBackend) SetUnconfirmedTransactions(_a0 *big.Int, _a1 int64) {
+ _m.Called(_a0, _a1)
+}
+
+// PrometheusBackend_SetUnconfirmedTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetUnconfirmedTransactions'
+type PrometheusBackend_SetUnconfirmedTransactions_Call struct {
+ *mock.Call
+}
+
+// SetUnconfirmedTransactions is a helper method to define mock.On call
+// - _a0 *big.Int
+// - _a1 int64
+func (_e *PrometheusBackend_Expecter) SetUnconfirmedTransactions(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetUnconfirmedTransactions_Call {
+ return &PrometheusBackend_SetUnconfirmedTransactions_Call{Call: _e.mock.On("SetUnconfirmedTransactions", _a0, _a1)}
+}
+
+func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) Run(run func(_a0 *big.Int, _a1 int64)) *PrometheusBackend_SetUnconfirmedTransactions_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(*big.Int), args[1].(int64))
+ })
+ return _c
+}
+
+func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) Return() *PrometheusBackend_SetUnconfirmedTransactions_Call {
+ _c.Call.Return()
+ return _c
+}
+
+func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) RunAndReturn(run func(*big.Int, int64)) *PrometheusBackend_SetUnconfirmedTransactions_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// NewPrometheusBackend creates a new instance of PrometheusBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewPrometheusBackend(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *PrometheusBackend {
+ mock := &PrometheusBackend{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/core/scripts/go.mod b/core/scripts/go.mod
index 7ee9ff2513..ac50bc8655 100644
--- a/core/scripts/go.mod
+++ b/core/scripts/go.mod
@@ -24,7 +24,7 @@ require (
github.com/shopspring/decimal v1.4.0
github.com/smartcontractkit/chain-selectors v1.0.23
github.com/smartcontractkit/chainlink-automation v1.0.4
- github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834
+ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1
github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000
github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7
github.com/spf13/cobra v1.8.0
@@ -320,7 +320,7 @@ require (
go.mongodb.org/mongo-driver v1.15.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
@@ -330,12 +330,12 @@ require (
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/ratelimit v0.3.0 // indirect
go.uber.org/zap v1.27.0 // indirect
- golang.org/x/arch v0.7.0 // indirect
+ golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/mod v0.19.0 // indirect
golang.org/x/net v0.27.0 // indirect
- golang.org/x/oauth2 v0.20.0 // indirect
+ golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/term v0.22.0 // indirect
@@ -343,7 +343,7 @@ require (
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.23.0 // indirect
gonum.org/v1/gonum v0.15.0 // indirect
- google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
+ google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect
google.golang.org/grpc v1.65.0 // indirect
diff --git a/core/scripts/go.sum b/core/scripts/go.sum
index 192357740f..db4c3cd316 100644
--- a/core/scripts/go.sum
+++ b/core/scripts/go.sum
@@ -10,27 +10,31 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
-cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
-cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
+cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14=
+cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
+cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s=
+cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs=
+cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI=
+cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
-cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg=
-cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
-cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
+cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA=
+cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
+cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
-cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc=
-cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=
+cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw=
+cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
-cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg=
-cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY=
+cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs=
+cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0=
contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo=
@@ -1070,8 +1074,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj
github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8=
github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM=
-github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI=
-github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo=
+github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 h1:pdEpjgbZ5w/Sd5lzg/XiuC5gVyrmSovOo+3nUD46SP8=
+github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs=
github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk=
@@ -1261,10 +1265,10 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg=
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03y3dZcGhC/FepKtEUY=
go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
@@ -1277,8 +1281,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
-go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
-go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q=
+go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08=
+go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg=
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
@@ -1313,8 +1317,8 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
-golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
-golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
+golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -1426,8 +1430,8 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
-golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
+golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1610,8 +1614,8 @@ google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
-google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY=
-google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg=
+google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw=
+google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1643,8 +1647,8 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
-google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
+google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc=
+google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY=
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A=
diff --git a/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go b/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go
index 338a582a76..8762241543 100644
--- a/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go
+++ b/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go
@@ -8,15 +8,19 @@ import (
"log"
"os"
"strings"
+ "time"
"github.com/ethereum/go-ethereum/common"
ragetypes "github.com/smartcontractkit/libocr/ragep2p/types"
"google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/durationpb"
+
+ capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"
+ "github.com/smartcontractkit/chainlink-common/pkg/values"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
helpers "github.com/smartcontractkit/chainlink/core/scripts/common"
- remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types"
kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
)
@@ -162,6 +166,12 @@ func peerToNode(nopID uint32, p peer) (kcr.CapabilitiesRegistryNodeParams, error
}, nil
}
+func newCapabilityConfig() *capabilitiespb.CapabilityConfig {
+ return &capabilitiespb.CapabilityConfig{
+ DefaultConfig: values.Proto(values.EmptyMap()).GetMapValue(),
+ }
+}
+
// Run expects the following environment variables to be set:
//
// 1. Deploys the CapabilitiesRegistry contract
@@ -308,9 +318,16 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) {
panic(err)
}
+ cc := newCapabilityConfig()
+ ccb, err := proto.Marshal(cc)
+ if err != nil {
+ panic(err)
+ }
+
cfgs := []kcr.CapabilitiesRegistryCapabilityConfiguration{
{
CapabilityId: ocrid,
+ Config: ccb,
},
}
_, err = reg.AddDON(env.Owner, ps, cfgs, true, true, 2)
@@ -324,11 +341,16 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) {
panic(err)
}
- config := &remotetypes.RemoteTriggerConfig{
- RegistrationRefreshMs: 20000,
- RegistrationExpiryMs: 60000,
- // F + 1
- MinResponsesToAggregate: uint32(1) + 1,
+ config := &capabilitiespb.CapabilityConfig{
+ DefaultConfig: values.Proto(values.EmptyMap()).GetMapValue(),
+ RemoteConfig: &capabilitiespb.CapabilityConfig_RemoteTriggerConfig{
+ RemoteTriggerConfig: &capabilitiespb.RemoteTriggerConfig{
+ RegistrationRefresh: durationpb.New(20 * time.Second),
+ RegistrationExpiry: durationpb.New(60 * time.Second),
+ // F + 1
+ MinResponsesToAggregate: uint32(1) + 1,
+ },
+ },
}
configb, err := proto.Marshal(config)
if err != nil {
@@ -351,9 +373,16 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) {
panic(err)
}
+ cc = newCapabilityConfig()
+ ccb, err = proto.Marshal(cc)
+ if err != nil {
+ panic(err)
+ }
+
cfgs = []kcr.CapabilitiesRegistryCapabilityConfiguration{
{
CapabilityId: wid,
+ Config: ccb,
},
}
_, err = reg.AddDON(env.Owner, ps, cfgs, true, false, 1)
diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go
index 94619b7ce6..e880ecfad2 100644
--- a/core/services/chainlink/application.go
+++ b/core/services/chainlink/application.go
@@ -17,19 +17,21 @@ import (
"go.uber.org/multierr"
"go.uber.org/zap/zapcore"
- pkgcapabilities "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
"github.com/smartcontractkit/chainlink-common/pkg/loop"
commonservices "github.com/smartcontractkit/chainlink-common/pkg/services"
"github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
- coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core"
"github.com/smartcontractkit/chainlink-common/pkg/utils"
"github.com/smartcontractkit/chainlink-common/pkg/utils/jsonserializable"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
+
"github.com/smartcontractkit/chainlink/v2/core/capabilities"
+ remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
"github.com/smartcontractkit/chainlink/v2/core/services/standardcapabilities"
"github.com/smartcontractkit/chainlink/v2/core/static"
+ "github.com/smartcontractkit/chainlink/v2/core/services/promreporter"
+
"github.com/smartcontractkit/chainlink/v2/core/bridges"
"github.com/smartcontractkit/chainlink/v2/core/build"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/remote"
@@ -47,7 +49,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/feeds"
"github.com/smartcontractkit/chainlink/v2/core/services/fluxmonitorv2"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway"
- "github.com/smartcontractkit/chainlink/v2/core/services/headreporter"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/keeper"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
@@ -180,7 +181,9 @@ type ApplicationOpts struct {
LoopRegistry *plugins.LoopRegistry
GRPCOpts loop.GRPCOpts
MercuryPool wsrpc.Pool
- CapabilitiesRegistry coretypes.CapabilitiesRegistry
+ CapabilitiesRegistry *capabilities.Registry
+ CapabilitiesDispatcher remotetypes.Dispatcher
+ CapabilitiesPeerWrapper p2ptypes.PeerWrapper
}
// NewApplication initializes a new store if one is not already
@@ -200,23 +203,39 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
restrictedHTTPClient := opts.RestrictedHTTPClient
unrestrictedHTTPClient := opts.UnrestrictedHTTPClient
- if opts.CapabilitiesRegistry == nil { // for tests only, in prod Registry is always set at this point
+ if opts.CapabilitiesRegistry == nil {
+ // for tests only, in prod Registry should always be set at this point
opts.CapabilitiesRegistry = capabilities.NewRegistry(globalLogger)
}
var externalPeerWrapper p2ptypes.PeerWrapper
- var getLocalNode func(ctx context.Context) (pkgcapabilities.Node, error)
- var capabilityRegistrySyncer registrysyncer.Syncer
+ if cfg.Capabilities().Peering().Enabled() {
+ var dispatcher remotetypes.Dispatcher
+ if opts.CapabilitiesDispatcher == nil {
+ externalPeer := externalp2p.NewExternalPeerWrapper(keyStore.P2P(), cfg.Capabilities().Peering(), opts.DS, globalLogger)
+ signer := externalPeer
+ externalPeerWrapper = externalPeer
+ remoteDispatcher := remote.NewDispatcher(externalPeerWrapper, signer, opts.CapabilitiesRegistry, globalLogger)
+ srvcs = append(srvcs, remoteDispatcher)
+
+ dispatcher = remoteDispatcher
+ } else {
+ dispatcher = opts.CapabilitiesDispatcher
+ externalPeerWrapper = opts.CapabilitiesPeerWrapper
+ }
+
+ srvcs = append(srvcs, externalPeerWrapper)
- if cfg.Capabilities().ExternalRegistry().Address() != "" {
rid := cfg.Capabilities().ExternalRegistry().RelayID()
registryAddress := cfg.Capabilities().ExternalRegistry().Address()
relayer, err := relayerChainInterops.Get(rid)
if err != nil {
return nil, fmt.Errorf("could not fetch relayer %s configured for capabilities registry: %w", rid, err)
}
+
registrySyncer, err := registrysyncer.New(
globalLogger,
+ externalPeerWrapper,
relayer,
registryAddress,
)
@@ -224,32 +243,15 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
return nil, fmt.Errorf("could not configure syncer: %w", err)
}
- capabilityRegistrySyncer = registrySyncer
- srvcs = append(srvcs, capabilityRegistrySyncer)
- }
-
- if cfg.Capabilities().Peering().Enabled() {
- if capabilityRegistrySyncer == nil {
- return nil, errors.Errorf("peering enabled but no capability registry found")
- }
- externalPeer := externalp2p.NewExternalPeerWrapper(keyStore.P2P(), cfg.Capabilities().Peering(), opts.DS, globalLogger)
- signer := externalPeer
- externalPeerWrapper = externalPeer
-
- srvcs = append(srvcs, externalPeerWrapper)
-
- dispatcher := remote.NewDispatcher(externalPeerWrapper, signer, opts.CapabilitiesRegistry, globalLogger)
-
wfLauncher := capabilities.NewLauncher(
globalLogger,
externalPeerWrapper,
dispatcher,
opts.CapabilitiesRegistry,
)
+ registrySyncer.AddLauncher(wfLauncher)
- capabilityRegistrySyncer.AddLauncher(wfLauncher)
- getLocalNode = wfLauncher.LocalNode
- srvcs = append(srvcs, dispatcher, wfLauncher)
+ srvcs = append(srvcs, dispatcher, wfLauncher, registrySyncer)
}
// LOOPs can be created as options, in the case of LOOP relayers, or
@@ -322,6 +324,8 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
srvcs = append(srvcs, mailMon)
srvcs = append(srvcs, relayerChainInterops.Services()...)
+ promReporter := promreporter.NewPromReporter(opts.DS, legacyEVMChains, globalLogger)
+ srvcs = append(srvcs, promReporter)
// Initialize Local Users ORM and Authentication Provider specified in config
// BasicAdminUsersORM is initialized and required regardless of separate Authentication Provider
@@ -361,16 +365,8 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
workflowORM = workflowstore.NewDBStore(opts.DS, globalLogger, clockwork.NewRealClock())
)
- promReporter := headreporter.NewPrometheusReporter(opts.DS, legacyEVMChains)
- chainIDs := make([]*big.Int, legacyEVMChains.Len())
- for i, chain := range legacyEVMChains.Slice() {
- chainIDs[i] = chain.ID()
- }
- telemReporter := headreporter.NewTelemetryReporter(telemetryManager, globalLogger, chainIDs...)
- headReporter := headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter)
- srvcs = append(srvcs, headReporter)
for _, chain := range legacyEVMChains.Slice() {
- chain.HeadBroadcaster().Subscribe(headReporter)
+ chain.HeadBroadcaster().Subscribe(promReporter)
chain.TxManager().RegisterResumeCallback(pipelineRunner.ResumeRun)
}
@@ -446,7 +442,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
globalLogger,
opts.CapabilitiesRegistry,
workflowORM,
- getLocalNode,
)
// Flux monitor requires ethereum just to boot, silence errors with a null delegate
diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go
index aaf458c76c..5aaf6e16dd 100644
--- a/core/services/chainlink/relayer_chain_interoperators_test.go
+++ b/core/services/chainlink/relayer_chain_interoperators_test.go
@@ -13,6 +13,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/loop"
"github.com/smartcontractkit/chainlink-common/pkg/types"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
+ "github.com/smartcontractkit/chainlink/v2/core/capabilities"
coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config"
solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config"
@@ -174,9 +175,10 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
lggr := logger.TestLogger(t)
factory := chainlink.RelayerFactory{
- Logger: lggr,
- LoopRegistry: plugins.NewLoopRegistry(lggr, nil),
- GRPCOpts: loop.GRPCOpts{},
+ Logger: lggr,
+ LoopRegistry: plugins.NewLoopRegistry(lggr, nil),
+ GRPCOpts: loop.GRPCOpts{},
+ CapabilitiesRegistry: capabilities.NewRegistry(lggr),
}
testctx := testutils.Context(t)
diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go
index ae222f56c6..849964f9be 100644
--- a/core/services/chainlink/relayer_factory.go
+++ b/core/services/chainlink/relayer_factory.go
@@ -11,6 +11,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay"
"github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink-common/pkg/types"
+ coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core"
"github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos"
coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config"
"github.com/smartcontractkit/chainlink-solana/pkg/solana"
@@ -18,8 +19,6 @@ import (
pkgstarknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink"
starkchain "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/chain"
"github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config"
-
- "github.com/smartcontractkit/chainlink/v2/core/capabilities"
"github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm"
coreconfig "github.com/smartcontractkit/chainlink/v2/core/config"
"github.com/smartcontractkit/chainlink/v2/core/config/env"
@@ -37,7 +36,7 @@ type RelayerFactory struct {
*plugins.LoopRegistry
loop.GRPCOpts
MercuryPool wsrpc.Pool
- CapabilitiesRegistry *capabilities.Registry
+ CapabilitiesRegistry coretypes.CapabilitiesRegistry
}
type DummyFactoryConfig struct {
diff --git a/core/services/functions/connector_handler_test.go b/core/services/functions/connector_handler_test.go
index 7e1f3ced34..a24139da58 100644
--- a/core/services/functions/connector_handler_test.go
+++ b/core/services/functions/connector_handler_test.go
@@ -269,7 +269,10 @@ func TestFunctionsConnectorHandler(t *testing.T) {
// first call to trigger the request
var response functions.HeartbeatResponse
allowlist.On("Allow", addr).Return(true).Once()
- listener.On("HandleOffchainRequest", mock.Anything, mock.Anything).Return(nil).Once()
+ handlerCalled := make(chan struct{})
+ listener.On("HandleOffchainRequest", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ handlerCalled <- struct{}{}
+ }).Return(nil).Once()
connector.On("SendToGateway", mock.Anything, "gw1", mock.Anything).Run(func(args mock.Arguments) {
respMsg, ok := args[2].(*api.Message)
require.True(t, ok)
@@ -277,6 +280,7 @@ func TestFunctionsConnectorHandler(t *testing.T) {
require.Equal(t, functions.RequestStatePending, response.Status)
}).Return(nil).Once()
handler.HandleGatewayMessage(ctx, "gw1", msg)
+ <-handlerCalled
// async response computation
reportCh <- &functions.OffchainResponse{
@@ -304,9 +308,13 @@ func TestFunctionsConnectorHandler(t *testing.T) {
// first call to trigger the request
var response functions.HeartbeatResponse
allowlist.On("Allow", addr).Return(true).Once()
- listener.On("HandleOffchainRequest", mock.Anything, mock.Anything).Return(errors.New("boom")).Once()
+ handlerCalled := make(chan struct{})
+ listener.On("HandleOffchainRequest", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ handlerCalled <- struct{}{}
+ }).Return(errors.New("boom")).Once()
connector.On("SendToGateway", mock.Anything, "gw1", mock.Anything).Return(nil).Once()
handler.HandleGatewayMessage(ctx, "gw1", msg)
+ <-handlerCalled
// collect the response - should eventually result in an internal error
gomega.NewGomegaWithT(t).Eventually(func() bool {
diff --git a/core/services/headreporter/head_reporter.go b/core/services/headreporter/head_reporter.go
deleted file mode 100644
index 94de8ae2be..0000000000
--- a/core/services/headreporter/head_reporter.go
+++ /dev/null
@@ -1,111 +0,0 @@
-package headreporter
-
-import (
- "context"
- "sync"
- "time"
-
- "github.com/smartcontractkit/chainlink-common/pkg/services"
- "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
- "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
-
- "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types"
- evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
-)
-
-type (
- HeadReporter interface {
- ReportNewHead(ctx context.Context, head *evmtypes.Head) error
- ReportPeriodic(ctx context.Context) error
- }
-
- HeadReporterService struct {
- services.StateMachine
- ds sqlutil.DataSource
- lggr logger.Logger
- newHeads *mailbox.Mailbox[*evmtypes.Head]
- chStop services.StopChan
- wgDone sync.WaitGroup
- reportPeriod time.Duration
- reporters []HeadReporter
- unsubscribeFns []func()
- }
-)
-
-func NewHeadReporterService(ds sqlutil.DataSource, lggr logger.Logger, reporters ...HeadReporter) *HeadReporterService {
- return &HeadReporterService{
- ds: ds,
- lggr: lggr.Named("HeadReporter"),
- newHeads: mailbox.NewSingle[*evmtypes.Head](),
- chStop: make(chan struct{}),
- reporters: reporters,
- reportPeriod: 15 * time.Second,
- }
-}
-
-func (hrd *HeadReporterService) Subscribe(subFn func(types.HeadTrackable) (evmtypes.Head, func())) {
- _, unsubscribe := subFn(hrd)
- hrd.unsubscribeFns = append(hrd.unsubscribeFns, unsubscribe)
-}
-
-func (hrd *HeadReporterService) Start(context.Context) error {
- return hrd.StartOnce(hrd.Name(), func() error {
- hrd.wgDone.Add(1)
- go hrd.eventLoop()
- return nil
- })
-}
-
-func (hrd *HeadReporterService) Close() error {
- return hrd.StopOnce(hrd.Name(), func() error {
- close(hrd.chStop)
- hrd.wgDone.Wait()
- return nil
- })
-}
-
-func (hrd *HeadReporterService) Name() string {
- return hrd.lggr.Name()
-}
-
-func (hrd *HeadReporterService) HealthReport() map[string]error {
- return map[string]error{hrd.Name(): hrd.Healthy()}
-}
-
-func (hrd *HeadReporterService) OnNewLongestChain(ctx context.Context, head *evmtypes.Head) {
- hrd.newHeads.Deliver(head)
-}
-
-func (hrd *HeadReporterService) eventLoop() {
- hrd.lggr.Debug("Starting event loop")
- defer hrd.wgDone.Done()
- ctx, cancel := hrd.chStop.NewCtx()
- defer cancel()
- after := time.After(hrd.reportPeriod)
- for {
- select {
- case <-hrd.newHeads.Notify():
- head, exists := hrd.newHeads.Retrieve()
- if !exists {
- continue
- }
- for _, reporter := range hrd.reporters {
- err := reporter.ReportNewHead(ctx, head)
- if err != nil && ctx.Err() == nil {
- hrd.lggr.Errorw("Error reporting new head", "err", err)
- }
- }
- case <-after:
- for _, reporter := range hrd.reporters {
- err := reporter.ReportPeriodic(ctx)
- if err != nil && ctx.Err() == nil {
- hrd.lggr.Errorw("Error in periodic report", "err", err)
- }
- }
- after = time.After(hrd.reportPeriod)
- case <-hrd.chStop:
- return
- }
- }
-}
diff --git a/core/services/headreporter/head_reporter_mock.go b/core/services/headreporter/head_reporter_mock.go
deleted file mode 100644
index 21978abb86..0000000000
--- a/core/services/headreporter/head_reporter_mock.go
+++ /dev/null
@@ -1,130 +0,0 @@
-// Code generated by mockery v2.43.2. DO NOT EDIT.
-
-package headreporter
-
-import (
- context "context"
-
- types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
- mock "github.com/stretchr/testify/mock"
-)
-
-// MockHeadReporter is an autogenerated mock type for the HeadReporter type
-type MockHeadReporter struct {
- mock.Mock
-}
-
-type MockHeadReporter_Expecter struct {
- mock *mock.Mock
-}
-
-func (_m *MockHeadReporter) EXPECT() *MockHeadReporter_Expecter {
- return &MockHeadReporter_Expecter{mock: &_m.Mock}
-}
-
-// ReportNewHead provides a mock function with given fields: ctx, head
-func (_m *MockHeadReporter) ReportNewHead(ctx context.Context, head *types.Head) error {
- ret := _m.Called(ctx, head)
-
- if len(ret) == 0 {
- panic("no return value specified for ReportNewHead")
- }
-
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, *types.Head) error); ok {
- r0 = rf(ctx, head)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// MockHeadReporter_ReportNewHead_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportNewHead'
-type MockHeadReporter_ReportNewHead_Call struct {
- *mock.Call
-}
-
-// ReportNewHead is a helper method to define mock.On call
-// - ctx context.Context
-// - head *types.Head
-func (_e *MockHeadReporter_Expecter) ReportNewHead(ctx interface{}, head interface{}) *MockHeadReporter_ReportNewHead_Call {
- return &MockHeadReporter_ReportNewHead_Call{Call: _e.mock.On("ReportNewHead", ctx, head)}
-}
-
-func (_c *MockHeadReporter_ReportNewHead_Call) Run(run func(ctx context.Context, head *types.Head)) *MockHeadReporter_ReportNewHead_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run(args[0].(context.Context), args[1].(*types.Head))
- })
- return _c
-}
-
-func (_c *MockHeadReporter_ReportNewHead_Call) Return(_a0 error) *MockHeadReporter_ReportNewHead_Call {
- _c.Call.Return(_a0)
- return _c
-}
-
-func (_c *MockHeadReporter_ReportNewHead_Call) RunAndReturn(run func(context.Context, *types.Head) error) *MockHeadReporter_ReportNewHead_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// ReportPeriodic provides a mock function with given fields: ctx
-func (_m *MockHeadReporter) ReportPeriodic(ctx context.Context) error {
- ret := _m.Called(ctx)
-
- if len(ret) == 0 {
- panic("no return value specified for ReportPeriodic")
- }
-
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context) error); ok {
- r0 = rf(ctx)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// MockHeadReporter_ReportPeriodic_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportPeriodic'
-type MockHeadReporter_ReportPeriodic_Call struct {
- *mock.Call
-}
-
-// ReportPeriodic is a helper method to define mock.On call
-// - ctx context.Context
-func (_e *MockHeadReporter_Expecter) ReportPeriodic(ctx interface{}) *MockHeadReporter_ReportPeriodic_Call {
- return &MockHeadReporter_ReportPeriodic_Call{Call: _e.mock.On("ReportPeriodic", ctx)}
-}
-
-func (_c *MockHeadReporter_ReportPeriodic_Call) Run(run func(ctx context.Context)) *MockHeadReporter_ReportPeriodic_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run(args[0].(context.Context))
- })
- return _c
-}
-
-func (_c *MockHeadReporter_ReportPeriodic_Call) Return(_a0 error) *MockHeadReporter_ReportPeriodic_Call {
- _c.Call.Return(_a0)
- return _c
-}
-
-func (_c *MockHeadReporter_ReportPeriodic_Call) RunAndReturn(run func(context.Context) error) *MockHeadReporter_ReportPeriodic_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// NewMockHeadReporter creates a new instance of MockHeadReporter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func NewMockHeadReporter(t interface {
- mock.TestingT
- Cleanup(func())
-}) *MockHeadReporter {
- mock := &MockHeadReporter{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/core/services/headreporter/head_reporter_test.go b/core/services/headreporter/head_reporter_test.go
deleted file mode 100644
index 304dd59a47..0000000000
--- a/core/services/headreporter/head_reporter_test.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package headreporter
-
-import (
- "sync/atomic"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/mock"
- "github.com/stretchr/testify/require"
-
- evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
- ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
-
- "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
- "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
-)
-
-func NewHead() evmtypes.Head {
- return evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(0)}
-}
-
-func Test_HeadReporterService(t *testing.T) {
- t.Run("report everything", func(t *testing.T) {
- db := pgtest.NewSqlxDB(t)
-
- headReporter := NewMockHeadReporter(t)
- service := NewHeadReporterService(db, logger.TestLogger(t), headReporter)
- service.reportPeriod = time.Second
- err := service.Start(testutils.Context(t))
- require.NoError(t, err)
-
- var reportCalls atomic.Int32
- head := NewHead()
- headReporter.On("ReportNewHead", mock.Anything, &head).Run(func(args mock.Arguments) {
- reportCalls.Add(1)
- }).Return(nil)
- headReporter.On("ReportPeriodic", mock.Anything).Run(func(args mock.Arguments) {
- reportCalls.Add(1)
- }).Return(nil)
- service.OnNewLongestChain(testutils.Context(t), &head)
-
- require.Eventually(t, func() bool { return reportCalls.Load() == 2 }, 5*time.Second, 100*time.Millisecond)
- })
-
- t.Run("has default report period", func(t *testing.T) {
- service := NewHeadReporterService(pgtest.NewSqlxDB(t), logger.TestLogger(t), NewMockHeadReporter(t))
- assert.Equal(t, service.reportPeriod, 15*time.Second)
- })
-}
diff --git a/core/services/headreporter/helper_test.go b/core/services/headreporter/helper_test.go
deleted file mode 100644
index fa05182a85..0000000000
--- a/core/services/headreporter/helper_test.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package headreporter
-
-func (p *prometheusReporter) SetBackend(b PrometheusBackend) {
- p.backend = b
-}
diff --git a/core/services/headreporter/prometheus_backend_mock.go b/core/services/headreporter/prometheus_backend_mock.go
deleted file mode 100644
index ca83f6c4fb..0000000000
--- a/core/services/headreporter/prometheus_backend_mock.go
+++ /dev/null
@@ -1,204 +0,0 @@
-// Code generated by mockery v2.43.2. DO NOT EDIT.
-
-package headreporter
-
-import (
- big "math/big"
-
- mock "github.com/stretchr/testify/mock"
-)
-
-// MockPrometheusBackend is an autogenerated mock type for the PrometheusBackend type
-type MockPrometheusBackend struct {
- mock.Mock
-}
-
-type MockPrometheusBackend_Expecter struct {
- mock *mock.Mock
-}
-
-func (_m *MockPrometheusBackend) EXPECT() *MockPrometheusBackend_Expecter {
- return &MockPrometheusBackend_Expecter{mock: &_m.Mock}
-}
-
-// SetMaxUnconfirmedAge provides a mock function with given fields: _a0, _a1
-func (_m *MockPrometheusBackend) SetMaxUnconfirmedAge(_a0 *big.Int, _a1 float64) {
- _m.Called(_a0, _a1)
-}
-
-// MockPrometheusBackend_SetMaxUnconfirmedAge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedAge'
-type MockPrometheusBackend_SetMaxUnconfirmedAge_Call struct {
- *mock.Call
-}
-
-// SetMaxUnconfirmedAge is a helper method to define mock.On call
-// - _a0 *big.Int
-// - _a1 float64
-func (_e *MockPrometheusBackend_Expecter) SetMaxUnconfirmedAge(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call {
- return &MockPrometheusBackend_SetMaxUnconfirmedAge_Call{Call: _e.mock.On("SetMaxUnconfirmedAge", _a0, _a1)}
-}
-
-func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) Run(run func(_a0 *big.Int, _a1 float64)) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run(args[0].(*big.Int), args[1].(float64))
- })
- return _c
-}
-
-func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) Return() *MockPrometheusBackend_SetMaxUnconfirmedAge_Call {
- _c.Call.Return()
- return _c
-}
-
-func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) RunAndReturn(run func(*big.Int, float64)) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// SetMaxUnconfirmedBlocks provides a mock function with given fields: _a0, _a1
-func (_m *MockPrometheusBackend) SetMaxUnconfirmedBlocks(_a0 *big.Int, _a1 int64) {
- _m.Called(_a0, _a1)
-}
-
-// MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedBlocks'
-type MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call struct {
- *mock.Call
-}
-
-// SetMaxUnconfirmedBlocks is a helper method to define mock.On call
-// - _a0 *big.Int
-// - _a1 int64
-func (_e *MockPrometheusBackend_Expecter) SetMaxUnconfirmedBlocks(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call {
- return &MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call{Call: _e.mock.On("SetMaxUnconfirmedBlocks", _a0, _a1)}
-}
-
-func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) Run(run func(_a0 *big.Int, _a1 int64)) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run(args[0].(*big.Int), args[1].(int64))
- })
- return _c
-}
-
-func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) Return() *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call {
- _c.Call.Return()
- return _c
-}
-
-func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) RunAndReturn(run func(*big.Int, int64)) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// SetPipelineRunsQueued provides a mock function with given fields: n
-func (_m *MockPrometheusBackend) SetPipelineRunsQueued(n int) {
- _m.Called(n)
-}
-
-// MockPrometheusBackend_SetPipelineRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineRunsQueued'
-type MockPrometheusBackend_SetPipelineRunsQueued_Call struct {
- *mock.Call
-}
-
-// SetPipelineRunsQueued is a helper method to define mock.On call
-// - n int
-func (_e *MockPrometheusBackend_Expecter) SetPipelineRunsQueued(n interface{}) *MockPrometheusBackend_SetPipelineRunsQueued_Call {
- return &MockPrometheusBackend_SetPipelineRunsQueued_Call{Call: _e.mock.On("SetPipelineRunsQueued", n)}
-}
-
-func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) Run(run func(n int)) *MockPrometheusBackend_SetPipelineRunsQueued_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run(args[0].(int))
- })
- return _c
-}
-
-func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) Return() *MockPrometheusBackend_SetPipelineRunsQueued_Call {
- _c.Call.Return()
- return _c
-}
-
-func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) RunAndReturn(run func(int)) *MockPrometheusBackend_SetPipelineRunsQueued_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// SetPipelineTaskRunsQueued provides a mock function with given fields: n
-func (_m *MockPrometheusBackend) SetPipelineTaskRunsQueued(n int) {
- _m.Called(n)
-}
-
-// MockPrometheusBackend_SetPipelineTaskRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineTaskRunsQueued'
-type MockPrometheusBackend_SetPipelineTaskRunsQueued_Call struct {
- *mock.Call
-}
-
-// SetPipelineTaskRunsQueued is a helper method to define mock.On call
-// - n int
-func (_e *MockPrometheusBackend_Expecter) SetPipelineTaskRunsQueued(n interface{}) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call {
- return &MockPrometheusBackend_SetPipelineTaskRunsQueued_Call{Call: _e.mock.On("SetPipelineTaskRunsQueued", n)}
-}
-
-func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) Run(run func(n int)) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run(args[0].(int))
- })
- return _c
-}
-
-func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) Return() *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call {
- _c.Call.Return()
- return _c
-}
-
-func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) RunAndReturn(run func(int)) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// SetUnconfirmedTransactions provides a mock function with given fields: _a0, _a1
-func (_m *MockPrometheusBackend) SetUnconfirmedTransactions(_a0 *big.Int, _a1 int64) {
- _m.Called(_a0, _a1)
-}
-
-// MockPrometheusBackend_SetUnconfirmedTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetUnconfirmedTransactions'
-type MockPrometheusBackend_SetUnconfirmedTransactions_Call struct {
- *mock.Call
-}
-
-// SetUnconfirmedTransactions is a helper method to define mock.On call
-// - _a0 *big.Int
-// - _a1 int64
-func (_e *MockPrometheusBackend_Expecter) SetUnconfirmedTransactions(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetUnconfirmedTransactions_Call {
- return &MockPrometheusBackend_SetUnconfirmedTransactions_Call{Call: _e.mock.On("SetUnconfirmedTransactions", _a0, _a1)}
-}
-
-func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) Run(run func(_a0 *big.Int, _a1 int64)) *MockPrometheusBackend_SetUnconfirmedTransactions_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run(args[0].(*big.Int), args[1].(int64))
- })
- return _c
-}
-
-func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) Return() *MockPrometheusBackend_SetUnconfirmedTransactions_Call {
- _c.Call.Return()
- return _c
-}
-
-func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) RunAndReturn(run func(*big.Int, int64)) *MockPrometheusBackend_SetUnconfirmedTransactions_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// NewMockPrometheusBackend creates a new instance of MockPrometheusBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func NewMockPrometheusBackend(t interface {
- mock.TestingT
- Cleanup(func())
-}) *MockPrometheusBackend {
- mock := &MockPrometheusBackend{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/core/services/headreporter/telemetry_reporter.go b/core/services/headreporter/telemetry_reporter.go
deleted file mode 100644
index 0d93ca59a4..0000000000
--- a/core/services/headreporter/telemetry_reporter.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package headreporter
-
-import (
- "context"
- "math/big"
-
- "github.com/pkg/errors"
-
- "github.com/smartcontractkit/libocr/commontypes"
- "google.golang.org/protobuf/proto"
-
- evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/synchronization"
- "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem"
- "github.com/smartcontractkit/chainlink/v2/core/services/telemetry"
-)
-
-type telemetryReporter struct {
- lggr logger.Logger
- endpoints map[uint64]commontypes.MonitoringEndpoint
-}
-
-func NewTelemetryReporter(monitoringEndpointGen telemetry.MonitoringEndpointGenerator, lggr logger.Logger, chainIDs ...*big.Int) HeadReporter {
- endpoints := make(map[uint64]commontypes.MonitoringEndpoint)
- for _, chainID := range chainIDs {
- endpoints[chainID.Uint64()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chainID.String(), "", synchronization.HeadReport)
- }
- return &telemetryReporter{lggr: lggr.Named("TelemetryReporter"), endpoints: endpoints}
-}
-
-func (t *telemetryReporter) ReportNewHead(ctx context.Context, head *evmtypes.Head) error {
- monitoringEndpoint := t.endpoints[head.EVMChainID.ToInt().Uint64()]
- if monitoringEndpoint == nil {
- return errors.Errorf("No monitoring endpoint provided chain_id=%d", head.EVMChainID.Int64())
- }
- var finalized *telem.Block
- latestFinalizedHead := head.LatestFinalizedHead()
- if latestFinalizedHead != nil {
- finalized = &telem.Block{
- Timestamp: uint64(latestFinalizedHead.GetTimestamp().UTC().Unix()),
- Number: uint64(latestFinalizedHead.BlockNumber()),
- Hash: latestFinalizedHead.BlockHash().Hex(),
- }
- }
- request := &telem.HeadReportRequest{
- ChainID: head.EVMChainID.String(),
- Latest: &telem.Block{
- Timestamp: uint64(head.Timestamp.UTC().Unix()),
- Number: uint64(head.Number),
- Hash: head.Hash.Hex(),
- },
- Finalized: finalized,
- }
- bytes, err := proto.Marshal(request)
- if err != nil {
- return errors.WithMessage(err, "telem.HeadReportRequest marshal error")
- }
- monitoringEndpoint.SendLog(bytes)
- if finalized == nil {
- t.lggr.Infow("No finalized block was found", "chainID", head.EVMChainID.Int64(),
- "head.number", head.Number, "chainLength", head.ChainLength())
- }
- return nil
-}
-
-func (t *telemetryReporter) ReportPeriodic(ctx context.Context) error {
- return nil
-}
diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go
deleted file mode 100644
index 85bfea5866..0000000000
--- a/core/services/headreporter/telemetry_reporter_test.go
+++ /dev/null
@@ -1,108 +0,0 @@
-package headreporter_test
-
-import (
- "math/big"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/stretchr/testify/assert"
- "google.golang.org/protobuf/proto"
-
- mocks2 "github.com/smartcontractkit/chainlink/v2/common/types/mocks"
- evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
- ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
- "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/headreporter"
- "github.com/smartcontractkit/chainlink/v2/core/services/synchronization"
- "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem"
- "github.com/smartcontractkit/chainlink/v2/core/services/telemetry"
-)
-
-func Test_TelemetryReporter_NewHead(t *testing.T) {
- head := evmtypes.Head{
- Number: 42,
- EVMChainID: ubig.NewI(100),
- Hash: common.HexToHash("0x1010"),
- Timestamp: time.UnixMilli(1000),
- IsFinalized: false,
- Parent: &evmtypes.Head{
- Number: 41,
- Hash: common.HexToHash("0x1009"),
- Timestamp: time.UnixMilli(999),
- IsFinalized: true,
- },
- }
- requestBytes, err := proto.Marshal(&telem.HeadReportRequest{
- ChainID: "100",
- Latest: &telem.Block{
- Timestamp: uint64(head.Timestamp.UTC().Unix()),
- Number: 42,
- Hash: head.Hash.Hex(),
- },
- Finalized: &telem.Block{
- Timestamp: uint64(head.Parent.Timestamp.UTC().Unix()),
- Number: 41,
- Hash: head.Parent.Hash.Hex(),
- },
- })
- assert.NoError(t, err)
-
- monitoringEndpoint := mocks2.NewMonitoringEndpoint(t)
- monitoringEndpoint.On("SendLog", requestBytes).Return()
-
- monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t)
- monitoringEndpointGen.
- On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport).
- Return(monitoringEndpoint)
- reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, logger.TestLogger(t), big.NewInt(100))
-
- err = reporter.ReportNewHead(testutils.Context(t), &head)
- assert.NoError(t, err)
-}
-
-func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) {
- head := evmtypes.Head{
- Number: 42,
- EVMChainID: ubig.NewI(100),
- Hash: common.HexToHash("0x1010"),
- Timestamp: time.UnixMilli(1000),
- IsFinalized: false,
- }
- requestBytes, err := proto.Marshal(&telem.HeadReportRequest{
- ChainID: "100",
- Latest: &telem.Block{
- Timestamp: uint64(head.Timestamp.UTC().Unix()),
- Number: 42,
- Hash: head.Hash.Hex(),
- },
- })
- assert.NoError(t, err)
-
- monitoringEndpoint := mocks2.NewMonitoringEndpoint(t)
- monitoringEndpoint.On("SendLog", requestBytes).Return()
-
- monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t)
- monitoringEndpointGen.
- On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport).
- Return(monitoringEndpoint)
- reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, logger.TestLogger(t), big.NewInt(100))
-
- err = reporter.ReportNewHead(testutils.Context(t), &head)
- assert.NoError(t, err)
-}
-
-func Test_TelemetryReporter_NewHead_MissingEndpoint(t *testing.T) {
- monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t)
- monitoringEndpointGen.
- On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport).
- Return(nil)
-
- reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, logger.TestLogger(t), big.NewInt(100))
-
- head := evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(100)}
-
- err := reporter.ReportNewHead(testutils.Context(t), &head)
- assert.Errorf(t, err, "No monitoring endpoint provided chain_id=100")
-}
diff --git a/core/services/job/helpers_test.go b/core/services/job/helpers_test.go
index d69056ae81..6f9bee66a0 100644
--- a/core/services/job/helpers_test.go
+++ b/core/services/job/helpers_test.go
@@ -71,7 +71,6 @@ maxServiceWorkers = 100
cacheEvictionInterval = "1s"
mercuryCredentialName = "%s"
contractVersion = "v2.1"
-useBufferV1 = %v
`
voterTurnoutDataSourceTemplate = `
// data source 1
@@ -277,7 +276,7 @@ func makeOCR2Keeper21JobSpec(t testing.TB, ks keystore.Master, transmitter commo
_, registry := cltest.MustInsertRandomKey(t, ks.Eth())
ocr2Keeper21Job := fmt.Sprintf(ocr2Keeper21JobSpecTemplate, registry.String(), kb.ID(), transmitter,
- fmt.Sprintf("%s127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), chainID, "mercury cred", false)
+ fmt.Sprintf("%s127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), chainID, "mercury cred")
jobSpec := makeOCR2JobSpecFromToml(t, ocr2Keeper21Job)
diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go
index 92d6cc65bc..7c99083a97 100644
--- a/core/services/ocr2/delegate.go
+++ b/core/services/ocr2/delegate.go
@@ -66,7 +66,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/autotelemetry21"
ocr2keeper21core "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core"
- "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider"
"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"
@@ -1188,14 +1187,6 @@ func (d *Delegate) newServicesOCR2Keepers21(
return nil, errors.New("could not coerce PluginProvider to AutomationProvider")
}
- // TODO: (AUTO-9355) remove once we remove v0
- if useBufferV1 := cfg.UseBufferV1 != nil && *cfg.UseBufferV1; useBufferV1 {
- logProviderFeatures, ok := keeperProvider.LogEventProvider().(logprovider.LogEventProviderFeatures)
- if ok {
- logProviderFeatures.WithBufferVersion("v1")
- }
- }
-
services, err := ocr2keeper.EVMDependencies21(kb)
if err != nil {
return nil, errors.Wrap(err, "could not build dependencies for ocr2 keepers")
diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go
index 73c5992470..bb2f6b0f7c 100644
--- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go
+++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go
@@ -38,6 +38,7 @@ import (
cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip"
+ evmcapabilities "github.com/smartcontractkit/chainlink/v2/core/capabilities"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
v2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
@@ -460,9 +461,10 @@ func setupNodeCCIP(
}
loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing())
relayerFactory := chainlink.RelayerFactory{
- Logger: lggr,
- LoopRegistry: loopRegistry,
- GRPCOpts: loop.GRPCOpts{},
+ Logger: lggr,
+ LoopRegistry: loopRegistry,
+ GRPCOpts: loop.GRPCOpts{},
+ CapabilitiesRegistry: evmcapabilities.NewRegistry(logger.TestLogger(t)),
}
testCtx := testutils.Context(t)
// evm alway enabled for backward compatibility
diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go
index 5099a4b57e..8d7a4551f1 100644
--- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go
+++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go
@@ -37,6 +37,7 @@ import (
cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip"
+ evmcapabilities "github.com/smartcontractkit/chainlink/v2/core/capabilities"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
v2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
@@ -457,9 +458,10 @@ func setupNodeCCIP(
}
loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing())
relayerFactory := chainlink.RelayerFactory{
- Logger: lggr,
- LoopRegistry: loopRegistry,
- GRPCOpts: loop.GRPCOpts{},
+ Logger: lggr,
+ LoopRegistry: loopRegistry,
+ GRPCOpts: loop.GRPCOpts{},
+ CapabilitiesRegistry: evmcapabilities.NewRegistry(lggr),
}
testCtx := testutils.Context(t)
// evm alway enabled for backward compatibility
diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go
index 49a79463a5..639d8ec04d 100644
--- a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go
+++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go
@@ -217,7 +217,9 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts,
}
var initialAllowedSenders []common.Address
var initialBlockedSenders []common.Address
- allowListAddress, _, allowListContract, err := functions_allow_list.DeployTermsOfServiceAllowList(owner, b, allowListConfig, initialAllowedSenders, initialBlockedSenders)
+ // The allowlist requires a pointer to the previous allowlist. If none exists, use the null address.
+ var nullPreviousAllowlist common.Address
+ allowListAddress, _, allowListContract, err := functions_allow_list.DeployTermsOfServiceAllowList(owner, b, allowListConfig, initialAllowedSenders, initialBlockedSenders, nullPreviousAllowlist)
require.NoError(t, err)
// Deploy Coordinator contract (matches updateConfig() in FunctionsBilling.sol)
diff --git a/core/services/ocr2/plugins/ocr2keeper/config.go b/core/services/ocr2/plugins/ocr2keeper/config.go
index 4b41e5a028..ec56f9c699 100644
--- a/core/services/ocr2/plugins/ocr2keeper/config.go
+++ b/core/services/ocr2/plugins/ocr2keeper/config.go
@@ -60,9 +60,6 @@ type PluginConfig struct {
ContractVersion string `json:"contractVersion"`
// CaptureAutomationCustomTelemetry is a bool flag to toggle Custom Telemetry Service
CaptureAutomationCustomTelemetry *bool `json:"captureAutomationCustomTelemetry,omitempty"`
- // UseBufferV1 is a bool flag to toggle the new log buffer implementation
- // TODO: (AUTO-9355) remove once we have a single version
- UseBufferV1 *bool `json:"useBufferV1,omitempty"`
}
func ValidatePluginConfig(cfg PluginConfig) error {
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer.go
deleted file mode 100644
index af934a0801..0000000000
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer.go
+++ /dev/null
@@ -1,388 +0,0 @@
-package logprovider
-
-import (
- "encoding/hex"
- "math/big"
- "sort"
- "sync"
- "sync/atomic"
-
- "github.com/smartcontractkit/chainlink-automation/pkg/v3/random"
- ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation"
-
- "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics"
-)
-
-var (
- // defaultFastExecLogsHigh is the default upper bound / maximum number of logs that Automation is committed to process for each upkeep,
- // based on available capacity, i.e. if there are no logs from other upkeeps.
- // Used by Log buffer to limit the number of logs we are saving in memory for each upkeep in a block
- defaultFastExecLogsHigh = 32
- // defaultNumOfLogUpkeeps is the default number of log upkeeps supported by the registry.
- defaultNumOfLogUpkeeps = 50
-)
-
-// fetchedLog holds the log and the ID of the upkeep
-type fetchedLog struct {
- upkeepID *big.Int
- log logpoller.Log
- // cachedLogID is the cached log identifier, used for sorting.
- // It is calculated lazily, and cached for performance.
- cachedLogID string
-}
-
-func (l *fetchedLog) getLogID() string {
- if len(l.cachedLogID) == 0 {
- ext := ocr2keepers.LogTriggerExtension{
- Index: uint32(l.log.LogIndex),
- }
- copy(ext.TxHash[:], l.log.TxHash[:])
- copy(ext.BlockHash[:], l.log.BlockHash[:])
- l.cachedLogID = hex.EncodeToString(ext.LogIdentifier())
- }
- return l.cachedLogID
-}
-
-// fetchedBlock holds the logs fetched for a block
-type fetchedBlock struct {
- blockNumber int64
- // logs is the logs fetched for the block and haven't been visited yet
- logs []fetchedLog
- // visited is the logs fetched for the block and have been visited.
- // We keep them in order to avoid fetching them again.
- visited []fetchedLog
-}
-
-func (b *fetchedBlock) Append(lggr logger.Logger, fl fetchedLog, maxBlockLogs, maxUpkeepLogs int) (fetchedLog, bool) {
- has, upkeepLogs := b.has(fl.upkeepID, fl.log)
- if has {
- // Skipping known logs
- return fetchedLog{}, false
- }
- // lggr.Debugw("Adding log", "i", i, "blockBlock", currentBlock.blockNumber, "logBlock", log.BlockNumber, "id", id)
- b.logs = append(b.logs, fl)
-
- // drop logs if we reached limits.
- if upkeepLogs+1 > maxUpkeepLogs {
- // in case we have logs overflow for a particular upkeep, we drop a log of that upkeep,
- // based on shared, random (per block) order of the logs in the block.
- b.Sort()
- var dropped fetchedLog
- currentLogs := make([]fetchedLog, 0, len(b.logs)-1)
- for _, l := range b.logs {
- if dropped.upkeepID == nil && l.upkeepID.Cmp(fl.upkeepID) == 0 {
- dropped = l
- continue
- }
- currentLogs = append(currentLogs, l)
- }
- b.logs = currentLogs
- return dropped, true
- } else if len(b.logs)+len(b.visited) > maxBlockLogs {
- // in case we have logs overflow in the buffer level, we drop a log based on
- // shared, random (per block) order of the logs in the block.
- b.Sort()
- dropped := b.logs[0]
- b.logs = b.logs[1:]
- return dropped, true
- }
-
- return fetchedLog{}, true
-}
-
-// Has returns true if the block has the log,
-// and the number of logs for that upkeep in the block.
-func (b fetchedBlock) has(id *big.Int, log logpoller.Log) (bool, int) {
- allLogs := append(b.logs, b.visited...)
- upkeepLogs := 0
- for _, l := range allLogs {
- if l.upkeepID.Cmp(id) != 0 {
- continue
- }
- upkeepLogs++
- if l.log.BlockHash == log.BlockHash && l.log.TxHash == log.TxHash && l.log.LogIndex == log.LogIndex {
- return true, upkeepLogs
- }
- }
- return false, upkeepLogs
-}
-
-func (b fetchedBlock) Clone() fetchedBlock {
- logs := make([]fetchedLog, len(b.logs))
- copy(logs, b.logs)
- visited := make([]fetchedLog, len(b.visited))
- copy(visited, b.visited)
- return fetchedBlock{
- blockNumber: b.blockNumber,
- logs: logs,
- visited: visited,
- }
-}
-
-// Sort by log identifiers, shuffled using a pseduorandom souce that is shared across all nodes
-// for a given block.
-func (b *fetchedBlock) Sort() {
- randSeed := random.GetRandomKeySource(nil, uint64(b.blockNumber))
-
- shuffledLogIDs := make(map[string]string, len(b.logs))
- for _, log := range b.logs {
- logID := log.getLogID()
- shuffledLogIDs[logID] = random.ShuffleString(logID, randSeed)
- }
-
- sort.SliceStable(b.logs, func(i, j int) bool {
- return shuffledLogIDs[b.logs[i].getLogID()] < shuffledLogIDs[b.logs[j].getLogID()]
- })
-}
-
-// logEventBuffer is a circular/ring buffer of fetched logs.
-// Each entry in the buffer represents a block,
-// and holds the logs fetched for that block.
-type logEventBuffer struct {
- lggr logger.Logger
- lock sync.RWMutex
- // size is the number of blocks supported by the buffer
- size int32
-
- numOfLogUpkeeps, fastExecLogsHigh uint32
- // blocks is the circular buffer of fetched blocks
- blocks []fetchedBlock
- // latestBlock is the latest block number seen
- latestBlock int64
-}
-
-func newLogEventBuffer(lggr logger.Logger, size, numOfLogUpkeeps, fastExecLogsHigh int) *logEventBuffer {
- return &logEventBuffer{
- lggr: lggr.Named("KeepersRegistry.LogEventBuffer"),
- size: int32(size),
- blocks: make([]fetchedBlock, size),
- numOfLogUpkeeps: uint32(numOfLogUpkeeps),
- fastExecLogsHigh: uint32(fastExecLogsHigh),
- }
-}
-
-func (b *logEventBuffer) latestBlockSeen() int64 {
- return atomic.LoadInt64(&b.latestBlock)
-}
-
-func (b *logEventBuffer) bufferSize() int {
- return int(atomic.LoadInt32(&b.size))
-}
-
-func (b *logEventBuffer) SetLimits(numOfLogUpkeeps, fastExecLogsHigh int) {
- atomic.StoreUint32(&b.numOfLogUpkeeps, uint32(numOfLogUpkeeps))
- atomic.StoreUint32(&b.fastExecLogsHigh, uint32(fastExecLogsHigh))
-}
-
-// enqueue adds logs (if not exist) to the buffer, returning the number of logs added
-// minus the number of logs dropped.
-func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int {
- b.lock.Lock()
- defer b.lock.Unlock()
-
- lggr := b.lggr.With("id", id.String())
-
- maxBlockLogs := int(atomic.LoadUint32(&b.fastExecLogsHigh) * atomic.LoadUint32(&b.numOfLogUpkeeps))
- maxUpkeepLogs := int(atomic.LoadUint32(&b.fastExecLogsHigh))
-
- latestBlock := b.latestBlockSeen()
- added, dropped := 0, 0
-
- for _, log := range logs {
- if log.BlockNumber == 0 {
- // invalid log
- continue
- }
- i := b.blockNumberIndex(log.BlockNumber)
- currentBlock := b.blocks[i]
- if currentBlock.blockNumber < log.BlockNumber {
- lggr.Debugw("Got log on a new block", "prevBlock", currentBlock.blockNumber, "newBlock", log.BlockNumber)
- currentBlock.blockNumber = log.BlockNumber
- currentBlock.logs = nil
- currentBlock.visited = nil
- } else if currentBlock.blockNumber > log.BlockNumber {
- // not expected to happen
- lggr.Debugw("Skipping log from old block", "currentBlock", currentBlock.blockNumber, "newBlock", log.BlockNumber)
- continue
- }
- droppedLog, ok := currentBlock.Append(lggr, fetchedLog{upkeepID: id, log: log}, maxBlockLogs, maxUpkeepLogs)
- if !ok {
- // Skipping known logs
- continue
- }
- if droppedLog.upkeepID != nil {
- dropped++
- lggr.Debugw("Reached log buffer limits, dropping log", "blockNumber", droppedLog.log.BlockNumber,
- "blockHash", droppedLog.log.BlockHash, "txHash", droppedLog.log.TxHash, "logIndex", droppedLog.log.LogIndex,
- "upkeepID", droppedLog.upkeepID.String())
- }
- added++
- b.blocks[i] = currentBlock
-
- if log.BlockNumber > latestBlock {
- latestBlock = log.BlockNumber
- }
- }
-
- if latestBlock > b.latestBlockSeen() {
- atomic.StoreInt64(&b.latestBlock, latestBlock)
- }
- if added > 0 {
- lggr.Debugw("Added logs to buffer", "addedLogs", added, "dropped", dropped, "latestBlock", latestBlock)
- prommetrics.AutomationLogBufferFlow.WithLabelValues(prommetrics.LogBufferFlowDirectionIngress).Add(float64(added))
- prommetrics.AutomationLogBufferFlow.WithLabelValues(prommetrics.LogBufferFlowDirectionDropped).Add(float64(dropped))
- }
-
- return added - dropped
-}
-
-// peek returns the logs in range [latestBlock-blocks, latestBlock]
-func (b *logEventBuffer) peek(blocks int) []fetchedLog {
- latestBlock := b.latestBlockSeen()
- if latestBlock == 0 {
- return nil
- }
- if blocks > int(latestBlock) {
- blocks = int(latestBlock) - 1
- }
-
- return b.peekRange(latestBlock-int64(blocks), latestBlock)
-}
-
-// peekRange returns the logs between start and end inclusive.
-func (b *logEventBuffer) peekRange(start, end int64) []fetchedLog {
- b.lock.RLock()
- defer b.lock.RUnlock()
-
- blocksInRange := b.getBlocksInRange(int(start), int(end))
-
- var results []fetchedLog
- for _, block := range blocksInRange {
- // double checking that we don't have any gaps in the range
- if block.blockNumber < start || block.blockNumber > end {
- continue
- }
- results = append(results, block.logs...)
- }
-
- sort.SliceStable(results, func(i, j int) bool {
- return results[i].log.BlockNumber < results[j].log.BlockNumber
- })
-
- b.lggr.Debugw("Peeked logs", "results", len(results), "start", start, "end", end)
-
- return results
-}
-
-// dequeueRange returns the logs between start and end inclusive.
-func (b *logEventBuffer) dequeueRange(start, end int64, upkeepLimit, totalLimit int) []fetchedLog {
- b.lock.Lock()
- defer b.lock.Unlock()
-
- blocksInRange := b.getBlocksInRange(int(start), int(end))
- fetchedBlocks := make([]fetchedBlock, 0, len(blocksInRange))
- for _, block := range blocksInRange {
- // Create clone of the blocks as they get processed and update underlying b.blocks
- fetchedBlocks = append(fetchedBlocks, block.Clone())
- }
-
- // Sort the blocks in reverse order of block number so that latest logs
- // are preferred while dequeueing.
- sort.SliceStable(fetchedBlocks, func(i, j int) bool {
- return fetchedBlocks[i].blockNumber > fetchedBlocks[j].blockNumber
- })
-
- logsCount := map[string]int{}
- totalCount := 0
- var results []fetchedLog
- for _, block := range fetchedBlocks {
- if block.blockNumber < start || block.blockNumber > end {
- // double checking that we don't have any gaps in the range
- continue
- }
- if totalCount >= totalLimit {
- // reached total limit, no need to process more blocks
- break
- }
- // Sort the logs in random order that is shared across all nodes.
- // This ensures that nodes across the network will process the same logs.
- block.Sort()
- var remainingLogs, blockResults []fetchedLog
- for _, log := range block.logs {
- if totalCount >= totalLimit {
- remainingLogs = append(remainingLogs, log)
- continue
- }
- if logsCount[log.upkeepID.String()] >= upkeepLimit {
- remainingLogs = append(remainingLogs, log)
- continue
- }
- blockResults = append(blockResults, log)
- logsCount[log.upkeepID.String()]++
- totalCount++
- }
- if len(blockResults) == 0 {
- continue
- }
- results = append(results, blockResults...)
- block.visited = append(block.visited, blockResults...)
- block.logs = remainingLogs
- b.blocks[b.blockNumberIndex(block.blockNumber)] = block
- }
-
- if len(results) > 0 {
- b.lggr.Debugw("Dequeued logs", "results", len(results), "start", start, "end", end)
- prommetrics.AutomationLogBufferFlow.WithLabelValues(prommetrics.LogBufferFlowDirectionEgress).Add(float64(len(results)))
- }
-
- return results
-}
-
-// getBlocksInRange returns the blocks between start and end.
-// NOTE: this function should be called with the lock held
-func (b *logEventBuffer) getBlocksInRange(start, end int) []fetchedBlock {
- var blocksInRange []fetchedBlock
- start, end = b.blockRangeToIndices(start, end)
- if start == -1 || end == -1 {
- // invalid range
- return blocksInRange
- }
- if start <= end {
- // Normal range, need to return indices from start to end(inclusive)
- return b.blocks[start : end+1]
- }
- // in case we get circular range such as [0, 1, end, ... , start, ..., size-1]
- // we need to return the blocks in two ranges: [0, end](inclusive) and [start, size-1]
- blocksInRange = append(blocksInRange, b.blocks[start:]...)
- blocksInRange = append(blocksInRange, b.blocks[:end+1]...)
-
- return blocksInRange
-}
-
-// blockRangeToIndices returns the normalized range of start to end block range,
-// to indices aligned with buffer size. Note ranges inclusive of start, end indices.
-func (b *logEventBuffer) blockRangeToIndices(start, end int) (int, int) {
- latest := b.latestBlockSeen()
- if end > int(latest) {
- // Limit end of range to latest block seen
- end = int(latest)
- }
- if end < start || start == 0 || end == 0 {
- // invalid range
- return -1, -1
- }
- size := b.bufferSize()
- if end-start >= size {
- // If range requires more than buffer size blocks, only to return
- // last size blocks as that's the max the buffer stores.
- start = (end - size) + 1
- }
- return b.blockNumberIndex(int64(start)), b.blockNumberIndex(int64(end))
-}
-
-// blockNumberIndex returns the index of the block in the buffer
-func (b *logEventBuffer) blockNumberIndex(bn int64) int {
- return int(bn-1) % b.bufferSize()
-}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_test.go
deleted file mode 100644
index dca43ca14a..0000000000
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_test.go
+++ /dev/null
@@ -1,892 +0,0 @@
-package logprovider
-
-import (
- "encoding/hex"
- "fmt"
- "math/big"
- "testing"
-
- "github.com/smartcontractkit/chainlink-automation/pkg/v3/types"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/stretchr/testify/require"
-
- ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation"
-
- "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core"
-)
-
-func TestLogEventBuffer_GetBlocksInRange(t *testing.T) {
- size := 3
- maxSeenBlock := int64(4)
- buf := newLogEventBuffer(logger.TestLogger(t), size, 10, 10)
-
- buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0},
- )
-
- buf.enqueue(big.NewInt(2),
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 2},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 2},
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x1"), LogIndex: 1},
- )
-
- tests := []struct {
- name string
- from int64
- to int64
- want int
- }{
- {
- name: "all",
- from: 2,
- to: 4,
- want: 3,
- },
- {
- name: "partial",
- from: 2,
- to: 3,
- want: 2,
- },
- {
- name: "circular",
- from: 3,
- to: 4,
- want: 2,
- },
- {
- name: "zero start",
- from: 0,
- to: 2,
- },
- {
- name: "invalid zero end",
- from: 0,
- to: 0,
- },
- {
- name: "invalid from larger than to",
- from: 4,
- to: 2,
- },
- {
- name: "outside max last seen",
- from: 5,
- to: 10,
- },
- {
- name: "limited by max last seen",
- from: 2,
- to: 5,
- want: 3,
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- blocks := buf.getBlocksInRange(int(tc.from), int(tc.to))
- require.Equal(t, tc.want, len(blocks))
- if tc.want > 0 {
- from := tc.from
- require.Equal(t, from, blocks[0].blockNumber)
- to := tc.to
- if to >= maxSeenBlock {
- to = maxSeenBlock
- }
- require.Equal(t, to, blocks[len(blocks)-1].blockNumber)
- }
- })
- }
-}
-
-func TestLogEventBuffer_GetBlocksInRange_Circular(t *testing.T) {
- size := 4
- buf := newLogEventBuffer(logger.TestLogger(t), size, 10, 10)
-
- require.Equal(t, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0},
- ), 3)
-
- require.Equal(t, buf.enqueue(big.NewInt(2),
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 2},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 2},
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x1"), LogIndex: 1},
- ), 3)
-
- require.Equal(t, buf.enqueue(big.NewInt(3),
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x1"), LogIndex: 4},
- logpoller.Log{BlockNumber: 5, TxHash: common.HexToHash("0x3"), LogIndex: 2},
- logpoller.Log{BlockNumber: 5, TxHash: common.HexToHash("0x3"), LogIndex: 5},
- ), 3)
-
- tests := []struct {
- name string
- from int64
- to int64
- expectedBlocks []int64
- }{
- {
- name: "happy flow",
- from: 2,
- to: 5,
- expectedBlocks: []int64{2, 3, 4, 5},
- },
- {
- name: "range overflow circular",
- from: 1,
- to: 6,
- expectedBlocks: []int64{2, 3, 4, 5},
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- blocks := buf.getBlocksInRange(int(tc.from), int(tc.to))
- require.Equal(t, len(tc.expectedBlocks), len(blocks))
- expectedBlockNumbers := map[int64]bool{}
- for _, b := range tc.expectedBlocks {
- expectedBlockNumbers[b] = false
- }
- for _, b := range blocks {
- expectedBlockNumbers[b.blockNumber] = true
- }
- for k, v := range expectedBlockNumbers {
- require.True(t, v, "missing block %d", k)
- }
- })
- }
-}
-
-func TestLogEventBuffer_EnqueueDequeue(t *testing.T) {
- t.Run("dequeue empty", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 3, 10, 10)
-
- results := buf.peekRange(int64(1), int64(2))
- require.Equal(t, 0, len(results))
- results = buf.peek(2)
- require.Equal(t, 0, len(results))
- })
-
- t.Run("enqueue", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 3, 10, 10)
-
- buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 1},
- )
- buf.lock.Lock()
- require.Equal(t, 2, len(buf.blocks[0].logs))
- buf.lock.Unlock()
- })
-
- t.Run("enqueue logs overflow", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 2, 2, 2)
-
- require.Equal(t, 2, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 1},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 2},
- ))
- buf.lock.Lock()
- require.Equal(t, 2, len(buf.blocks[0].logs))
- buf.lock.Unlock()
- })
-
- t.Run("enqueue logs overflow with dynamic limits", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 2, 10, 2)
-
- require.Equal(t, 2, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 1},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 2},
- ))
- buf.SetLimits(10, 3)
- require.Equal(t, 3, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x21"), LogIndex: 0},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x21"), LogIndex: 1},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x21"), LogIndex: 2},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x21"), LogIndex: 3},
- ))
-
- buf.lock.Lock()
- defer buf.lock.Unlock()
- require.Equal(t, 2, len(buf.blocks[0].logs))
- require.Equal(t, 3, len(buf.blocks[1].logs))
- })
-
- t.Run("enqueue logs overflow with dynamic limits", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 2, 10, 2)
-
- require.Equal(t, 2, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 1},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 2},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 3},
- ))
- buf.SetLimits(10, 3)
- require.Equal(t, 3, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x21"), LogIndex: 0},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x21"), LogIndex: 1},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x21"), LogIndex: 2},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x21"), LogIndex: 3},
- ))
-
- buf.lock.Lock()
- defer buf.lock.Unlock()
- require.Equal(t, 2, len(buf.blocks[0].logs))
- })
-
- t.Run("enqueue block overflow", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 3, 2, 10)
-
- require.Equal(t, 5, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0},
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x4"), LogIndex: 0},
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x4"), LogIndex: 1},
- ))
- buf.lock.Lock()
- require.Equal(t, 2, len(buf.blocks[0].logs))
- buf.lock.Unlock()
- })
-
- t.Run("enqueue upkeep block overflow", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 10, 10, 2)
-
- require.Equal(t, 2, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 1},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 2},
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 3},
- ))
- buf.lock.Lock()
- require.Equal(t, 2, len(buf.blocks[0].logs))
- buf.lock.Unlock()
- })
-
- t.Run("peek range after dequeue", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 3, 10, 10)
-
- require.Equal(t, buf.enqueue(big.NewInt(10),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 10},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x1"), LogIndex: 11},
- ), 2)
- require.Equal(t, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x1"), LogIndex: 1},
- ), 2)
- results := buf.peekRange(int64(1), int64(2))
- require.Equal(t, 2, len(results))
- verifyBlockNumbers(t, results, 1, 2)
- removed := buf.dequeueRange(int64(1), int64(2), 2, 10)
- require.Equal(t, 2, len(removed))
- results = buf.peekRange(int64(1), int64(2))
- require.Equal(t, 0, len(results))
- })
-
- t.Run("enqueue peek and dequeue", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 4, 10, 10)
-
- require.Equal(t, buf.enqueue(big.NewInt(10),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 10},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x1"), LogIndex: 11},
- ), 2)
- require.Equal(t, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x1"), LogIndex: 1},
- ), 2)
- results := buf.peek(8)
- require.Equal(t, 4, len(results))
- verifyBlockNumbers(t, results, 1, 2, 3, 3)
- removed := buf.dequeueRange(1, 3, 5, 5)
- require.Equal(t, 4, len(removed))
- buf.lock.Lock()
- require.Equal(t, 0, len(buf.blocks[0].logs))
- require.Equal(t, int64(2), buf.blocks[1].blockNumber)
- require.Equal(t, 1, len(buf.blocks[1].visited))
- buf.lock.Unlock()
- })
-
- t.Run("enqueue and peek range circular", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 3, 10, 10)
-
- require.Equal(t, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0},
- ), 3)
- require.Equal(t, buf.enqueue(big.NewInt(10),
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x1"), LogIndex: 10},
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x1"), LogIndex: 11},
- ), 2)
-
- results := buf.peekRange(int64(1), int64(1))
- require.Equal(t, 0, len(results))
-
- results = buf.peekRange(int64(3), int64(5))
- require.Equal(t, 3, len(results))
- verifyBlockNumbers(t, results, 3, 4, 4)
- })
-
- t.Run("doesnt enqueue old blocks", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 3, 5, 10)
-
- require.Equal(t, buf.enqueue(big.NewInt(10),
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x1"), LogIndex: 10},
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x1"), LogIndex: 11},
- ), 2)
- require.Equal(t, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0},
- ), 2)
- results := buf.peekRange(int64(1), int64(5))
- fmt.Println(results)
- verifyBlockNumbers(t, results, 2, 3, 4, 4)
- })
-
- t.Run("dequeue with limits returns latest block logs", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 3, 5, 10)
- require.Equal(t, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0},
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x4"), LogIndex: 0},
- logpoller.Log{BlockNumber: 5, TxHash: common.HexToHash("0x5"), LogIndex: 0},
- ), 5)
-
- logs := buf.dequeueRange(1, 5, 2, 10)
- require.Equal(t, 2, len(logs))
- require.Equal(t, int64(5), logs[0].log.BlockNumber)
- require.Equal(t, int64(4), logs[1].log.BlockNumber)
-
- require.Equal(t, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x4"), LogIndex: 1},
- logpoller.Log{BlockNumber: 5, TxHash: common.HexToHash("0x5"), LogIndex: 1},
- ), 2)
-
- logs = buf.dequeueRange(1, 5, 3, 2)
- require.Equal(t, 2, len(logs))
- })
-
- t.Run("dequeue doesn't return same logs again", func(t *testing.T) {
- buf := newLogEventBuffer(logger.TestLogger(t), 3, 5, 10)
- require.Equal(t, buf.enqueue(big.NewInt(1),
- logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
- logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0},
- logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0},
- ), 3)
-
- logs := buf.dequeueRange(3, 3, 2, 10)
- fmt.Println(logs)
- require.Equal(t, 1, len(logs))
-
- logs = buf.dequeueRange(3, 3, 2, 10)
- fmt.Println(logs)
- require.Equal(t, 0, len(logs))
- })
-}
-
-func TestLogEventBuffer_FetchedBlock_Append(t *testing.T) {
- type appendArgs struct {
- fl fetchedLog
- maxBlockLogs, maxUpkeepLogs int
- added, dropped bool
- }
-
- tests := []struct {
- name string
- blockNumber int64
- logs []fetchedLog
- visited []fetchedLog
- toAdd []appendArgs
- expected []fetchedLog
- added bool
- }{
- {
- name: "empty block",
- blockNumber: 1,
- logs: []fetchedLog{},
- visited: []fetchedLog{},
- toAdd: []appendArgs{
- {
- fl: fetchedLog{
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- maxBlockLogs: 10,
- maxUpkeepLogs: 2,
- added: true,
- },
- },
- expected: []fetchedLog{
- {
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- },
- },
- {
- name: "existing log",
- blockNumber: 1,
- logs: []fetchedLog{
- {
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- },
- visited: []fetchedLog{},
- toAdd: []appendArgs{
- {
- fl: fetchedLog{
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- maxBlockLogs: 10,
- maxUpkeepLogs: 2,
- added: false,
- },
- },
- expected: []fetchedLog{
- {
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- },
- },
- {
- name: "visited log",
- blockNumber: 1,
- logs: []fetchedLog{},
- visited: []fetchedLog{
- {
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- },
- toAdd: []appendArgs{
- {
- fl: fetchedLog{
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- maxBlockLogs: 10,
- maxUpkeepLogs: 2,
- added: false,
- },
- },
- expected: []fetchedLog{},
- },
- {
- name: "upkeep log limits",
- blockNumber: 1,
- logs: []fetchedLog{},
- visited: []fetchedLog{},
- toAdd: []appendArgs{
- {
- fl: fetchedLog{
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- maxBlockLogs: 10,
- maxUpkeepLogs: 2,
- added: true,
- },
- {
- fl: fetchedLog{
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 1,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- maxBlockLogs: 10,
- maxUpkeepLogs: 2,
- added: true,
- },
- {
- fl: fetchedLog{
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 2,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- maxBlockLogs: 10,
- maxUpkeepLogs: 2,
- added: true,
- dropped: true,
- },
- },
- expected: []fetchedLog{
- {
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 1,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- {
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 2,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- },
- },
- {
- name: "block log limits",
- blockNumber: 1,
- logs: []fetchedLog{},
- visited: []fetchedLog{},
- toAdd: []appendArgs{
- {
- fl: fetchedLog{
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- maxBlockLogs: 2,
- maxUpkeepLogs: 4,
- added: true,
- },
- {
- fl: fetchedLog{
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 1,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- maxBlockLogs: 2,
- maxUpkeepLogs: 4,
- added: true,
- },
- {
- fl: fetchedLog{
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 2,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- maxBlockLogs: 2,
- maxUpkeepLogs: 4,
- added: true,
- dropped: true,
- },
- },
- expected: []fetchedLog{
- {
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 1,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- {
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 2,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- },
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- lggr := logger.TestLogger(t)
- b := fetchedBlock{
- blockNumber: tc.blockNumber,
- logs: make([]fetchedLog, len(tc.logs)),
- visited: make([]fetchedLog, len(tc.visited)),
- }
- copy(b.logs, tc.logs)
- copy(b.visited, tc.visited)
-
- for _, args := range tc.toAdd {
- dropped, added := b.Append(lggr, args.fl, args.maxBlockLogs, args.maxUpkeepLogs)
- require.Equal(t, args.added, added)
- if args.dropped {
- require.NotNil(t, dropped.upkeepID)
- } else {
- require.Nil(t, dropped.upkeepID)
- }
- }
- // clear cached logIDs
- for i := range b.logs {
- b.logs[i].cachedLogID = ""
- }
- require.Equal(t, tc.expected, b.logs)
- })
- }
-}
-func TestLogEventBuffer_FetchedBlock_Sort(t *testing.T) {
- tests := []struct {
- name string
- blockNumber int64
- logs []fetchedLog
- beforeSort []string
- afterSort []string
- iterations int
- }{
- {
- name: "no logs",
- blockNumber: 10,
- logs: []fetchedLog{},
- beforeSort: []string{},
- afterSort: []string{},
- },
- {
- name: "single log",
- blockNumber: 1,
- logs: []fetchedLog{
- {
- log: logpoller.Log{
- BlockHash: common.HexToHash("0x111"),
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- },
- },
- beforeSort: []string{
- "0000000000000000000000000000000000000000000000000000000000000111000000000000000000000000000000000000000000000000000000000000000100000000",
- },
- afterSort: []string{
- "0000000000000000000000000000000000000000000000000000000000000111000000000000000000000000000000000000000000000000000000000000000100000000",
- },
- },
- {
- name: "multiple logs with 10 iterations",
- blockNumber: 1,
- logs: []fetchedLog{
- {
- log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
- TxHash: common.HexToHash("0xb711bd1103927611ee41152aa8ae27f3330"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- {
- log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
- TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "222").BigInt(),
- },
- {
- log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
- TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
- LogIndex: 4,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- {
- log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
- TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
- LogIndex: 3,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "222").BigInt(),
- },
- {
- log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
- TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
- LogIndex: 2,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- {
- log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
- TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
- LogIndex: 5,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- {
- log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
- TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
- LogIndex: 3,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- {
- log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
- TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
- LogIndex: 1,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- },
- beforeSort: []string{
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000b711bd1103927611ee41152aa8ae27f333000000000",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000000",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000004",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000002",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000005",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000001",
- },
- afterSort: []string{
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000b711bd1103927611ee41152aa8ae27f333000000000",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000000",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000001",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000002",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000004",
- "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000005",
- },
- iterations: 10,
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- b := fetchedBlock{
- blockNumber: tc.blockNumber,
- logs: make([]fetchedLog, len(tc.logs)),
- }
- if tc.iterations == 0 {
- tc.iterations = 1
- }
- // performing the same multiple times should yield the same result
- // default is one iteration
- for i := 0; i < tc.iterations; i++ {
- copy(b.logs, tc.logs)
- logIDs := getLogIds(b)
- require.Equal(t, len(tc.beforeSort), len(logIDs))
- require.Equal(t, tc.beforeSort, logIDs)
- b.Sort()
- logIDsAfterSort := getLogIds(b)
- require.Equal(t, len(tc.afterSort), len(logIDsAfterSort))
- require.Equal(t, tc.afterSort, logIDsAfterSort)
- }
- })
- }
-}
-
-func TestLogEventBuffer_FetchedBlock_Clone(t *testing.T) {
- b1 := fetchedBlock{
- blockNumber: 1,
- logs: []fetchedLog{
- {
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 0,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- {
- log: logpoller.Log{
- BlockNumber: 1,
- TxHash: common.HexToHash("0x1"),
- LogIndex: 2,
- },
- upkeepID: core.GenUpkeepID(types.LogTrigger, "111").BigInt(),
- },
- },
- }
-
- b2 := b1.Clone()
- require.Equal(t, b1.blockNumber, b2.blockNumber)
- require.Equal(t, len(b1.logs), len(b2.logs))
- require.Equal(t, b1.logs[0].log.BlockNumber, b2.logs[0].log.BlockNumber)
-
- b1.blockNumber = 2
- b1.logs[0].log.BlockNumber = 2
- require.NotEqual(t, b1.blockNumber, b2.blockNumber)
- require.NotEqual(t, b1.logs[0].log.BlockNumber, b2.logs[0].log.BlockNumber)
-}
-
-func verifyBlockNumbers(t *testing.T, logs []fetchedLog, bns ...int64) {
- require.Equal(t, len(bns), len(logs), "expected length mismatch")
- for i, log := range logs {
- require.Equal(t, bns[i], log.log.BlockNumber, "wrong block number")
- }
-}
-
-func getLogIds(b fetchedBlock) []string {
- logIDs := make([]string, len(b.logs))
- for i, l := range b.logs {
- ext := ocr2keepers.LogTriggerExtension{
- TxHash: l.log.TxHash,
- Index: uint32(l.log.LogIndex),
- BlockHash: l.log.BlockHash,
- }
- logIDs[i] = hex.EncodeToString(ext.LogIdentifier())
- }
- return logIDs
-}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go
index 19302624b4..7ec65ff474 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go
@@ -35,23 +35,12 @@ type LogTriggersOptions struct {
// Finality depth is the number of blocks to wait before considering a block final.
FinalityDepth int64
- // TODO: (AUTO-9355) remove once we have a single version
- BufferVersion BufferVersion
// LogLimit is the minimum number of logs to process in a single block window.
LogLimit uint32
// BlockRate determines the block window for log processing.
BlockRate uint32
}
-// BufferVersion is the version of the log buffer.
-// TODO: (AUTO-9355) remove once we have a single version
-type BufferVersion string
-
-const (
- BufferVersionDefault BufferVersion = ""
- BufferVersionV1 BufferVersion = "v1"
-)
-
func NewOptions(finalityDepth int64, chainID *big.Int) LogTriggersOptions {
opts := new(LogTriggersOptions)
opts.chainID = chainID
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go
index 475963c575..49741b7911 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go
@@ -34,115 +34,92 @@ import (
)
func TestIntegration_LogEventProvider(t *testing.T) {
- tests := []struct {
- name string
- bufferVersion logprovider.BufferVersion
- logLimit uint32
- }{
- {
- name: "default buffer",
- bufferVersion: logprovider.BufferVersionDefault,
- logLimit: 10,
- },
- {
- name: "buffer v1",
- bufferVersion: logprovider.BufferVersionV1,
- logLimit: 10,
- },
- }
+ ctx, cancel := context.WithCancel(testutils.Context(t))
+ defer cancel()
+
+ backend, stopMining, accounts := setupBackend(t)
+ defer stopMining()
+ carrol := accounts[2]
+
+ db := setupDB(t)
+ defer db.Close()
+
+ opts := logprovider.NewOptions(200, big.NewInt(1))
+ opts.ReadInterval = time.Second / 2
+ opts.LogLimit = 10
+
+ lp, ethClient := setupDependencies(t, db, backend)
+ filterStore := logprovider.NewUpkeepFilterStore()
+ provider, _ := setup(logger.TestLogger(t), lp, nil, nil, filterStore, &opts)
+ logProvider := provider.(logprovider.LogEventProviderTest)
+
+ n := 10
+
+ backend.Commit()
+ lp.PollAndSaveLogs(ctx, 1) // Ensure log poller has a latest block
- for _, tc := range tests {
- bufferVersion, logLimit := tc.bufferVersion, tc.logLimit
- t.Run(tc.name, func(t *testing.T) {
- ctx, cancel := context.WithCancel(testutils.Context(t))
- defer cancel()
-
- backend, stopMining, accounts := setupBackend(t)
- defer stopMining()
- carrol := accounts[2]
-
- db := setupDB(t)
- defer db.Close()
-
- opts := logprovider.NewOptions(200, big.NewInt(1))
- opts.ReadInterval = time.Second / 2
- opts.BufferVersion = bufferVersion
- opts.LogLimit = logLimit
-
- lp, ethClient := setupDependencies(t, db, backend)
- filterStore := logprovider.NewUpkeepFilterStore()
- provider, _ := setup(logger.TestLogger(t), lp, nil, nil, filterStore, &opts)
- logProvider := provider.(logprovider.LogEventProviderTest)
-
- n := 10
-
- backend.Commit()
- lp.PollAndSaveLogs(ctx, 1) // Ensure log poller has a latest block
-
- ids, addrs, contracts := deployUpkeepCounter(ctx, t, n, ethClient, backend, carrol, logProvider)
- lp.PollAndSaveLogs(ctx, int64(n))
-
- go func() {
- if err := logProvider.Start(ctx); err != nil {
- t.Logf("error starting log provider: %s", err)
- t.Fail()
- }
- }()
- defer logProvider.Close()
-
- logsRounds := 10
-
- poll := pollFn(ctx, t, lp, ethClient)
-
- triggerEvents(ctx, t, backend, carrol, logsRounds, poll, contracts...)
-
- poll(backend.Commit())
-
- waitLogPoller(ctx, t, backend, lp, ethClient)
-
- waitLogProvider(ctx, t, logProvider, 3)
-
- allPayloads := collectPayloads(ctx, t, logProvider, n, logsRounds/2)
- require.GreaterOrEqual(t, len(allPayloads), n,
- "failed to get logs after restart")
-
- t.Run("Restart", func(t *testing.T) {
- t.Log("restarting log provider")
- // assuming that our service was closed and restarted,
- // we should be able to backfill old logs and fetch new ones
- filterStore := logprovider.NewUpkeepFilterStore()
- logProvider2 := logprovider.NewLogProvider(logger.TestLogger(t), lp, big.NewInt(1), logprovider.NewLogEventsPacker(), filterStore, opts)
-
- poll(backend.Commit())
- go func() {
- if err2 := logProvider2.Start(ctx); err2 != nil {
- t.Logf("error starting log provider: %s", err2)
- t.Fail()
- }
- }()
- defer logProvider2.Close()
-
- // re-register filters
- for i, id := range ids {
- err := logProvider2.RegisterFilter(ctx, logprovider.FilterOptions{
- UpkeepID: id,
- TriggerConfig: newPlainLogTriggerConfig(addrs[i]),
- // using block number at which the upkeep was registered,
- // before we emitted any logs
- UpdateBlock: uint64(n),
- })
- require.NoError(t, err)
- }
-
- waitLogProvider(ctx, t, logProvider2, 2)
-
- t.Log("getting logs after restart")
- logsAfterRestart := collectPayloads(ctx, t, logProvider2, n, 5)
- require.GreaterOrEqual(t, len(logsAfterRestart), n,
- "failed to get logs after restart")
+ ids, addrs, contracts := deployUpkeepCounter(ctx, t, n, ethClient, backend, carrol, logProvider)
+ lp.PollAndSaveLogs(ctx, int64(n))
+
+ go func() {
+ if err := logProvider.Start(ctx); err != nil {
+ t.Logf("error starting log provider: %s", err)
+ t.Fail()
+ }
+ }()
+ defer logProvider.Close()
+
+ logsRounds := 10
+
+ poll := pollFn(ctx, t, lp, ethClient)
+
+ triggerEvents(ctx, t, backend, carrol, logsRounds, poll, contracts...)
+
+ poll(backend.Commit())
+
+ waitLogPoller(ctx, t, backend, lp, ethClient)
+
+ waitLogProvider(ctx, t, logProvider, 3)
+
+ allPayloads := collectPayloads(ctx, t, logProvider, n, logsRounds/2)
+ require.GreaterOrEqual(t, len(allPayloads), n,
+ "failed to get logs after restart")
+
+ t.Run("Restart", func(t *testing.T) {
+ t.Log("restarting log provider")
+ // assuming that our service was closed and restarted,
+ // we should be able to backfill old logs and fetch new ones
+ filterStore := logprovider.NewUpkeepFilterStore()
+ logProvider2 := logprovider.NewLogProvider(logger.TestLogger(t), lp, big.NewInt(1), logprovider.NewLogEventsPacker(), filterStore, opts)
+
+ poll(backend.Commit())
+ go func() {
+ if err2 := logProvider2.Start(ctx); err2 != nil {
+ t.Logf("error starting log provider: %s", err2)
+ t.Fail()
+ }
+ }()
+ defer logProvider2.Close()
+
+ // re-register filters
+ for i, id := range ids {
+ err := logProvider2.RegisterFilter(ctx, logprovider.FilterOptions{
+ UpkeepID: id,
+ TriggerConfig: newPlainLogTriggerConfig(addrs[i]),
+ // using block number at which the upkeep was registered,
+ // before we emitted any logs
+ UpdateBlock: uint64(n),
})
- })
- }
+ require.NoError(t, err)
+ }
+
+ waitLogProvider(ctx, t, logProvider2, 2)
+
+ t.Log("getting logs after restart")
+ logsAfterRestart := collectPayloads(ctx, t, logProvider2, n, 5)
+ require.GreaterOrEqual(t, len(logsAfterRestart), n,
+ "failed to get logs after restart")
+ })
}
func TestIntegration_LogEventProvider_UpdateConfig(t *testing.T) {
@@ -219,78 +196,55 @@ func TestIntegration_LogEventProvider_UpdateConfig(t *testing.T) {
}
func TestIntegration_LogEventProvider_Backfill(t *testing.T) {
- tests := []struct {
- name string
- bufferVersion logprovider.BufferVersion
- logLimit uint32
- }{
- {
- name: "default buffer",
- bufferVersion: logprovider.BufferVersionDefault,
- logLimit: 10,
- },
- {
- name: "buffer v1",
- bufferVersion: logprovider.BufferVersionV1,
- logLimit: 10,
- },
- }
-
- for _, tc := range tests {
- bufferVersion, limitLow := tc.bufferVersion, tc.logLimit
- t.Run(tc.name, func(t *testing.T) {
- ctx, cancel := context.WithTimeout(testutils.Context(t), time.Second*60)
- defer cancel()
+ ctx, cancel := context.WithTimeout(testutils.Context(t), time.Second*60)
+ defer cancel()
- backend, stopMining, accounts := setupBackend(t)
- defer stopMining()
- carrol := accounts[2]
+ backend, stopMining, accounts := setupBackend(t)
+ defer stopMining()
+ carrol := accounts[2]
- db := setupDB(t)
- defer db.Close()
+ db := setupDB(t)
+ defer db.Close()
- opts := logprovider.NewOptions(200, big.NewInt(1))
- opts.ReadInterval = time.Second / 4
- opts.BufferVersion = bufferVersion
- opts.LogLimit = limitLow
+ opts := logprovider.NewOptions(200, big.NewInt(1))
+ opts.ReadInterval = time.Second / 4
+ opts.LogLimit = 10
- lp, ethClient := setupDependencies(t, db, backend)
- filterStore := logprovider.NewUpkeepFilterStore()
- provider, _ := setup(logger.TestLogger(t), lp, nil, nil, filterStore, &opts)
- logProvider := provider.(logprovider.LogEventProviderTest)
+ lp, ethClient := setupDependencies(t, db, backend)
+ filterStore := logprovider.NewUpkeepFilterStore()
+ provider, _ := setup(logger.TestLogger(t), lp, nil, nil, filterStore, &opts)
+ logProvider := provider.(logprovider.LogEventProviderTest)
- n := 10
+ n := 10
- backend.Commit()
- lp.PollAndSaveLogs(ctx, 1) // Ensure log poller has a latest block
- _, _, contracts := deployUpkeepCounter(ctx, t, n, ethClient, backend, carrol, logProvider)
+ backend.Commit()
+ lp.PollAndSaveLogs(ctx, 1) // Ensure log poller has a latest block
+ _, _, contracts := deployUpkeepCounter(ctx, t, n, ethClient, backend, carrol, logProvider)
- poll := pollFn(ctx, t, lp, ethClient)
+ poll := pollFn(ctx, t, lp, ethClient)
- rounds := 8
- for i := 0; i < rounds; i++ {
- poll(backend.Commit())
- triggerEvents(ctx, t, backend, carrol, n, poll, contracts...)
- poll(backend.Commit())
- }
+ rounds := 8
+ for i := 0; i < rounds; i++ {
+ poll(backend.Commit())
+ triggerEvents(ctx, t, backend, carrol, n, poll, contracts...)
+ poll(backend.Commit())
+ }
- waitLogPoller(ctx, t, backend, lp, ethClient)
+ waitLogPoller(ctx, t, backend, lp, ethClient)
- // starting the log provider should backfill logs
- go func() {
- if startErr := logProvider.Start(ctx); startErr != nil {
- t.Logf("error starting log provider: %s", startErr)
- t.Fail()
- }
- }()
- defer logProvider.Close()
+ // starting the log provider should backfill logs
+ go func() {
+ if startErr := logProvider.Start(ctx); startErr != nil {
+ t.Logf("error starting log provider: %s", startErr)
+ t.Fail()
+ }
+ }()
+ defer logProvider.Close()
- waitLogProvider(ctx, t, logProvider, 3)
+ waitLogProvider(ctx, t, logProvider, 3)
- allPayloads := collectPayloads(ctx, t, logProvider, n*rounds, 5)
- require.GreaterOrEqual(t, len(allPayloads), len(contracts), "failed to backfill logs")
- })
- }
+ allPayloads := collectPayloads(ctx, t, logProvider, n*rounds, 5)
+ require.GreaterOrEqual(t, len(allPayloads), len(contracts), "failed to backfill logs")
}
func TestIntegration_LogRecoverer_Backfill(t *testing.T) {
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go
index 3609d0a465..f1de1ef512 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go
@@ -81,13 +81,8 @@ type LogEventProviderTest interface {
CurrentPartitionIdx() uint64
}
-type LogEventProviderFeatures interface {
- WithBufferVersion(v BufferVersion)
-}
-
var _ LogEventProvider = &logEventProvider{}
var _ LogEventProviderTest = &logEventProvider{}
-var _ LogEventProviderFeatures = &logEventProvider{}
// logEventProvider manages log filters for upkeeps and enables to read the log events.
type logEventProvider struct {
@@ -104,8 +99,7 @@ type logEventProvider struct {
registerLock sync.Mutex
filterStore UpkeepFilterStore
- buffer *logEventBuffer
- bufferV1 LogBuffer
+ buffer LogBuffer
opts LogTriggersOptions
@@ -119,8 +113,7 @@ func NewLogProvider(lggr logger.Logger, poller logpoller.LogPoller, chainID *big
threadCtrl: utils.NewThreadControl(),
lggr: lggr.Named("KeepersRegistry.LogEventProvider"),
packer: packer,
- buffer: newLogEventBuffer(lggr, int(opts.LookbackBlocks), defaultNumOfLogUpkeeps, defaultFastExecLogsHigh),
- bufferV1: NewLogBuffer(lggr, uint32(opts.LookbackBlocks), opts.BlockRate, opts.LogLimit),
+ buffer: NewLogBuffer(lggr, uint32(opts.LookbackBlocks), opts.BlockRate, opts.LogLimit),
poller: poller,
opts: opts,
filterStore: filterStore,
@@ -147,20 +140,7 @@ func (p *logEventProvider) SetConfig(cfg ocr2keepers.LogEventProviderConfig) {
atomic.StoreUint32(&p.opts.BlockRate, blockRate)
atomic.StoreUint32(&p.opts.LogLimit, logLimit)
- switch p.opts.BufferVersion {
- case BufferVersionV1:
- p.bufferV1.SetConfig(uint32(p.opts.LookbackBlocks), blockRate, logLimit)
- default:
- }
-}
-
-func (p *logEventProvider) WithBufferVersion(v BufferVersion) {
- p.lock.Lock()
- defer p.lock.Unlock()
-
- p.lggr.Debugw("with buffer version", "version", v)
-
- p.opts.BufferVersion = v
+ p.buffer.SetConfig(uint32(p.opts.LookbackBlocks), blockRate, logLimit)
}
func (p *logEventProvider) Start(context.Context) error {
@@ -197,7 +177,7 @@ func (p *logEventProvider) Start(context.Context) error {
for {
select {
case <-ticker.C:
- if err := p.syncBufferFilters(); err != nil {
+ if err := p.buffer.SyncFilters(p.filterStore); err != nil {
p.lggr.Warnw("failed to sync buffer filters", "err", err)
}
case <-ctx.Done():
@@ -259,22 +239,11 @@ func (p *logEventProvider) getLogsFromBuffer(latestBlock int64) []ocr2keepers.Up
start = 1
}
- switch p.opts.BufferVersion {
- case BufferVersionV1:
- payloads = p.minimumCommitmentDequeue(latestBlock, start)
+ payloads = p.minimumCommitmentDequeue(latestBlock, start)
- // if we have remaining capacity following minimum commitment dequeue, perform a best effort dequeue
- if len(payloads) < MaxPayloads {
- payloads = p.bestEffortDequeue(latestBlock, start, payloads)
- }
- default:
- logs := p.buffer.dequeueRange(start, latestBlock, AllowedLogsPerUpkeep, MaxPayloads)
- for _, l := range logs {
- payload, err := p.createPayload(l.upkeepID, l.log)
- if err == nil {
- payloads = append(payloads, payload)
- }
- }
+ // if we have remaining capacity following minimum commitment dequeue, perform a best effort dequeue
+ if len(payloads) < MaxPayloads {
+ payloads = p.bestEffortDequeue(latestBlock, start, payloads)
}
return payloads
@@ -290,7 +259,7 @@ func (p *logEventProvider) minimumCommitmentDequeue(latestBlock, start int64) []
startWindow, _ := getBlockWindow(start, blockRate)
// dequeue the minimum number logs (log limit, varies by chain) per upkeep for this block window
- logs, remaining := p.bufferV1.Dequeue(startWindow, MaxPayloads-len(payloads), true)
+ logs, remaining := p.buffer.Dequeue(startWindow, MaxPayloads-len(payloads), true)
if len(logs) > 0 {
p.lggr.Debugw("minimum commitment dequeue", "start", start, "latestBlock", latestBlock, "logs", len(logs), "remaining", remaining)
}
@@ -316,7 +285,7 @@ func (p *logEventProvider) bestEffortDequeue(latestBlock, start int64, payloads
startWindow, _ := getBlockWindow(start, blockRate)
// dequeue as many logs as we can, based on remaining capacity, for this block window
- logs, remaining := p.bufferV1.Dequeue(startWindow, MaxPayloads-len(payloads), false)
+ logs, remaining := p.buffer.Dequeue(startWindow, MaxPayloads-len(payloads), false)
if len(logs) > 0 {
p.lggr.Debugw("best effort dequeue", "start", start, "latestBlock", latestBlock, "logs", len(logs), "remaining", remaining)
}
@@ -522,12 +491,8 @@ func (p *logEventProvider) readLogs(ctx context.Context, latest int64, filters [
}
filteredLogs := filter.Select(logs...)
- switch p.opts.BufferVersion {
- case BufferVersionV1:
- p.bufferV1.Enqueue(filter.upkeepID, filteredLogs...)
- default:
- p.buffer.enqueue(filter.upkeepID, filteredLogs...)
- }
+ p.buffer.Enqueue(filter.upkeepID, filteredLogs...)
+
// Update the lastPollBlock for filter in slice this is then
// updated into filter store in updateFiltersLastPoll
filters[i].lastPollBlock = latest
@@ -535,16 +500,3 @@ func (p *logEventProvider) readLogs(ctx context.Context, latest int64, filters [
return merr
}
-
-func (p *logEventProvider) syncBufferFilters() error {
- p.lock.RLock()
- buffVersion := p.opts.BufferVersion
- p.lock.RUnlock()
-
- switch buffVersion {
- case BufferVersionV1:
- return p.bufferV1.SyncFilters(p.filterStore)
- default:
- return nil
- }
-}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_test.go
index 282f89d370..9536a24ce0 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_test.go
@@ -258,37 +258,14 @@ func TestLogEventProvider_ReadLogs(t *testing.T) {
filterStore := NewUpkeepFilterStore()
p := NewLogProvider(logger.TestLogger(t), mp, big.NewInt(1), &mockedPacker{}, filterStore, NewOptions(200, big.NewInt(1)))
- var ids []*big.Int
for i := 0; i < 10; i++ {
cfg, f := newEntry(p, i+1)
- ids = append(ids, f.upkeepID)
require.NoError(t, p.RegisterFilter(ctx, FilterOptions{
UpkeepID: f.upkeepID,
TriggerConfig: cfg,
}))
}
- t.Run("no entries", func(t *testing.T) {
- require.NoError(t, p.ReadLogs(ctx, big.NewInt(999999)))
- logs := p.buffer.peek(10)
- require.Len(t, logs, 0)
- })
-
- t.Run("has entries", func(t *testing.T) {
- require.NoError(t, p.ReadLogs(ctx, ids[:2]...))
- logs := p.buffer.peek(10)
- require.Len(t, logs, 2)
-
- var updatedFilters []upkeepFilter
- filterStore.RangeFiltersByIDs(func(i int, f upkeepFilter) {
- updatedFilters = append(updatedFilters, f.Clone())
- }, ids[:2]...)
- for _, f := range updatedFilters {
- // Last poll block should be updated
- require.Equal(t, int64(1), f.lastPollBlock)
- }
- })
-
// TODO: test rate limiting
}
@@ -342,7 +319,6 @@ func remainingBlockWindowCounts(queues map[string]*upkeepLogQueue, blockRate int
func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
t.Run("dequeuing from an empty buffer returns 0 logs", func(t *testing.T) {
opts := NewOptions(200, big.NewInt(42161))
- opts.BufferVersion = "v1"
logPoller := &mockLogPoller{
LatestBlockFn: func(ctx context.Context) (int64, error) {
@@ -361,7 +337,6 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
t.Run("a single log for a single upkeep gets dequeued", func(t *testing.T) {
opts := NewOptions(200, big.NewInt(42161))
- opts.BufferVersion = "v1"
logPoller := &mockLogPoller{
LatestBlockFn: func(ctx context.Context) (int64, error) {
@@ -373,7 +348,7 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
ctx := context.Background()
- buffer := provider.bufferV1
+ buffer := provider.buffer
buffer.Enqueue(big.NewInt(1), logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0})
@@ -384,7 +359,6 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
t.Run("a log per upkeep for 4 upkeeps across 4 blocks (2 separate block windows) is dequeued, for a total of 4 payloads", func(t *testing.T) {
opts := NewOptions(200, big.NewInt(42161))
- opts.BufferVersion = "v1"
logPoller := &mockLogPoller{
LatestBlockFn: func(ctx context.Context) (int64, error) {
@@ -396,7 +370,7 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
ctx := context.Background()
- buffer := provider.bufferV1
+ buffer := provider.buffer
buffer.Enqueue(big.NewInt(1), logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0})
buffer.Enqueue(big.NewInt(2), logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0})
@@ -410,7 +384,6 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
t.Run("100 logs are dequeued for a single upkeep, 1 log for every block window across 100 blocks followed by best effort", func(t *testing.T) {
opts := NewOptions(200, big.NewInt(42161))
- opts.BufferVersion = "v1"
logPoller := &mockLogPoller{
LatestBlockFn: func(ctx context.Context) (int64, error) {
@@ -422,7 +395,7 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
ctx := context.Background()
- buffer := provider.bufferV1.(*logBuffer)
+ buffer := provider.buffer.(*logBuffer)
for i := 0; i < 100; i++ {
buffer.Enqueue(big.NewInt(1), logpoller.Log{BlockNumber: int64(i + 1), TxHash: common.HexToHash(fmt.Sprintf("0x%d", i+1)), LogIndex: 0})
@@ -439,7 +412,6 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
t.Run("100 logs are dequeued for two upkeeps, 25 logs each as min commitment (50 logs total best effort), followed by best effort", func(t *testing.T) {
opts := NewOptions(200, big.NewInt(42161))
- opts.BufferVersion = "v1"
logPoller := &mockLogPoller{
LatestBlockFn: func(ctx context.Context) (int64, error) {
@@ -451,7 +423,7 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
ctx := context.Background()
- buffer := provider.bufferV1.(*logBuffer)
+ buffer := provider.buffer.(*logBuffer)
for i := 0; i < 100; i++ {
buffer.Enqueue(big.NewInt(1), logpoller.Log{BlockNumber: int64(i + 1), TxHash: common.HexToHash(fmt.Sprintf("0x1%d", i+1)), LogIndex: 0})
@@ -491,7 +463,6 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
t.Run("minimum guaranteed for all windows including an incomplete window followed by best effort", func(t *testing.T) {
opts := NewOptions(200, big.NewInt(42161))
- opts.BufferVersion = "v1"
logPoller := &mockLogPoller{
LatestBlockFn: func(ctx context.Context) (int64, error) {
@@ -503,7 +474,7 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
ctx := context.Background()
- buffer := provider.bufferV1.(*logBuffer)
+ buffer := provider.buffer.(*logBuffer)
for i := 0; i < 102; i++ {
buffer.Enqueue(big.NewInt(1), logpoller.Log{BlockNumber: int64(i + 1), TxHash: common.HexToHash(fmt.Sprintf("0x1%d", i+1)), LogIndex: 0})
@@ -551,7 +522,6 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
t.Run("min dequeue followed by best effort followed by reorg followed by best effort", func(t *testing.T) {
opts := NewOptions(200, big.NewInt(42161))
- opts.BufferVersion = "v1"
logPoller := &mockLogPoller{
LatestBlockFn: func(ctx context.Context) (int64, error) {
@@ -563,7 +533,7 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
ctx := context.Background()
- buffer := provider.bufferV1.(*logBuffer)
+ buffer := provider.buffer.(*logBuffer)
for i := 0; i < 100; i++ {
buffer.Enqueue(big.NewInt(1), logpoller.Log{BlockNumber: int64(i + 1), TxHash: common.HexToHash(fmt.Sprintf("0x1%d", i+1)), LogIndex: 0})
@@ -606,7 +576,6 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
t.Run("sparsely populated blocks", func(t *testing.T) {
opts := NewOptions(200, big.NewInt(42161))
- opts.BufferVersion = "v1"
logPoller := &mockLogPoller{
LatestBlockFn: func(ctx context.Context) (int64, error) {
@@ -618,7 +587,7 @@ func TestLogEventProvider_GetLatestPayloads(t *testing.T) {
ctx := context.Background()
- buffer := provider.bufferV1.(*logBuffer)
+ buffer := provider.buffer.(*logBuffer)
upkeepOmittedOnBlocks := map[int64][]int{
1: {5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100}, // upkeep 1 won't have logs on 20 blocks
diff --git a/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go b/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go
index a79237cf04..7f74f9a38a 100644
--- a/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go
@@ -54,7 +54,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper"
- "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
@@ -119,7 +118,7 @@ func TestIntegration_KeeperPluginConditionalUpkeep(t *testing.T) {
require.NoError(t, err)
registry := deployKeeper21Registry(t, steve, backend, linkAddr, linkFeedAddr, gasFeedAddr)
- setupNodes(t, nodeKeys, registry, backend, steve, false)
+ setupNodes(t, nodeKeys, registry, backend, steve)
<-time.After(time.Second * 5)
@@ -173,368 +172,314 @@ func TestIntegration_KeeperPluginConditionalUpkeep(t *testing.T) {
}
func TestIntegration_KeeperPluginLogUpkeep(t *testing.T) {
- tests := []struct {
- name string
- logBufferVersion logprovider.BufferVersion
- }{
- {
- name: "default buffer",
- logBufferVersion: logprovider.BufferVersionDefault,
- },
- {
- name: "buffer v1",
- logBufferVersion: logprovider.BufferVersionV1,
- },
- }
+ g := gomega.NewWithT(t)
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- g := gomega.NewWithT(t)
-
- // setup blockchain
- sergey := testutils.MustNewSimTransactor(t) // owns all the link
- steve := testutils.MustNewSimTransactor(t) // registry owner
- carrol := testutils.MustNewSimTransactor(t) // upkeep owner
- genesisData := core.GenesisAlloc{
- sergey.From: {Balance: assets.Ether(10000).ToInt()},
- steve.From: {Balance: assets.Ether(10000).ToInt()},
- carrol.From: {Balance: assets.Ether(10000).ToInt()},
- }
- // Generate 5 keys for nodes (1 bootstrap + 4 ocr nodes) and fund them with ether
- var nodeKeys [5]ethkey.KeyV2
- for i := int64(0); i < 5; i++ {
- nodeKeys[i] = cltest.MustGenerateRandomKey(t)
- genesisData[nodeKeys[i].Address] = core.GenesisAccount{Balance: assets.Ether(1000).ToInt()}
- }
+ // setup blockchain
+ sergey := testutils.MustNewSimTransactor(t) // owns all the link
+ steve := testutils.MustNewSimTransactor(t) // registry owner
+ carrol := testutils.MustNewSimTransactor(t) // upkeep owner
+ genesisData := core.GenesisAlloc{
+ sergey.From: {Balance: assets.Ether(10000).ToInt()},
+ steve.From: {Balance: assets.Ether(10000).ToInt()},
+ carrol.From: {Balance: assets.Ether(10000).ToInt()},
+ }
+ // Generate 5 keys for nodes (1 bootstrap + 4 ocr nodes) and fund them with ether
+ var nodeKeys [5]ethkey.KeyV2
+ for i := int64(0); i < 5; i++ {
+ nodeKeys[i] = cltest.MustGenerateRandomKey(t)
+ genesisData[nodeKeys[i].Address] = core.GenesisAccount{Balance: assets.Ether(1000).ToInt()}
+ }
- backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil))
- stopMining := cltest.Mine(backend, 3*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain
- defer stopMining()
+ backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil))
+ stopMining := cltest.Mine(backend, 3*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain
+ defer stopMining()
- // Deploy registry
- linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(sergey, backend)
- require.NoError(t, err)
- gasFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(steve, backend, 18, big.NewInt(60000000000))
- require.NoError(t, err)
- linkFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(steve, backend, 18, big.NewInt(2000000000000000000))
- require.NoError(t, err)
+ // Deploy registry
+ linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(sergey, backend)
+ require.NoError(t, err)
+ gasFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(steve, backend, 18, big.NewInt(60000000000))
+ require.NoError(t, err)
+ linkFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(steve, backend, 18, big.NewInt(2000000000000000000))
+ require.NoError(t, err)
- registry := deployKeeper21Registry(t, steve, backend, linkAddr, linkFeedAddr, gasFeedAddr)
- setupNodes(t, nodeKeys, registry, backend, steve, tc.logBufferVersion == logprovider.BufferVersionV1)
- upkeeps := 1
+ registry := deployKeeper21Registry(t, steve, backend, linkAddr, linkFeedAddr, gasFeedAddr)
+ setupNodes(t, nodeKeys, registry, backend, steve)
+ upkeeps := 1
- _, err = linkToken.Transfer(sergey, carrol.From, big.NewInt(0).Mul(oneHunEth, big.NewInt(int64(upkeeps+1))))
- require.NoError(t, err)
+ _, err = linkToken.Transfer(sergey, carrol.From, big.NewInt(0).Mul(oneHunEth, big.NewInt(int64(upkeeps+1))))
+ require.NoError(t, err)
- backend.Commit()
+ backend.Commit()
- ids, addrs, contracts := deployUpkeeps(t, backend, carrol, steve, linkToken, registry, upkeeps)
- require.Equal(t, upkeeps, len(ids))
- require.Equal(t, len(ids), len(contracts))
- require.Equal(t, len(ids), len(addrs))
+ ids, addrs, contracts := deployUpkeeps(t, backend, carrol, steve, linkToken, registry, upkeeps)
+ require.Equal(t, upkeeps, len(ids))
+ require.Equal(t, len(ids), len(contracts))
+ require.Equal(t, len(ids), len(addrs))
- backend.Commit()
+ backend.Commit()
- emits := 1
- go emitEvents(testutils.Context(t), t, emits, contracts, carrol, func() {
- backend.Commit()
- })
+ emits := 1
+ go emitEvents(testutils.Context(t), t, emits, contracts, carrol, func() {
+ backend.Commit()
+ })
- listener, done := listenPerformed(t, backend, registry, ids, int64(1))
- g.Eventually(listener, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.BeTrue())
- done()
+ listener, done := listenPerformed(t, backend, registry, ids, int64(1))
+ g.Eventually(listener, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.BeTrue())
+ done()
- t.Run("recover logs", func(t *testing.T) {
- addr, contract := addrs[0], contracts[0]
- upkeepID := registerUpkeep(t, registry, addr, carrol, steve, backend)
+ t.Run("recover logs", func(t *testing.T) {
+ addr, contract := addrs[0], contracts[0]
+ upkeepID := registerUpkeep(t, registry, addr, carrol, steve, backend)
+ backend.Commit()
+ t.Logf("Registered new upkeep %s for address %s", upkeepID.String(), addr.String())
+ // Emit 100 logs in a burst
+ recoverEmits := 100
+ i := 0
+ emitEvents(testutils.Context(t), t, 100, []*log_upkeep_counter_wrapper.LogUpkeepCounter{contract}, carrol, func() {
+ i++
+ if i%(recoverEmits/4) == 0 {
backend.Commit()
- t.Logf("Registered new upkeep %s for address %s", upkeepID.String(), addr.String())
- // Emit 100 logs in a burst
- recoverEmits := 100
- i := 0
- emitEvents(testutils.Context(t), t, 100, []*log_upkeep_counter_wrapper.LogUpkeepCounter{contract}, carrol, func() {
- i++
- if i%(recoverEmits/4) == 0 {
- backend.Commit()
- time.Sleep(time.Millisecond * 250) // otherwise we get "invalid transaction nonce" errors
- }
- })
+ time.Sleep(time.Millisecond * 250) // otherwise we get "invalid transaction nonce" errors
+ }
+ })
- beforeDummyBlocks := backend.Blockchain().CurrentBlock().Number.Uint64()
+ beforeDummyBlocks := backend.Blockchain().CurrentBlock().Number.Uint64()
- // Mine enough blocks to ensure these logs don't fall into log provider range
- dummyBlocks := 500
- for i := 0; i < dummyBlocks; i++ {
- backend.Commit()
- time.Sleep(time.Millisecond * 10)
- }
+ // Mine enough blocks to ensure these logs don't fall into log provider range
+ dummyBlocks := 500
+ for i := 0; i < dummyBlocks; i++ {
+ backend.Commit()
+ time.Sleep(time.Millisecond * 10)
+ }
- t.Logf("Mined %d blocks, waiting for logs to be recovered", dummyBlocks)
+ t.Logf("Mined %d blocks, waiting for logs to be recovered", dummyBlocks)
- listener, done := listenPerformedN(t, backend, registry, ids, int64(beforeDummyBlocks), recoverEmits)
- defer done()
- g.Eventually(listener, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.BeTrue())
- })
- })
- }
+ listener, done := listenPerformedN(t, backend, registry, ids, int64(beforeDummyBlocks), recoverEmits)
+ defer done()
+ g.Eventually(listener, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.BeTrue())
+ })
}
func TestIntegration_KeeperPluginLogUpkeep_Retry(t *testing.T) {
- tests := []struct {
- name string
- logBufferVersion logprovider.BufferVersion
- }{
- {
- name: "default buffer",
- logBufferVersion: logprovider.BufferVersionDefault,
- },
- {
- name: "buffer v1",
- logBufferVersion: logprovider.BufferVersionV1,
- },
+ g := gomega.NewWithT(t)
+
+ // setup blockchain
+ linkOwner := testutils.MustNewSimTransactor(t) // owns all the link
+ registryOwner := testutils.MustNewSimTransactor(t) // registry owner
+ upkeepOwner := testutils.MustNewSimTransactor(t) // upkeep owner
+ genesisData := core.GenesisAlloc{
+ linkOwner.From: {Balance: assets.Ether(10000).ToInt()},
+ registryOwner.From: {Balance: assets.Ether(10000).ToInt()},
+ upkeepOwner.From: {Balance: assets.Ether(10000).ToInt()},
}
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- g := gomega.NewWithT(t)
-
- // setup blockchain
- linkOwner := testutils.MustNewSimTransactor(t) // owns all the link
- registryOwner := testutils.MustNewSimTransactor(t) // registry owner
- upkeepOwner := testutils.MustNewSimTransactor(t) // upkeep owner
- genesisData := core.GenesisAlloc{
- linkOwner.From: {Balance: assets.Ether(10000).ToInt()},
- registryOwner.From: {Balance: assets.Ether(10000).ToInt()},
- upkeepOwner.From: {Balance: assets.Ether(10000).ToInt()},
- }
+ // Generate 5 keys for nodes (1 bootstrap + 4 ocr nodes) and fund them with ether
+ var nodeKeys [5]ethkey.KeyV2
+ for i := int64(0); i < 5; i++ {
+ nodeKeys[i] = cltest.MustGenerateRandomKey(t)
+ genesisData[nodeKeys[i].Address] = core.GenesisAccount{Balance: assets.Ether(1000).ToInt()}
+ }
- // Generate 5 keys for nodes (1 bootstrap + 4 ocr nodes) and fund them with ether
- var nodeKeys [5]ethkey.KeyV2
- for i := int64(0); i < 5; i++ {
- nodeKeys[i] = cltest.MustGenerateRandomKey(t)
- genesisData[nodeKeys[i].Address] = core.GenesisAccount{Balance: assets.Ether(1000).ToInt()}
- }
+ backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil))
+ stopMining := cltest.Mine(backend, 3*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain
+ defer stopMining()
- backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil))
- stopMining := cltest.Mine(backend, 3*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain
- defer stopMining()
+ // Deploy registry
+ linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(linkOwner, backend)
+ require.NoError(t, err)
- // Deploy registry
- linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(linkOwner, backend)
- require.NoError(t, err)
+ gasFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(registryOwner, backend, 18, big.NewInt(60000000000))
+ require.NoError(t, err)
- gasFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(registryOwner, backend, 18, big.NewInt(60000000000))
- require.NoError(t, err)
+ linkFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(registryOwner, backend, 18, big.NewInt(2000000000000000000))
+ require.NoError(t, err)
- linkFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(registryOwner, backend, 18, big.NewInt(2000000000000000000))
- require.NoError(t, err)
+ registry := deployKeeper21Registry(t, registryOwner, backend, linkAddr, linkFeedAddr, gasFeedAddr)
- registry := deployKeeper21Registry(t, registryOwner, backend, linkAddr, linkFeedAddr, gasFeedAddr)
+ _, mercuryServer := setupNodes(t, nodeKeys, registry, backend, registryOwner)
- _, mercuryServer := setupNodes(t, nodeKeys, registry, backend, registryOwner, tc.logBufferVersion == logprovider.BufferVersionV1)
+ const upkeepCount = 10
+ const mercuryFailCount = upkeepCount * 3 * 2
- const upkeepCount = 10
- const mercuryFailCount = upkeepCount * 3 * 2
+ // testing with the mercury server involves mocking responses. currently,
+ // there is not a way to connect a mercury call to an upkeep id (though we
+ // could add custom headers) so the test must be fairly basic and just
+ // count calls before switching to successes
+ var (
+ mu sync.Mutex
+ count int
+ )
- // testing with the mercury server involves mocking responses. currently,
- // there is not a way to connect a mercury call to an upkeep id (though we
- // could add custom headers) so the test must be fairly basic and just
- // count calls before switching to successes
- var (
- mu sync.Mutex
- count int
- )
+ mercuryServer.RegisterHandler(func(w http.ResponseWriter, r *http.Request) {
+ mu.Lock()
+ defer mu.Unlock()
- mercuryServer.RegisterHandler(func(w http.ResponseWriter, r *http.Request) {
- mu.Lock()
- defer mu.Unlock()
+ count++
- count++
+ _ = r.ParseForm()
- _ = r.ParseForm()
+ t.Logf("MercuryHTTPServe:RequestURI: %s", r.RequestURI)
- t.Logf("MercuryHTTPServe:RequestURI: %s", r.RequestURI)
+ for key, value := range r.Form {
+ t.Logf("MercuryHTTPServe:FormValue: key: %s; value: %s;", key, value)
+ }
- for key, value := range r.Form {
- t.Logf("MercuryHTTPServe:FormValue: key: %s; value: %s;", key, value)
- }
+ // the streams lookup retries against the remote server 3 times before
+ // returning a result as retryable.
+ // the simulation here should force the streams lookup process to return
+ // retryable 2 times.
+ // the total count of failures should be (upkeepCount * 3 * tryCount)
+ if count <= mercuryFailCount {
+ w.WriteHeader(http.StatusNotFound)
- // the streams lookup retries against the remote server 3 times before
- // returning a result as retryable.
- // the simulation here should force the streams lookup process to return
- // retryable 2 times.
- // the total count of failures should be (upkeepCount * 3 * tryCount)
- if count <= mercuryFailCount {
- w.WriteHeader(http.StatusNotFound)
+ return
+ }
- return
- }
+ // start sending success messages
+ output := `{"chainlinkBlob":"0x0001c38d71fed6c320b90e84b6f559459814d068e2a1700adc931ca9717d4fe70000000000000000000000000000000000000000000000000000000001a80b52b4bf1233f9cb71144a253a1791b202113c4ab4a92fa1b176d684b4959666ff8200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001004254432d5553442d415242495452554d2d544553544e4554000000000000000000000000000000000000000000000000000000000000000000000000645570be000000000000000000000000000000000000000000000000000002af2b818dc5000000000000000000000000000000000000000000000000000002af2426faf3000000000000000000000000000000000000000000000000000002af32dc209700000000000000000000000000000000000000000000000000000000012130f8df0a9745bb6ad5e2df605e158ba8ad8a33ef8a0acf9851f0f01668a3a3f2b68600000000000000000000000000000000000000000000000000000000012130f60000000000000000000000000000000000000000000000000000000000000002c4a7958dce105089cf5edb68dad7dcfe8618d7784eb397f97d5a5fade78c11a58275aebda478968e545f7e3657aba9dcbe8d44605e4c6fde3e24edd5e22c94270000000000000000000000000000000000000000000000000000000000000002459c12d33986018a8959566d145225f0c4a4e61a9a3f50361ccff397899314f0018162cf10cd89897635a0bb62a822355bd199d09f4abe76e4d05261bb44733d"}`
- // start sending success messages
- output := `{"chainlinkBlob":"0x0001c38d71fed6c320b90e84b6f559459814d068e2a1700adc931ca9717d4fe70000000000000000000000000000000000000000000000000000000001a80b52b4bf1233f9cb71144a253a1791b202113c4ab4a92fa1b176d684b4959666ff8200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001004254432d5553442d415242495452554d2d544553544e4554000000000000000000000000000000000000000000000000000000000000000000000000645570be000000000000000000000000000000000000000000000000000002af2b818dc5000000000000000000000000000000000000000000000000000002af2426faf3000000000000000000000000000000000000000000000000000002af32dc209700000000000000000000000000000000000000000000000000000000012130f8df0a9745bb6ad5e2df605e158ba8ad8a33ef8a0acf9851f0f01668a3a3f2b68600000000000000000000000000000000000000000000000000000000012130f60000000000000000000000000000000000000000000000000000000000000002c4a7958dce105089cf5edb68dad7dcfe8618d7784eb397f97d5a5fade78c11a58275aebda478968e545f7e3657aba9dcbe8d44605e4c6fde3e24edd5e22c94270000000000000000000000000000000000000000000000000000000000000002459c12d33986018a8959566d145225f0c4a4e61a9a3f50361ccff397899314f0018162cf10cd89897635a0bb62a822355bd199d09f4abe76e4d05261bb44733d"}`
+ w.WriteHeader(http.StatusOK)
+ _, _ = w.Write([]byte(output))
+ })
- w.WriteHeader(http.StatusOK)
- _, _ = w.Write([]byte(output))
- })
+ defer mercuryServer.Stop()
- defer mercuryServer.Stop()
+ _, err = linkToken.Transfer(linkOwner, upkeepOwner.From, big.NewInt(0).Mul(oneHunEth, big.NewInt(int64(upkeepCount+1))))
+ require.NoError(t, err)
- _, err = linkToken.Transfer(linkOwner, upkeepOwner.From, big.NewInt(0).Mul(oneHunEth, big.NewInt(int64(upkeepCount+1))))
- require.NoError(t, err)
+ backend.Commit()
- backend.Commit()
+ feeds, err := newFeedLookupUpkeepController(backend, registryOwner)
+ require.NoError(t, err, "no error expected from creating a feed lookup controller")
+
+ // deploy multiple upkeeps that listen to a log emitter and need to be
+ // performed for each log event
+ _ = feeds.DeployUpkeeps(t, backend, upkeepOwner, upkeepCount, func(int) bool {
+ return false
+ })
+ _ = feeds.RegisterAndFund(t, registry, registryOwner, backend, linkToken)
+ _ = feeds.EnableMercury(t, backend, registry, registryOwner)
+ _ = feeds.VerifyEnv(t, backend, registry, registryOwner)
- feeds, err := newFeedLookupUpkeepController(backend, registryOwner)
- require.NoError(t, err, "no error expected from creating a feed lookup controller")
-
- // deploy multiple upkeeps that listen to a log emitter and need to be
- // performed for each log event
- _ = feeds.DeployUpkeeps(t, backend, upkeepOwner, upkeepCount, func(int) bool {
- return false
- })
- _ = feeds.RegisterAndFund(t, registry, registryOwner, backend, linkToken)
- _ = feeds.EnableMercury(t, backend, registry, registryOwner)
- _ = feeds.VerifyEnv(t, backend, registry, registryOwner)
-
- // start emitting events in a separate go-routine
- // feed lookup relies on a single contract event log to perform multiple
- // listener contracts
- go func() {
- // only 1 event is necessary to make all 10 upkeeps eligible
- _ = feeds.EmitEvents(t, backend, 1, func() {
- // pause per emit for expected block production time
- time.Sleep(3 * time.Second)
- })
- }()
-
- listener, done := listenPerformed(t, backend, registry, feeds.UpkeepsIds(), int64(1))
- defer done()
- g.Eventually(listener, testutils.WaitTimeout(t)-(5*time.Second), cltest.DBPollingInterval).Should(gomega.BeTrue())
+ // start emitting events in a separate go-routine
+ // feed lookup relies on a single contract event log to perform multiple
+ // listener contracts
+ go func() {
+ // only 1 event is necessary to make all 10 upkeeps eligible
+ _ = feeds.EmitEvents(t, backend, 1, func() {
+ // pause per emit for expected block production time
+ time.Sleep(3 * time.Second)
})
- }
+ }()
+
+ listener, done := listenPerformed(t, backend, registry, feeds.UpkeepsIds(), int64(1))
+ defer done()
+ g.Eventually(listener, testutils.WaitTimeout(t)-(5*time.Second), cltest.DBPollingInterval).Should(gomega.BeTrue())
}
func TestIntegration_KeeperPluginLogUpkeep_ErrHandler(t *testing.T) {
- tests := []struct {
- name string
- logBufferVersion logprovider.BufferVersion
- }{
- {
- name: "default buffer",
- logBufferVersion: logprovider.BufferVersionDefault,
- },
- {
- name: "buffer v1",
- logBufferVersion: logprovider.BufferVersionV1,
- },
+ g := gomega.NewWithT(t)
+
+ // setup blockchain
+ linkOwner := testutils.MustNewSimTransactor(t) // owns all the link
+ registryOwner := testutils.MustNewSimTransactor(t) // registry owner
+ upkeepOwner := testutils.MustNewSimTransactor(t) // upkeep owner
+ genesisData := core.GenesisAlloc{
+ linkOwner.From: {Balance: assets.Ether(10000).ToInt()},
+ registryOwner.From: {Balance: assets.Ether(10000).ToInt()},
+ upkeepOwner.From: {Balance: assets.Ether(10000).ToInt()},
}
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- g := gomega.NewWithT(t)
-
- // setup blockchain
- linkOwner := testutils.MustNewSimTransactor(t) // owns all the link
- registryOwner := testutils.MustNewSimTransactor(t) // registry owner
- upkeepOwner := testutils.MustNewSimTransactor(t) // upkeep owner
- genesisData := core.GenesisAlloc{
- linkOwner.From: {Balance: assets.Ether(10000).ToInt()},
- registryOwner.From: {Balance: assets.Ether(10000).ToInt()},
- upkeepOwner.From: {Balance: assets.Ether(10000).ToInt()},
- }
+ // Generate 5 keys for nodes (1 bootstrap + 4 ocr nodes) and fund them with ether
+ var nodeKeys [5]ethkey.KeyV2
+ for i := int64(0); i < 5; i++ {
+ nodeKeys[i] = cltest.MustGenerateRandomKey(t)
+ genesisData[nodeKeys[i].Address] = core.GenesisAccount{Balance: assets.Ether(1000).ToInt()}
+ }
- // Generate 5 keys for nodes (1 bootstrap + 4 ocr nodes) and fund them with ether
- var nodeKeys [5]ethkey.KeyV2
- for i := int64(0); i < 5; i++ {
- nodeKeys[i] = cltest.MustGenerateRandomKey(t)
- genesisData[nodeKeys[i].Address] = core.GenesisAccount{Balance: assets.Ether(1000).ToInt()}
- }
+ backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil))
+ stopMining := cltest.Mine(backend, 3*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain
+ defer stopMining()
- backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil))
- stopMining := cltest.Mine(backend, 3*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain
- defer stopMining()
+ // Deploy registry
+ linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(linkOwner, backend)
+ require.NoError(t, err)
- // Deploy registry
- linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(linkOwner, backend)
- require.NoError(t, err)
+ gasFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(registryOwner, backend, 18, big.NewInt(60000000000))
+ require.NoError(t, err)
- gasFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(registryOwner, backend, 18, big.NewInt(60000000000))
- require.NoError(t, err)
+ linkFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(registryOwner, backend, 18, big.NewInt(2000000000000000000))
+ require.NoError(t, err)
- linkFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(registryOwner, backend, 18, big.NewInt(2000000000000000000))
- require.NoError(t, err)
+ registry := deployKeeper21Registry(t, registryOwner, backend, linkAddr, linkFeedAddr, gasFeedAddr)
- registry := deployKeeper21Registry(t, registryOwner, backend, linkAddr, linkFeedAddr, gasFeedAddr)
+ _, mercuryServer := setupNodes(t, nodeKeys, registry, backend, registryOwner)
- _, mercuryServer := setupNodes(t, nodeKeys, registry, backend, registryOwner, tc.logBufferVersion == logprovider.BufferVersionV1)
+ upkeepCount := 10
- upkeepCount := 10
+ errResponses := []int{
+ http.StatusUnauthorized,
+ http.StatusBadRequest,
+ http.StatusInternalServerError,
+ http.StatusNotFound,
+ http.StatusNotFound,
+ http.StatusNotFound,
+ http.StatusUnauthorized,
+ }
+ startMercuryServer(t, mercuryServer, func(i int) (int, []byte) {
+ var resp int
+ if i < len(errResponses) {
+ resp = errResponses[i]
+ }
+ if resp == 0 {
+ resp = http.StatusNotFound
+ }
+ return resp, nil
+ })
+ defer mercuryServer.Stop()
- errResponses := []int{
- http.StatusUnauthorized,
- http.StatusBadRequest,
- http.StatusInternalServerError,
- http.StatusNotFound,
- http.StatusNotFound,
- http.StatusNotFound,
- http.StatusUnauthorized,
- }
- startMercuryServer(t, mercuryServer, func(i int) (int, []byte) {
- var resp int
- if i < len(errResponses) {
- resp = errResponses[i]
- }
- if resp == 0 {
- resp = http.StatusNotFound
- }
- return resp, nil
- })
- defer mercuryServer.Stop()
+ _, err = linkToken.Transfer(linkOwner, upkeepOwner.From, big.NewInt(0).Mul(oneHunEth, big.NewInt(int64(upkeepCount+1))))
+ require.NoError(t, err)
- _, err = linkToken.Transfer(linkOwner, upkeepOwner.From, big.NewInt(0).Mul(oneHunEth, big.NewInt(int64(upkeepCount+1))))
- require.NoError(t, err)
+ backend.Commit()
- backend.Commit()
+ feeds, err := newFeedLookupUpkeepController(backend, registryOwner)
+ require.NoError(t, err, "no error expected from creating a feed lookup controller")
- feeds, err := newFeedLookupUpkeepController(backend, registryOwner)
- require.NoError(t, err, "no error expected from creating a feed lookup controller")
+ // deploy multiple upkeeps that listen to a log emitter and need to be
+ // performed for each log event
+ checkResultsProvider := func(i int) bool {
+ return i%2 == 1
+ }
+ require.NoError(t, feeds.DeployUpkeeps(t, backend, upkeepOwner, upkeepCount, checkResultsProvider))
+ require.NoError(t, feeds.RegisterAndFund(t, registry, registryOwner, backend, linkToken))
+ require.NoError(t, feeds.EnableMercury(t, backend, registry, registryOwner))
+ require.NoError(t, feeds.VerifyEnv(t, backend, registry, registryOwner))
+
+ startBlock := backend.Blockchain().CurrentBlock().Number.Int64()
+ // start emitting events in a separate go-routine
+ // feed lookup relies on a single contract event log to perform multiple
+ // listener contracts
+ go func() {
+ // only 1 event is necessary to make all 10 upkeeps eligible
+ _ = feeds.EmitEvents(t, backend, 1, func() {
+ // pause per emit for expected block production time
+ time.Sleep(3 * time.Second)
+ })
+ }()
- // deploy multiple upkeeps that listen to a log emitter and need to be
- // performed for each log event
- checkResultsProvider := func(i int) bool {
- return i%2 == 1
- }
- require.NoError(t, feeds.DeployUpkeeps(t, backend, upkeepOwner, upkeepCount, checkResultsProvider))
- require.NoError(t, feeds.RegisterAndFund(t, registry, registryOwner, backend, linkToken))
- require.NoError(t, feeds.EnableMercury(t, backend, registry, registryOwner))
- require.NoError(t, feeds.VerifyEnv(t, backend, registry, registryOwner))
-
- startBlock := backend.Blockchain().CurrentBlock().Number.Int64()
- // start emitting events in a separate go-routine
- // feed lookup relies on a single contract event log to perform multiple
- // listener contracts
- go func() {
- // only 1 event is necessary to make all 10 upkeeps eligible
- _ = feeds.EmitEvents(t, backend, 1, func() {
- // pause per emit for expected block production time
- time.Sleep(3 * time.Second)
- })
- }()
-
- go makeDummyBlocks(t, backend, 3*time.Second, 1000)
-
- idsToCheck := make([]*big.Int, 0)
- for i, uid := range feeds.UpkeepsIds() {
- if checkResultsProvider(i) {
- idsToCheck = append(idsToCheck, uid)
- }
- }
+ go makeDummyBlocks(t, backend, 3*time.Second, 1000)
- listener, done := listenPerformed(t, backend, registry, idsToCheck, startBlock)
- defer done()
- g.Eventually(listener, testutils.WaitTimeout(t)-(5*time.Second), cltest.DBPollingInterval).Should(gomega.BeTrue())
- })
+ idsToCheck := make([]*big.Int, 0)
+ for i, uid := range feeds.UpkeepsIds() {
+ if checkResultsProvider(i) {
+ idsToCheck = append(idsToCheck, uid)
+ }
}
+
+ listener, done := listenPerformed(t, backend, registry, idsToCheck, startBlock)
+ defer done()
+ g.Eventually(listener, testutils.WaitTimeout(t)-(5*time.Second), cltest.DBPollingInterval).Should(gomega.BeTrue())
}
func startMercuryServer(t *testing.T, mercuryServer *mercury.SimulatedMercuryServer, responder func(i int) (int, []byte)) {
@@ -644,7 +589,7 @@ func listenPerformed(t *testing.T, backend *backends.SimulatedBackend, registry
return listenPerformedN(t, backend, registry, ids, startBlock, 0)
}
-func setupNodes(t *testing.T, nodeKeys [5]ethkey.KeyV2, registry *iregistry21.IKeeperRegistryMaster, backend *backends.SimulatedBackend, usr *bind.TransactOpts, useBufferV1 bool) ([]Node, *mercury.SimulatedMercuryServer) {
+func setupNodes(t *testing.T, nodeKeys [5]ethkey.KeyV2, registry *iregistry21.IKeeperRegistryMaster, backend *backends.SimulatedBackend, usr *bind.TransactOpts) ([]Node, *mercury.SimulatedMercuryServer) {
lggr := logger.TestLogger(t)
mServer := mercury.NewSimulatedMercuryServer()
mServer.Start()
@@ -727,8 +672,7 @@ func setupNodes(t *testing.T, nodeKeys [5]ethkey.KeyV2, registry *iregistry21.IK
cacheEvictionInterval = "1s"
mercuryCredentialName = "%s"
contractVersion = "v2.1"
- useBufferV1 = %v
- `, i, registry.Address(), node.KeyBundle.ID(), node.Transmitter, fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), MercuryCredName, useBufferV1))
+ `, i, registry.Address(), node.KeyBundle.ID(), node.Transmitter, fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), MercuryCredName))
}
// Setup config on contract
diff --git a/core/services/headreporter/prometheus_reporter.go b/core/services/promreporter/prom_reporter.go
similarity index 63%
rename from core/services/headreporter/prometheus_reporter.go
rename to core/services/promreporter/prom_reporter.go
index 3e39c7aca4..31d5f1129e 100644
--- a/core/services/headreporter/prometheus_reporter.go
+++ b/core/services/promreporter/prom_reporter.go
@@ -1,28 +1,40 @@
-package headreporter
+package promreporter
import (
"context"
"fmt"
"math/big"
+ "sync"
"time"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
+ txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
+
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"go.uber.org/multierr"
- "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
- txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr"
- "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
+ "github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
+
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
)
type (
- prometheusReporter struct {
- ds sqlutil.DataSource
- chains legacyevm.LegacyChainContainer
- backend PrometheusBackend
+ promReporter struct {
+ services.StateMachine
+ ds sqlutil.DataSource
+ chains legacyevm.LegacyChainContainer
+ lggr logger.Logger
+ backend PrometheusBackend
+ newHeads *mailbox.Mailbox[*evmtypes.Head]
+ chStop services.StopChan
+ wgDone sync.WaitGroup
+ reportPeriod time.Duration
}
PrometheusBackend interface {
@@ -59,15 +71,103 @@ var (
})
)
-func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer) *prometheusReporter {
- return &prometheusReporter{
- ds: ds,
- chains: chainContainer,
- backend: defaultBackend{},
+func (defaultBackend) SetUnconfirmedTransactions(evmChainID *big.Int, n int64) {
+ promUnconfirmedTransactions.WithLabelValues(evmChainID.String()).Set(float64(n))
+}
+
+func (defaultBackend) SetMaxUnconfirmedAge(evmChainID *big.Int, s float64) {
+ promMaxUnconfirmedAge.WithLabelValues(evmChainID.String()).Set(s)
+}
+
+func (defaultBackend) SetMaxUnconfirmedBlocks(evmChainID *big.Int, n int64) {
+ promMaxUnconfirmedBlocks.WithLabelValues(evmChainID.String()).Set(float64(n))
+}
+
+func (defaultBackend) SetPipelineRunsQueued(n int) {
+ promPipelineTaskRunsQueued.Set(float64(n))
+}
+
+func (defaultBackend) SetPipelineTaskRunsQueued(n int) {
+ promPipelineRunsQueued.Set(float64(n))
+}
+
+func NewPromReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) *promReporter {
+ var backend PrometheusBackend = defaultBackend{}
+ period := 15 * time.Second
+ for _, opt := range opts {
+ switch v := opt.(type) {
+ case time.Duration:
+ period = v
+ case PrometheusBackend:
+ backend = v
+ }
+ }
+
+ chStop := make(chan struct{})
+ return &promReporter{
+ ds: ds,
+ chains: chainContainer,
+ lggr: lggr.Named("PromReporter"),
+ backend: backend,
+ newHeads: mailbox.NewSingle[*evmtypes.Head](),
+ chStop: chStop,
+ reportPeriod: period,
}
}
-func (pr *prometheusReporter) getTxm(evmChainID *big.Int) (txmgr.TxManager, error) {
+// Start starts PromReporter.
+func (pr *promReporter) Start(context.Context) error {
+ return pr.StartOnce("PromReporter", func() error {
+ pr.wgDone.Add(1)
+ go pr.eventLoop()
+ return nil
+ })
+}
+
+func (pr *promReporter) Close() error {
+ return pr.StopOnce("PromReporter", func() error {
+ close(pr.chStop)
+ pr.wgDone.Wait()
+ return nil
+ })
+}
+func (pr *promReporter) Name() string {
+ return pr.lggr.Name()
+}
+
+func (pr *promReporter) HealthReport() map[string]error {
+ return map[string]error{pr.Name(): pr.Healthy()}
+}
+
+func (pr *promReporter) OnNewLongestChain(ctx context.Context, head *evmtypes.Head) {
+ pr.newHeads.Deliver(head)
+}
+
+func (pr *promReporter) eventLoop() {
+ pr.lggr.Debug("Starting event loop")
+ defer pr.wgDone.Done()
+ ctx, cancel := pr.chStop.NewCtx()
+ defer cancel()
+ for {
+ select {
+ case <-pr.newHeads.Notify():
+ head, exists := pr.newHeads.Retrieve()
+ if !exists {
+ continue
+ }
+ pr.reportHeadMetrics(ctx, head)
+ case <-time.After(pr.reportPeriod):
+ if err := errors.Wrap(pr.reportPipelineRunStats(ctx), "reportPipelineRunStats failed"); err != nil {
+ pr.lggr.Errorw("Error reporting prometheus metrics", "err", err)
+ }
+
+ case <-pr.chStop:
+ return
+ }
+ }
+}
+
+func (pr *promReporter) getTxm(evmChainID *big.Int) (txmgr.TxManager, error) {
chain, err := pr.chains.Get(evmChainID.String())
if err != nil {
return nil, fmt.Errorf("failed to get chain: %w", err)
@@ -75,16 +175,20 @@ func (pr *prometheusReporter) getTxm(evmChainID *big.Int) (txmgr.TxManager, erro
return chain.TxManager(), nil
}
-func (pr *prometheusReporter) ReportNewHead(ctx context.Context, head *evmtypes.Head) error {
+func (pr *promReporter) reportHeadMetrics(ctx context.Context, head *evmtypes.Head) {
evmChainID := head.EVMChainID.ToInt()
- return multierr.Combine(
+ err := multierr.Combine(
errors.Wrap(pr.reportPendingEthTxes(ctx, evmChainID), "reportPendingEthTxes failed"),
errors.Wrap(pr.reportMaxUnconfirmedAge(ctx, evmChainID), "reportMaxUnconfirmedAge failed"),
errors.Wrap(pr.reportMaxUnconfirmedBlocks(ctx, head), "reportMaxUnconfirmedBlocks failed"),
)
+
+ if err != nil && ctx.Err() == nil {
+ pr.lggr.Errorw("Error reporting prometheus metrics", "err", err)
+ }
}
-func (pr *prometheusReporter) reportPendingEthTxes(ctx context.Context, evmChainID *big.Int) (err error) {
+func (pr *promReporter) reportPendingEthTxes(ctx context.Context, evmChainID *big.Int) (err error) {
txm, err := pr.getTxm(evmChainID)
if err != nil {
return fmt.Errorf("failed to get txm: %w", err)
@@ -98,7 +202,7 @@ func (pr *prometheusReporter) reportPendingEthTxes(ctx context.Context, evmChain
return nil
}
-func (pr *prometheusReporter) reportMaxUnconfirmedAge(ctx context.Context, evmChainID *big.Int) (err error) {
+func (pr *promReporter) reportMaxUnconfirmedAge(ctx context.Context, evmChainID *big.Int) (err error) {
txm, err := pr.getTxm(evmChainID)
if err != nil {
return fmt.Errorf("failed to get txm: %w", err)
@@ -117,7 +221,7 @@ func (pr *prometheusReporter) reportMaxUnconfirmedAge(ctx context.Context, evmCh
return nil
}
-func (pr *prometheusReporter) reportMaxUnconfirmedBlocks(ctx context.Context, head *evmtypes.Head) (err error) {
+func (pr *promReporter) reportMaxUnconfirmedBlocks(ctx context.Context, head *evmtypes.Head) (err error) {
txm, err := pr.getTxm(head.EVMChainID.ToInt())
if err != nil {
return fmt.Errorf("failed to get txm: %w", err)
@@ -136,11 +240,7 @@ func (pr *prometheusReporter) reportMaxUnconfirmedBlocks(ctx context.Context, he
return nil
}
-func (pr *prometheusReporter) ReportPeriodic(ctx context.Context) error {
- return errors.Wrap(pr.reportPipelineRunStats(ctx), "reportPipelineRunStats failed")
-}
-
-func (pr *prometheusReporter) reportPipelineRunStats(ctx context.Context) (err error) {
+func (pr *promReporter) reportPipelineRunStats(ctx context.Context) (err error) {
rows, err := pr.ds.QueryContext(ctx, `
SELECT pipeline_run_id FROM pipeline_task_runs WHERE finished_at IS NULL
`)
@@ -171,23 +271,3 @@ SELECT pipeline_run_id FROM pipeline_task_runs WHERE finished_at IS NULL
return nil
}
-
-func (defaultBackend) SetUnconfirmedTransactions(evmChainID *big.Int, n int64) {
- promUnconfirmedTransactions.WithLabelValues(evmChainID.String()).Set(float64(n))
-}
-
-func (defaultBackend) SetMaxUnconfirmedAge(evmChainID *big.Int, s float64) {
- promMaxUnconfirmedAge.WithLabelValues(evmChainID.String()).Set(s)
-}
-
-func (defaultBackend) SetMaxUnconfirmedBlocks(evmChainID *big.Int, n int64) {
- promMaxUnconfirmedBlocks.WithLabelValues(evmChainID.String()).Set(float64(n))
-}
-
-func (defaultBackend) SetPipelineRunsQueued(n int) {
- promPipelineTaskRunsQueued.Set(float64(n))
-}
-
-func (defaultBackend) SetPipelineTaskRunsQueued(n int) {
- promPipelineRunsQueued.Set(float64(n))
-}
diff --git a/core/services/headreporter/prometheus_reporter_test.go b/core/services/promreporter/prom_reporter_test.go
similarity index 64%
rename from core/services/headreporter/prometheus_reporter_test.go
rename to core/services/promreporter/prom_reporter_test.go
index 32d2c09d0e..b61fa25bdc 100644
--- a/core/services/headreporter/prometheus_reporter_test.go
+++ b/core/services/promreporter/prom_reporter_test.go
@@ -1,7 +1,8 @@
-package headreporter_test
+package promreporter_test
import (
"math/big"
+ "sync/atomic"
"testing"
"time"
@@ -9,40 +10,90 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest"
+
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
+ evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
+ ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
"github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/mocks"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/headreporter"
+ "github.com/smartcontractkit/chainlink/v2/core/services/promreporter"
)
-func Test_PrometheusReporter(t *testing.T) {
+func newHead() evmtypes.Head {
+ return evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(0)}
+}
+
+func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer {
+ config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t)
+ keyStore := cltest.NewKeyStore(t, db).Eth()
+ ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator())
+ require.NoError(t, err)
+ lggr := logger.TestLogger(t)
+ lpOpts := logpoller.Opts{
+ PollPeriod: 100 * time.Millisecond,
+ FinalityDepth: 2,
+ BackfillBatchSize: 3,
+ RpcBatchSize: 2,
+ KeepFinalizedBlocksDepth: 1000,
+ }
+ ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth)
+ lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, ht, lpOpts)
+
+ txm, err := txmgr.NewTxm(
+ db,
+ evmConfig,
+ evmConfig.GasEstimator(),
+ evmConfig.Transactions(),
+ nil,
+ dbConfig,
+ dbConfig.Listener(),
+ ethClient,
+ lggr,
+ lp,
+ keyStore,
+ estimator)
+ require.NoError(t, err)
+
+ cfg := configtest.NewGeneralConfig(t, nil)
+ return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm)
+}
+
+func Test_PromReporter_OnNewLongestChain(t *testing.T) {
t.Run("with nothing in the database", func(t *testing.T) {
db := pgtest.NewSqlxDB(t)
- backend := headreporter.NewMockPrometheusBackend(t)
+ backend := mocks.NewPrometheusBackend(t)
+ reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond)
+
+ var subscribeCalls atomic.Int32
+
backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return()
backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return()
backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return()
+ backend.On("SetPipelineTaskRunsQueued", 0).Return()
+ backend.On("SetPipelineRunsQueued", 0).
+ Run(func(args mock.Arguments) {
+ subscribeCalls.Add(1)
+ }).
+ Return()
- reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db))
- reporter.SetBackend(backend)
+ servicetest.Run(t, reporter)
- head := headreporter.NewHead()
- err := reporter.ReportNewHead(testutils.Context(t), &head)
- require.NoError(t, err)
+ head := newHead()
+ reporter.OnNewLongestChain(testutils.Context(t), &head)
- backend.On("SetPipelineTaskRunsQueued", 0).Return()
- backend.On("SetPipelineRunsQueued", 0).Return()
- err = reporter.ReportPeriodic(testutils.Context(t))
- require.NoError(t, err)
+ require.Eventually(t, func() bool { return subscribeCalls.Load() >= 1 }, 12*time.Second, 100*time.Millisecond)
})
t.Run("with unconfirmed evm.txes", func(t *testing.T) {
@@ -51,92 +102,61 @@ func Test_PrometheusReporter(t *testing.T) {
ethKeyStore := cltest.NewKeyStore(t, db).Eth()
_, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore)
- etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress)
- cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, fromAddress)
- cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress)
- require.NoError(t, txStore.UpdateTxAttemptBroadcastBeforeBlockNum(testutils.Context(t), etx.ID, 7))
+ var subscribeCalls atomic.Int32
- backend := headreporter.NewMockPrometheusBackend(t)
+ backend := mocks.NewPrometheusBackend(t)
backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(3)).Return()
backend.On("SetMaxUnconfirmedAge", big.NewInt(0), mock.MatchedBy(func(s float64) bool {
return s > 0
})).Return()
backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(35)).Return()
+ backend.On("SetPipelineTaskRunsQueued", 0).Return()
+ backend.On("SetPipelineRunsQueued", 0).
+ Run(func(args mock.Arguments) {
+ subscribeCalls.Add(1)
+ }).
+ Return()
+ reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond)
+ servicetest.Run(t, reporter)
- reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db))
- reporter.SetBackend(backend)
-
- head := headreporter.NewHead()
- err := reporter.ReportNewHead(testutils.Context(t), &head)
- require.NoError(t, err)
+ etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress)
+ cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, fromAddress)
+ cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress)
+ require.NoError(t, txStore.UpdateTxAttemptBroadcastBeforeBlockNum(testutils.Context(t), etx.ID, 7))
- backend.On("SetPipelineTaskRunsQueued", 0).Return()
- backend.On("SetPipelineRunsQueued", 0).Return()
+ head := newHead()
+ reporter.OnNewLongestChain(testutils.Context(t), &head)
- err = reporter.ReportPeriodic(testutils.Context(t))
- require.NoError(t, err)
+ require.Eventually(t, func() bool { return subscribeCalls.Load() >= 1 }, 12*time.Second, 100*time.Millisecond)
})
t.Run("with unfinished pipeline task runs", func(t *testing.T) {
db := pgtest.NewSqlxDB(t)
pgtest.MustExec(t, db, `SET CONSTRAINTS pipeline_task_runs_pipeline_run_id_fkey DEFERRED`)
+ backend := mocks.NewPrometheusBackend(t)
+ reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond)
+
cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1)
cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1)
cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 2)
- backend := headreporter.NewMockPrometheusBackend(t)
+ var subscribeCalls atomic.Int32
+
backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return()
backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return()
backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return()
-
- reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db))
- reporter.SetBackend(backend)
-
- head := headreporter.NewHead()
- err := reporter.ReportNewHead(testutils.Context(t), &head)
- require.NoError(t, err)
-
backend.On("SetPipelineTaskRunsQueued", 3).Return()
- backend.On("SetPipelineRunsQueued", 2).Return()
-
- err = reporter.ReportPeriodic(testutils.Context(t))
- require.NoError(t, err)
- })
-}
-
-func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer {
- config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t)
- keyStore := cltest.NewKeyStore(t, db).Eth()
- ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator())
- require.NoError(t, err)
- lggr := logger.TestLogger(t)
- lpOpts := logpoller.Opts{
- PollPeriod: 100 * time.Millisecond,
- FinalityDepth: 2,
- BackfillBatchSize: 3,
- RpcBatchSize: 2,
- KeepFinalizedBlocksDepth: 1000,
- }
- ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth)
- lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, ht, lpOpts)
+ backend.On("SetPipelineRunsQueued", 2).
+ Run(func(args mock.Arguments) {
+ subscribeCalls.Add(1)
+ }).
+ Return()
+ servicetest.Run(t, reporter)
- txm, err := txmgr.NewTxm(
- db,
- evmConfig,
- evmConfig.GasEstimator(),
- evmConfig.Transactions(),
- nil,
- dbConfig,
- dbConfig.Listener(),
- ethClient,
- lggr,
- lp,
- keyStore,
- estimator)
- require.NoError(t, err)
+ head := newHead()
+ reporter.OnNewLongestChain(testutils.Context(t), &head)
- cfg := configtest.NewGeneralConfig(t, nil)
- return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm)
+ require.Eventually(t, func() bool { return subscribeCalls.Load() >= 1 }, 12*time.Second, 100*time.Millisecond)
+ })
}
diff --git a/core/services/registrysyncer/local_registry.go b/core/services/registrysyncer/local_registry.go
new file mode 100644
index 0000000000..4e4a632bf8
--- /dev/null
+++ b/core/services/registrysyncer/local_registry.go
@@ -0,0 +1,85 @@
+package registrysyncer
+
+import (
+ "context"
+ "errors"
+ "fmt"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
+
+ kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
+ p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
+)
+
+type DonID uint32
+
+type DON struct {
+ capabilities.DON
+ CapabilityConfigurations map[string]capabilities.CapabilityConfiguration
+}
+
+type Capability struct {
+ ID string
+ CapabilityType capabilities.CapabilityType
+}
+
+type LocalRegistry struct {
+ lggr logger.Logger
+ peerWrapper p2ptypes.PeerWrapper
+ IDsToDONs map[DonID]DON
+ IDsToNodes map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo
+ IDsToCapabilities map[string]Capability
+}
+
+func (l *LocalRegistry) LocalNode(ctx context.Context) (capabilities.Node, error) {
+ // Load the current nodes PeerWrapper, this gets us the current node's
+ // PeerID, allowing us to contextualize registry information in terms of DON ownership
+ // (eg. get my current DON configuration, etc).
+ if l.peerWrapper.GetPeer() == nil {
+ return capabilities.Node{}, errors.New("unable to get local node: peerWrapper hasn't started yet")
+ }
+
+ pid := l.peerWrapper.GetPeer().ID()
+
+ var workflowDON capabilities.DON
+ capabilityDONs := []capabilities.DON{}
+ for _, d := range l.IDsToDONs {
+ for _, p := range d.Members {
+ if p == pid {
+ if d.AcceptsWorkflows {
+ // The CapabilitiesRegistry enforces that the DON ID is strictly
+ // greater than 0, so if the ID is 0, it means we've not set `workflowDON` initialized above yet.
+ if workflowDON.ID == 0 {
+ workflowDON = d.DON
+ l.lggr.Debug("Workflow DON identified: %+v", workflowDON)
+ } else {
+ l.lggr.Errorf("Configuration error: node %s belongs to more than one workflowDON", pid)
+ }
+ }
+
+ capabilityDONs = append(capabilityDONs, d.DON)
+ }
+ }
+ }
+
+ return capabilities.Node{
+ PeerID: &pid,
+ WorkflowDON: workflowDON,
+ CapabilityDONs: capabilityDONs,
+ }, nil
+}
+
+func (l *LocalRegistry) ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) {
+ d, ok := l.IDsToDONs[DonID(donID)]
+ if !ok {
+ return capabilities.CapabilityConfiguration{}, fmt.Errorf("could not find don %d", donID)
+ }
+
+ cc, ok := d.CapabilityConfigurations[capabilityID]
+ if !ok {
+ return capabilities.CapabilityConfiguration{}, fmt.Errorf("could not find capability configuration for capability %s and donID %d", capabilityID, donID)
+ }
+
+ return cc, nil
+}
diff --git a/core/services/registrysyncer/syncer.go b/core/services/registrysyncer/syncer.go
index f3c254af6d..6a44ff561d 100644
--- a/core/services/registrysyncer/syncer.go
+++ b/core/services/registrysyncer/syncer.go
@@ -7,9 +7,14 @@ import (
"sync"
"time"
+ "google.golang.org/protobuf/proto"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
+ capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"
"github.com/smartcontractkit/chainlink-common/pkg/services"
"github.com/smartcontractkit/chainlink-common/pkg/types"
"github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives"
+ "github.com/smartcontractkit/chainlink-common/pkg/values"
kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
"github.com/smartcontractkit/chainlink/v2/core/logger"
@@ -17,17 +22,8 @@ import (
evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types"
)
-type HashedCapabilityID [32]byte
-type DonID uint32
-
-type State struct {
- IDsToDONs map[DonID]kcr.CapabilitiesRegistryDONInfo
- IDsToNodes map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo
- IDsToCapabilities map[HashedCapabilityID]kcr.CapabilitiesRegistryCapabilityInfo
-}
-
type Launcher interface {
- Launch(ctx context.Context, state State) error
+ Launch(ctx context.Context, registry *LocalRegistry) error
}
type Syncer interface {
@@ -36,12 +32,14 @@ type Syncer interface {
}
type registrySyncer struct {
+ services.StateMachine
stopCh services.StopChan
launchers []Launcher
reader types.ContractReader
initReader func(ctx context.Context, lggr logger.Logger, relayer contractReaderFactory, registryAddress string) (types.ContractReader, error)
relayer contractReaderFactory
registryAddress string
+ peerWrapper p2ptypes.PeerWrapper
wg sync.WaitGroup
lggr logger.Logger
@@ -57,6 +55,7 @@ var (
// New instantiates a new RegistrySyncer
func New(
lggr logger.Logger,
+ peerWrapper p2ptypes.PeerWrapper,
relayer contractReaderFactory,
registryAddress string,
) (*registrySyncer, error) {
@@ -67,6 +66,7 @@ func New(
relayer: relayer,
registryAddress: registryAddress,
initReader: newReader,
+ peerWrapper: peerWrapper,
}, nil
}
@@ -118,12 +118,14 @@ func newReader(ctx context.Context, lggr logger.Logger, relayer contractReaderFa
}
func (s *registrySyncer) Start(ctx context.Context) error {
- s.wg.Add(1)
- go func() {
- defer s.wg.Done()
- s.syncLoop()
- }()
- return nil
+ return s.StartOnce("RegistrySyncer", func() error {
+ s.wg.Add(1)
+ go func() {
+ defer s.wg.Done()
+ s.syncLoop()
+ }()
+ return nil
+ })
}
func (s *registrySyncer) syncLoop() {
@@ -156,33 +158,81 @@ func (s *registrySyncer) syncLoop() {
}
}
-func (s *registrySyncer) state(ctx context.Context) (State, error) {
- dons := []kcr.CapabilitiesRegistryDONInfo{}
- err := s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getDONs", primitives.Unconfirmed, nil, &dons)
+func unmarshalCapabilityConfig(data []byte) (capabilities.CapabilityConfiguration, error) {
+ cconf := &capabilitiespb.CapabilityConfig{}
+ err := proto.Unmarshal(data, cconf)
if err != nil {
- return State{}, err
+ return capabilities.CapabilityConfiguration{}, err
}
- idsToDONs := map[DonID]kcr.CapabilitiesRegistryDONInfo{}
- for _, d := range dons {
- idsToDONs[DonID(d.Id)] = d
+ var rtc capabilities.RemoteTriggerConfig
+ if prtc := cconf.GetRemoteTriggerConfig(); prtc != nil {
+ rtc.RegistrationRefresh = prtc.RegistrationRefresh.AsDuration()
+ rtc.RegistrationExpiry = prtc.RegistrationExpiry.AsDuration()
+ rtc.MinResponsesToAggregate = prtc.MinResponsesToAggregate
+ rtc.MessageExpiry = prtc.MessageExpiry.AsDuration()
}
+ return capabilities.CapabilityConfiguration{
+ DefaultConfig: values.FromMapValueProto(cconf.DefaultConfig),
+ RemoteTriggerConfig: rtc,
+ }, nil
+}
+
+func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, error) {
caps := []kcr.CapabilitiesRegistryCapabilityInfo{}
- err = s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getCapabilities", primitives.Unconfirmed, nil, &caps)
+ err := s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getCapabilities", primitives.Unconfirmed, nil, &caps)
if err != nil {
- return State{}, err
+ return nil, err
}
- idsToCapabilities := map[HashedCapabilityID]kcr.CapabilitiesRegistryCapabilityInfo{}
+ idsToCapabilities := map[string]Capability{}
+ hashedIDsToCapabilityIDs := map[[32]byte]string{}
for _, c := range caps {
- idsToCapabilities[c.HashedId] = c
+ cid := fmt.Sprintf("%s@%s", c.LabelledName, c.Version)
+ idsToCapabilities[cid] = Capability{
+ ID: cid,
+ CapabilityType: toCapabilityType(c.CapabilityType),
+ }
+
+ hashedIDsToCapabilityIDs[c.HashedId] = cid
+ }
+
+ dons := []kcr.CapabilitiesRegistryDONInfo{}
+ err = s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getDONs", primitives.Unconfirmed, nil, &dons)
+ if err != nil {
+ return nil, err
+ }
+
+ idsToDONs := map[DonID]DON{}
+ for _, d := range dons {
+ cc := map[string]capabilities.CapabilityConfiguration{}
+ for _, dc := range d.CapabilityConfigurations {
+ cid, ok := hashedIDsToCapabilityIDs[dc.CapabilityId]
+ if !ok {
+ return nil, fmt.Errorf("invariant violation: could not find full ID for hashed ID %s", dc.CapabilityId)
+ }
+
+ cconf, innerErr := unmarshalCapabilityConfig(dc.Config)
+ if innerErr != nil {
+ return nil, innerErr
+ }
+
+ cconf.RemoteTriggerConfig.ApplyDefaults()
+
+ cc[cid] = cconf
+ }
+
+ idsToDONs[DonID(d.Id)] = DON{
+ DON: *toDONInfo(d),
+ CapabilityConfigurations: cc,
+ }
}
nodes := []kcr.CapabilitiesRegistryNodeInfo{}
err = s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getNodes", primitives.Unconfirmed, nil, &nodes)
if err != nil {
- return State{}, err
+ return nil, err
}
idsToNodes := map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo{}
@@ -190,7 +240,13 @@ func (s *registrySyncer) state(ctx context.Context) (State, error) {
idsToNodes[node.P2pId] = node
}
- return State{IDsToDONs: idsToDONs, IDsToCapabilities: idsToCapabilities, IDsToNodes: idsToNodes}, nil
+ return &LocalRegistry{
+ lggr: s.lggr,
+ peerWrapper: s.peerWrapper,
+ IDsToDONs: idsToDONs,
+ IDsToCapabilities: idsToCapabilities,
+ IDsToNodes: idsToNodes,
+ }, nil
}
func (s *registrySyncer) sync(ctx context.Context) error {
@@ -211,13 +267,13 @@ func (s *registrySyncer) sync(ctx context.Context) error {
s.reader = reader
}
- state, err := s.state(ctx)
+ lr, err := s.localRegistry(ctx)
if err != nil {
return fmt.Errorf("failed to sync with remote registry: %w", err)
}
for _, h := range s.launchers {
- if err := h.Launch(ctx, state); err != nil {
+ if err := h.Launch(ctx, lr); err != nil {
s.lggr.Errorf("error calling launcher: %s", err)
}
}
@@ -225,6 +281,38 @@ func (s *registrySyncer) sync(ctx context.Context) error {
return nil
}
+func toCapabilityType(capabilityType uint8) capabilities.CapabilityType {
+ switch capabilityType {
+ case 0:
+ return capabilities.CapabilityTypeTrigger
+ case 1:
+ return capabilities.CapabilityTypeAction
+ case 2:
+ return capabilities.CapabilityTypeConsensus
+ case 3:
+ return capabilities.CapabilityTypeTarget
+ default:
+ // Not found
+ return capabilities.CapabilityType(-1)
+ }
+}
+
+func toDONInfo(don kcr.CapabilitiesRegistryDONInfo) *capabilities.DON {
+ peerIDs := []p2ptypes.PeerID{}
+ for _, p := range don.NodeP2PIds {
+ peerIDs = append(peerIDs, p)
+ }
+
+ return &capabilities.DON{
+ ID: don.Id,
+ ConfigVersion: don.ConfigCount,
+ Members: peerIDs,
+ F: don.F,
+ IsPublic: don.IsPublic,
+ AcceptsWorkflows: don.AcceptsWorkflows,
+ }
+}
+
func (s *registrySyncer) AddLauncher(launchers ...Launcher) {
s.mu.Lock()
defer s.mu.Unlock()
@@ -232,9 +320,11 @@ func (s *registrySyncer) AddLauncher(launchers ...Launcher) {
}
func (s *registrySyncer) Close() error {
- close(s.stopCh)
- s.wg.Wait()
- return nil
+ return s.StopOnce("RegistrySyncer", func() error {
+ close(s.stopCh)
+ s.wg.Wait()
+ return nil
+ })
}
func (s *registrySyncer) Ready() error {
diff --git a/core/services/registrysyncer/syncer_test.go b/core/services/registrysyncer/syncer_test.go
index c239cead43..b926183394 100644
--- a/core/services/registrysyncer/syncer_test.go
+++ b/core/services/registrysyncer/syncer_test.go
@@ -16,9 +16,15 @@ import (
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/durationpb"
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
"github.com/smartcontractkit/chainlink-common/pkg/types"
+ "github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
+ "github.com/smartcontractkit/chainlink-common/pkg/values"
+ capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
@@ -27,14 +33,15 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
+ "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types/mocks"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types"
)
var writeChainCapability = kcr.CapabilitiesRegistryCapability{
- LabelledName: "write-chain",
- Version: "1.0.1",
- ResponseType: uint8(1),
+ LabelledName: "write-chain",
+ Version: "1.0.1",
+ CapabilityType: uint8(3),
}
func startNewChainWithRegistry(t *testing.T) (*kcr.CapabilitiesRegistry, common.Address, *bind.TransactOpts, *backends.SimulatedBackend) {
@@ -120,14 +127,22 @@ func randomWord() [32]byte {
}
type launcher struct {
- localRegistry State
+ localRegistry *LocalRegistry
}
-func (l *launcher) Launch(ctx context.Context, localRegistry State) error {
+func (l *launcher) Launch(ctx context.Context, localRegistry *LocalRegistry) error {
l.localRegistry = localRegistry
return nil
}
+func toPeerIDs(ids [][32]byte) []p2ptypes.PeerID {
+ pids := []p2ptypes.PeerID{}
+ for _, id := range ids {
+ pids = append(pids, id)
+ }
+ return pids
+}
+
func TestReader_Integration(t *testing.T) {
ctx := testutils.Context(t)
reg, regAddress, owner, sim := startNewChainWithRegistry(t)
@@ -136,7 +151,9 @@ func TestReader_Integration(t *testing.T) {
require.NoError(t, err, "AddCapability failed for %s", writeChainCapability.LabelledName)
sim.Commit()
- cid, err := reg.GetHashedCapabilityId(&bind.CallOpts{}, writeChainCapability.LabelledName, writeChainCapability.Version)
+ cid := fmt.Sprintf("%s@%s", writeChainCapability.LabelledName, writeChainCapability.Version)
+
+ hid, err := reg.GetHashedCapabilityId(&bind.CallOpts{}, writeChainCapability.LabelledName, writeChainCapability.Version)
require.NoError(t, err)
_, err = reg.AddNodeOperators(owner, []kcr.CapabilitiesRegistryNodeOperator{
@@ -165,30 +182,46 @@ func TestReader_Integration(t *testing.T) {
NodeOperatorId: uint32(1),
Signer: signersSet[0],
P2pId: nodeSet[0],
- HashedCapabilityIds: [][32]byte{cid},
+ HashedCapabilityIds: [][32]byte{hid},
},
{
// The first NodeOperatorId has id 1 since the id is auto-incrementing.
NodeOperatorId: uint32(1),
Signer: signersSet[1],
P2pId: nodeSet[1],
- HashedCapabilityIds: [][32]byte{cid},
+ HashedCapabilityIds: [][32]byte{hid},
},
{
// The first NodeOperatorId has id 1 since the id is auto-incrementing.
NodeOperatorId: uint32(1),
Signer: signersSet[2],
P2pId: nodeSet[2],
- HashedCapabilityIds: [][32]byte{cid},
+ HashedCapabilityIds: [][32]byte{hid},
},
}
_, err = reg.AddNodes(owner, nodes)
require.NoError(t, err)
+ config := &capabilitiespb.CapabilityConfig{
+ DefaultConfig: values.Proto(values.EmptyMap()).GetMapValue(),
+ RemoteConfig: &capabilitiespb.CapabilityConfig_RemoteTriggerConfig{
+ RemoteTriggerConfig: &capabilitiespb.RemoteTriggerConfig{
+ RegistrationRefresh: durationpb.New(20 * time.Second),
+ RegistrationExpiry: durationpb.New(60 * time.Second),
+ // F + 1
+ MinResponsesToAggregate: uint32(1) + 1,
+ },
+ },
+ }
+ configb, err := proto.Marshal(config)
+ if err != nil {
+ panic(err)
+ }
+
cfgs := []kcr.CapabilitiesRegistryCapabilityConfiguration{
{
- CapabilityId: cid,
- Config: []byte(`{"hello": "world"}`),
+ CapabilityId: hid,
+ Config: configb,
},
}
_, err = reg.AddDON(
@@ -203,8 +236,9 @@ func TestReader_Integration(t *testing.T) {
require.NoError(t, err)
+ wrapper := mocks.NewPeerWrapper(t)
factory := newContractReaderFactory(t, sim)
- syncer, err := New(logger.TestLogger(t), factory, regAddress.Hex())
+ syncer, err := New(logger.TestLogger(t), wrapper, factory, regAddress.Hex())
require.NoError(t, err)
l := &launcher{}
@@ -216,25 +250,35 @@ func TestReader_Integration(t *testing.T) {
assert.Len(t, s.IDsToCapabilities, 1)
gotCap := s.IDsToCapabilities[cid]
- assert.Equal(t, kcr.CapabilitiesRegistryCapabilityInfo{
- HashedId: cid,
- LabelledName: "write-chain",
- Version: "1.0.1",
- ResponseType: uint8(1),
- CapabilityType: uint8(0),
- IsDeprecated: false,
+ assert.Equal(t, Capability{
+ CapabilityType: capabilities.CapabilityTypeTarget,
+ ID: "write-chain@1.0.1",
}, gotCap)
assert.Len(t, s.IDsToDONs, 1)
- assert.Equal(t, kcr.CapabilitiesRegistryDONInfo{
- Id: 1, // initial Id
- ConfigCount: 1, // initial Count
- IsPublic: true,
- AcceptsWorkflows: true,
- F: 1,
- NodeP2PIds: nodeSet,
- CapabilityConfigurations: cfgs,
- }, s.IDsToDONs[1])
+ rtc := capabilities.RemoteTriggerConfig{
+ RegistrationRefresh: 20 * time.Second,
+ MinResponsesToAggregate: 2,
+ RegistrationExpiry: 60 * time.Second,
+ MessageExpiry: 120 * time.Second,
+ }
+ expectedDON := DON{
+ DON: capabilities.DON{
+ ID: 1,
+ ConfigVersion: 1,
+ IsPublic: true,
+ AcceptsWorkflows: true,
+ F: 1,
+ Members: toPeerIDs(nodeSet),
+ },
+ CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{
+ cid: {
+ DefaultConfig: values.EmptyMap(),
+ RemoteTriggerConfig: rtc,
+ },
+ },
+ }
+ assert.Equal(t, expectedDON, s.IDsToDONs[1])
nodesInfo := []kcr.CapabilitiesRegistryNodeInfo{
{
@@ -244,7 +288,7 @@ func TestReader_Integration(t *testing.T) {
WorkflowDONId: 1,
Signer: signersSet[0],
P2pId: nodeSet[0],
- HashedCapabilityIds: [][32]byte{cid},
+ HashedCapabilityIds: [][32]byte{hid},
CapabilitiesDONIds: []*big.Int{},
},
{
@@ -254,7 +298,7 @@ func TestReader_Integration(t *testing.T) {
WorkflowDONId: 1,
Signer: signersSet[1],
P2pId: nodeSet[1],
- HashedCapabilityIds: [][32]byte{cid},
+ HashedCapabilityIds: [][32]byte{hid},
CapabilitiesDONIds: []*big.Int{},
},
{
@@ -264,7 +308,7 @@ func TestReader_Integration(t *testing.T) {
WorkflowDONId: 1,
Signer: signersSet[2],
P2pId: nodeSet[2],
- HashedCapabilityIds: [][32]byte{cid},
+ HashedCapabilityIds: [][32]byte{hid},
CapabilitiesDONIds: []*big.Int{},
},
}
@@ -276,3 +320,84 @@ func TestReader_Integration(t *testing.T) {
nodeSet[2]: nodesInfo[2],
}, s.IDsToNodes)
}
+
+func TestSyncer_LocalNode(t *testing.T) {
+ ctx := tests.Context(t)
+ lggr := logger.TestLogger(t)
+
+ var pid p2ptypes.PeerID
+ err := pid.UnmarshalText([]byte("12D3KooWBCF1XT5Wi8FzfgNCqRL76Swv8TRU3TiD4QiJm8NMNX7N"))
+ require.NoError(t, err)
+ peer := mocks.NewPeer(t)
+ peer.On("ID").Return(pid)
+ wrapper := mocks.NewPeerWrapper(t)
+ wrapper.On("GetPeer").Return(peer)
+
+ workflowDonNodes := []p2ptypes.PeerID{
+ pid,
+ randomWord(),
+ randomWord(),
+ randomWord(),
+ }
+
+ dID := uint32(1)
+ // The below state describes a Workflow DON (AcceptsWorkflows = true),
+ // which exposes the streams-trigger and write_chain capabilities.
+ // We expect receivers to be wired up and both capabilities to be added to the registry.
+ localRegistry := LocalRegistry{
+ lggr: lggr,
+ peerWrapper: wrapper,
+ IDsToDONs: map[DonID]DON{
+ DonID(dID): {
+ DON: capabilities.DON{
+ ID: dID,
+ ConfigVersion: uint32(2),
+ F: uint8(1),
+ IsPublic: true,
+ AcceptsWorkflows: true,
+ Members: workflowDonNodes,
+ },
+ },
+ },
+ IDsToNodes: map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo{
+ workflowDonNodes[0]: {
+ NodeOperatorId: 1,
+ Signer: randomWord(),
+ P2pId: workflowDonNodes[0],
+ },
+ workflowDonNodes[1]: {
+ NodeOperatorId: 1,
+ Signer: randomWord(),
+ P2pId: workflowDonNodes[1],
+ },
+ workflowDonNodes[2]: {
+ NodeOperatorId: 1,
+ Signer: randomWord(),
+ P2pId: workflowDonNodes[2],
+ },
+ workflowDonNodes[3]: {
+ NodeOperatorId: 1,
+ Signer: randomWord(),
+ P2pId: workflowDonNodes[3],
+ },
+ },
+ }
+
+ node, err := localRegistry.LocalNode(ctx)
+ require.NoError(t, err)
+
+ don := capabilities.DON{
+ ID: dID,
+ ConfigVersion: 2,
+ Members: workflowDonNodes,
+ F: 1,
+ IsPublic: true,
+ AcceptsWorkflows: true,
+ }
+ expectedNode := capabilities.Node{
+ PeerID: &pid,
+ WorkflowDON: don,
+ CapabilityDONs: []capabilities.DON{don},
+ }
+ assert.Equal(t, expectedNode, node)
+}
diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go
index b937e0b580..acd006940f 100644
--- a/core/services/workflows/delegate.go
+++ b/core/services/workflows/delegate.go
@@ -7,7 +7,6 @@ import (
"github.com/google/uuid"
"github.com/pelletier/go-toml"
- "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
"github.com/smartcontractkit/chainlink-common/pkg/types/core"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
@@ -15,10 +14,9 @@ import (
)
type Delegate struct {
- registry core.CapabilitiesRegistry
- logger logger.Logger
- getLocalNode func(ctx context.Context) (capabilities.Node, error)
- store store.Store
+ registry core.CapabilitiesRegistry
+ logger logger.Logger
+ store store.Store
}
var _ job.Delegate = (*Delegate)(nil)
@@ -44,7 +42,6 @@ func (d *Delegate) ServicesForSpec(_ context.Context, spec job.Job) ([]job.Servi
WorkflowOwner: spec.WorkflowSpec.WorkflowOwner,
WorkflowName: spec.WorkflowSpec.WorkflowName,
Registry: d.registry,
- GetLocalNode: d.getLocalNode,
Store: d.store,
}
engine, err := NewEngine(cfg)
@@ -58,9 +55,8 @@ func NewDelegate(
logger logger.Logger,
registry core.CapabilitiesRegistry,
store store.Store,
- getLocalNode func(ctx context.Context) (capabilities.Node, error),
) *Delegate {
- return &Delegate{logger: logger, registry: registry, store: store, getLocalNode: getLocalNode}
+ return &Delegate{logger: logger, registry: registry, store: store}
}
func ValidatedWorkflowJobSpec(tomlString string) (job.Job, error) {
diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go
index f83d40b176..ed5daaf210 100644
--- a/core/services/workflows/engine.go
+++ b/core/services/workflows/engine.go
@@ -33,7 +33,6 @@ type Engine struct {
logger logger.Logger
registry core.CapabilitiesRegistry
workflow *workflow
- getLocalNode func(ctx context.Context) (capabilities.Node, error)
localNode capabilities.Node
executionStates store.Store
pendingStepRequests chan stepRequest
@@ -164,9 +163,11 @@ func (e *Engine) initializeCapability(ctx context.Context, step *step) error {
return newCPErr("failed to get capability info", err)
}
+ step.info = info
+
// Special treatment for local targets - wrap into a transmission capability
// If the DON is nil, this is a local target.
- if info.CapabilityType == capabilities.CapabilityTypeTarget && info.DON == nil {
+ if info.CapabilityType == capabilities.CapabilityTypeTarget && info.IsLocal {
l := e.logger.With("capabilityID", step.ID)
l.Debug("wrapping capability in local transmission protocol")
cp = transmission.NewLocalTargetCapability(
@@ -222,7 +223,7 @@ func (e *Engine) init(ctx context.Context) {
retryErr := retryable(ctx, e.logger, e.retryMs, e.maxRetries, func() error {
// first wait for localDON to return a non-error response; this depends
// on the underlying peerWrapper returning the PeerID.
- node, err := e.getLocalNode(ctx)
+ node, err := e.registry.LocalNode(ctx)
if err != nil {
return fmt.Errorf("failed to get donInfo: %w", err)
}
@@ -680,6 +681,45 @@ func (e *Engine) workerForStepRequest(ctx context.Context, msg stepRequest) {
}
}
+func merge(baseConfig *values.Map, overrideConfig *values.Map) *values.Map {
+ m := values.EmptyMap()
+
+ for k, v := range baseConfig.Underlying {
+ m.Underlying[k] = v
+ }
+
+ for k, v := range overrideConfig.Underlying {
+ m.Underlying[k] = v
+ }
+
+ return m
+}
+
+func (e *Engine) configForStep(ctx context.Context, executionID string, step *step) (*values.Map, error) {
+ ID := step.info.ID
+
+ // If the capability info is missing a DON, then
+ // the capability is local, and we should use the localNode's DON ID.
+ var donID uint32
+ if !step.info.IsLocal {
+ donID = step.info.DON.ID
+ } else {
+ donID = e.localNode.WorkflowDON.ID
+ }
+
+ capConfig, err := e.registry.ConfigForCapability(ctx, ID, donID)
+ if err != nil {
+ e.logger.Warnw(fmt.Sprintf("could not retrieve config from remote registry: %s", err), "executionID", executionID, "capabilityID", ID)
+ return step.config, nil
+ }
+
+ // Merge the configs for now; note that this means that a workflow can override
+ // all of the config set by the capability. This is probably not desirable in
+ // the long-term, but we don't know much about those use cases so stick to a simpler
+ // implementation for now.
+ return merge(capConfig.DefaultConfig, step.config), nil
+}
+
// executeStep executes the referenced capability within a step and returns the result.
func (e *Engine) executeStep(ctx context.Context, msg stepRequest) (*values.Map, values.Value, error) {
step, err := e.workflow.Vertex(msg.stepRef)
@@ -704,9 +744,14 @@ func (e *Engine) executeStep(ctx context.Context, msg stepRequest) (*values.Map,
return nil, nil, err
}
+ config, err := e.configForStep(ctx, msg.state.ExecutionID, step)
+ if err != nil {
+ return nil, nil, err
+ }
+
tr := capabilities.CapabilityRequest{
Inputs: inputsMap,
- Config: step.config,
+ Config: config,
Metadata: capabilities.RequestMetadata{
WorkflowID: msg.state.WorkflowID,
WorkflowExecutionID: msg.state.ExecutionID,
@@ -825,7 +870,6 @@ type Config struct {
QueueSize int
NewWorkerTimeout time.Duration
MaxExecutionDuration time.Duration
- GetLocalNode func(ctx context.Context) (capabilities.Node, error)
Store store.Store
// For testing purposes only
@@ -868,12 +912,6 @@ func NewEngine(cfg Config) (engine *Engine, err error) {
cfg.MaxExecutionDuration = defaultMaxExecutionDuration
}
- if cfg.GetLocalNode == nil {
- cfg.GetLocalNode = func(ctx context.Context) (capabilities.Node, error) {
- return capabilities.Node{}, nil
- }
- }
-
if cfg.retryMs == 0 {
cfg.retryMs = 5000
}
@@ -911,7 +949,6 @@ func NewEngine(cfg Config) (engine *Engine, err error) {
logger: cfg.Lggr.Named("WorkflowEngine").With("workflowID", cfg.WorkflowID),
registry: cfg.Registry,
workflow: workflow,
- getLocalNode: cfg.GetLocalNode,
executionStates: cfg.Store,
pendingStepRequests: make(chan stepRequest, cfg.QueueSize),
stepUpdateCh: make(chan store.WorkflowExecutionStep),
diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go
index 2c4129dbaf..b8d5a9591e 100644
--- a/core/services/workflows/engine_test.go
+++ b/core/services/workflows/engine_test.go
@@ -99,26 +99,46 @@ func newTestDBStore(t *testing.T, clock clockwork.Clock) store.Store {
return store.NewDBStore(db, logger.TestLogger(t), clock)
}
+type testConfigProvider struct {
+ localNode func(ctx context.Context) (capabilities.Node, error)
+ configForCapability func(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error)
+}
+
+func (t testConfigProvider) LocalNode(ctx context.Context) (capabilities.Node, error) {
+ if t.localNode != nil {
+ return t.localNode(ctx)
+ }
+
+ peerID := p2ptypes.PeerID{}
+ return capabilities.Node{
+ WorkflowDON: capabilities.DON{
+ ID: 1,
+ },
+ PeerID: &peerID,
+ }, nil
+}
+
+func (t testConfigProvider) ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) {
+ if t.configForCapability != nil {
+ return t.configForCapability(ctx, capabilityID, donID)
+ }
+
+ return capabilities.CapabilityConfiguration{DefaultConfig: values.EmptyMap()}, nil
+}
+
// newTestEngine creates a new engine with some test defaults.
func newTestEngine(t *testing.T, reg *coreCap.Registry, spec string, opts ...func(c *Config)) (*Engine, *testHooks) {
- peerID := p2ptypes.PeerID{}
initFailed := make(chan struct{})
initSuccessful := make(chan struct{})
executionFinished := make(chan string, 100)
clock := clockwork.NewFakeClock()
+
+ reg.SetLocalRegistry(&testConfigProvider{})
cfg := Config{
WorkflowID: testWorkflowId,
Lggr: logger.TestLogger(t),
Registry: reg,
Spec: spec,
- GetLocalNode: func(ctx context.Context) (capabilities.Node, error) {
- return capabilities.Node{
- WorkflowDON: capabilities.DON{
- ID: 1,
- },
- PeerID: &peerID,
- }, nil
- },
maxRetries: 1,
retryMs: 100,
afterInit: func(success bool) {
@@ -787,6 +807,19 @@ func TestEngine_GetsNodeInfoDuringInitialization(t *testing.T) {
},
}
retryCount := 0
+
+ reg.SetLocalRegistry(testConfigProvider{
+ localNode: func(ctx context.Context) (capabilities.Node, error) {
+ n := capabilities.Node{}
+ err := errors.New("peer not initialized")
+ if retryCount > 0 {
+ n = node
+ err = nil
+ }
+ retryCount++
+ return n, err
+ },
+ })
eng, hooks := newTestEngine(
t,
reg,
@@ -796,16 +829,6 @@ func TestEngine_GetsNodeInfoDuringInitialization(t *testing.T) {
c.clock = clock
c.maxRetries = 2
c.retryMs = 0
- c.GetLocalNode = func(ctx context.Context) (capabilities.Node, error) {
- n := capabilities.Node{}
- err := errors.New("peer not initialized")
- if retryCount > 0 {
- n = node
- err = nil
- }
- retryCount++
- return n, err
- }
},
)
servicetest.Run(t, eng)
@@ -969,3 +992,74 @@ func TestEngine_Error(t *testing.T) {
})
}
}
+
+func TestEngine_MergesWorkflowConfigAndCRConfig(t *testing.T) {
+ ctx := testutils.Context(t)
+ reg := coreCap.NewRegistry(logger.TestLogger(t))
+
+ trigger, _ := mockTrigger(t)
+
+ require.NoError(t, reg.Add(ctx, trigger))
+ require.NoError(t, reg.Add(ctx, mockConsensus()))
+ writeID := "write_polygon-testnet-mumbai@1.0.0"
+
+ gotConfig := values.EmptyMap()
+ target := newMockCapability(
+ // Create a remote capability so we don't use the local transmission protocol.
+ capabilities.MustNewRemoteCapabilityInfo(
+ writeID,
+ capabilities.CapabilityTypeTarget,
+ "a write capability targeting polygon testnet",
+ &capabilities.DON{ID: 1},
+ ),
+ func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) {
+ gotConfig = req.Config
+
+ return capabilities.CapabilityResponse{
+ Value: req.Inputs,
+ }, nil
+ },
+ )
+ require.NoError(t, reg.Add(ctx, target))
+
+ eng, testHooks := newTestEngine(
+ t,
+ reg,
+ simpleWorkflow,
+ )
+ reg.SetLocalRegistry(testConfigProvider{
+ configForCapability: func(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) {
+ if capabilityID != writeID {
+ return capabilities.CapabilityConfiguration{
+ DefaultConfig: values.EmptyMap(),
+ }, nil
+ }
+
+ cm, err := values.WrapMap(map[string]any{
+ "deltaStage": "1s",
+ "schedule": "allAtOnce",
+ })
+ if err != nil {
+ return capabilities.CapabilityConfiguration{}, err
+ }
+
+ return capabilities.CapabilityConfiguration{
+ DefaultConfig: cm,
+ }, nil
+ },
+ })
+
+ servicetest.Run(t, eng)
+
+ eid := getExecutionId(t, eng, testHooks)
+
+ state, err := eng.executionStates.Get(ctx, eid)
+ require.NoError(t, err)
+
+ assert.Equal(t, state.Status, store.StatusCompleted)
+
+ m, err := values.Unwrap(gotConfig)
+ require.NoError(t, err)
+ assert.Equal(t, m.(map[string]any)["deltaStage"], "1s")
+ assert.Equal(t, m.(map[string]any)["schedule"], "allAtOnce")
+}
diff --git a/core/services/workflows/models.go b/core/services/workflows/models.go
index d55212a30c..8d970dfa94 100644
--- a/core/services/workflows/models.go
+++ b/core/services/workflows/models.go
@@ -79,6 +79,7 @@ func (w *workflow) dependents(start string) ([]*step, error) {
type step struct {
workflows.Vertex
capability capabilities.CallbackCapability
+ info capabilities.CapabilityInfo
config *values.Map
}
diff --git a/core/web/testdata/body/health.html b/core/web/testdata/body/health.html
index 4e244a9fe7..2a1b222753 100644
--- a/core/web/testdata/body/health.html
+++ b/core/web/testdata/body/health.html
@@ -69,9 +69,6 @@
-
- HeadReporter
-
JobSpawner
@@ -99,6 +96,9 @@
BridgeCache
+
+ PromReporter
+
TelemetryManager
diff --git a/core/web/testdata/body/health.json b/core/web/testdata/body/health.json
index 224a3534c9..10415c0abd 100644
--- a/core/web/testdata/body/health.json
+++ b/core/web/testdata/body/health.json
@@ -99,15 +99,6 @@
"output": ""
}
},
- {
- "type": "checks",
- "id": "HeadReporter",
- "attributes": {
- "name": "HeadReporter",
- "status": "passing",
- "output": ""
- }
- },
{
"type": "checks",
"id": "JobSpawner",
@@ -171,6 +162,15 @@
"output": ""
}
},
+ {
+ "type": "checks",
+ "id": "PromReporter",
+ "attributes": {
+ "name": "PromReporter",
+ "status": "passing",
+ "output": ""
+ }
+ },
{
"type": "checks",
"id": "TelemetryManager",
diff --git a/core/web/testdata/body/health.txt b/core/web/testdata/body/health.txt
index 0fbac846a6..09c8cff6c2 100644
--- a/core/web/testdata/body/health.txt
+++ b/core/web/testdata/body/health.txt
@@ -10,7 +10,6 @@ ok EVM.0.Txm.BlockHistoryEstimator
ok EVM.0.Txm.Broadcaster
ok EVM.0.Txm.Confirmer
ok EVM.0.Txm.WrappedEvmEstimator
-ok HeadReporter
ok JobSpawner
ok Mailbox.Monitor
ok Mercury.WSRPCPool
@@ -18,4 +17,5 @@ ok Mercury.WSRPCPool.CacheSet
ok PipelineORM
ok PipelineRunner
ok PipelineRunner.BridgeCache
+ok PromReporter
ok TelemetryManager
diff --git a/go.mod b/go.mod
index ee87e23f30..fdebb10181 100644
--- a/go.mod
+++ b/go.mod
@@ -74,7 +74,7 @@ require (
github.com/shopspring/decimal v1.4.0
github.com/smartcontractkit/chain-selectors v1.0.23
github.com/smartcontractkit/chainlink-automation v1.0.4
- github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834
+ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45
github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa
github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827
@@ -129,6 +129,11 @@ require (
)
require (
+ cloud.google.com/go/auth v0.7.1 // indirect
+ cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect
+ cloud.google.com/go/compute/metadata v0.5.0 // indirect
+ cloud.google.com/go/iam v1.1.11 // indirect
+ cloud.google.com/go/storage v1.43.0 // indirect
contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect
cosmossdk.io/api v0.3.1 // indirect
cosmossdk.io/core v0.5.1 // indirect
@@ -323,17 +328,21 @@ require (
go.etcd.io/bbolt v1.3.7 // indirect
go.mongodb.org/mongo-driver v1.15.0 // indirect
go.opencensus.io v0.24.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
+ go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/ratelimit v0.3.0 // indirect
- golang.org/x/arch v0.7.0 // indirect
+ golang.org/x/arch v0.8.0 // indirect
+ golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sys v0.22.0 // indirect
- google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
+ google.golang.org/api v0.188.0 // indirect
+ google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect
gopkg.in/guregu/null.v2 v2.1.2 // indirect
diff --git a/go.sum b/go.sum
index ac442571a9..d65d3fa705 100644
--- a/go.sum
+++ b/go.sum
@@ -10,27 +10,30 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
-cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
-cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
+cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14=
+cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
+cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s=
+cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs=
+cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI=
+cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
-cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg=
-cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
-cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
+cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
+cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
-cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc=
-cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=
+cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw=
+cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
-cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg=
-cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY=
+cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs=
+cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0=
contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo=
@@ -533,8 +536,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
-github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
+github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA=
+github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
@@ -1027,8 +1030,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj
github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8=
github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM=
-github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI=
-github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo=
+github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 h1:pdEpjgbZ5w/Sd5lzg/XiuC5gVyrmSovOo+3nUD46SP8=
+github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs=
github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk=
@@ -1215,10 +1218,10 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg=
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03y3dZcGhC/FepKtEUY=
go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
@@ -1231,8 +1234,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
-go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
-go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q=
+go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08=
+go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg=
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
@@ -1267,8 +1270,8 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
-golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
-golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
+golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -1379,8 +1382,8 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
-golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
+golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1564,8 +1567,8 @@ google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
-google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY=
-google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg=
+google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw=
+google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1597,8 +1600,8 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
-google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
+google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc=
+google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY=
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A=
diff --git a/integration-tests/actions/automationv2/actions.go b/integration-tests/actions/automationv2/actions.go
index f7d495bda5..40caf15917 100644
--- a/integration-tests/actions/automationv2/actions.go
+++ b/integration-tests/actions/automationv2/actions.go
@@ -88,8 +88,7 @@ type AutomationTest struct {
mercuryCredentialName string
TransmitterKeyIndex int
- Logger zerolog.Logger
- useLogBufferV1 bool
+ Logger zerolog.Logger
}
type UpkeepConfig struct {
@@ -117,7 +116,6 @@ func NewAutomationTestK8s(
TransmitterKeyIndex: 0,
UpkeepPrivilegeManager: chainClient.MustGetRootKeyAddress(),
mercuryCredentialName: "",
- useLogBufferV1: false,
Logger: l,
}
}
@@ -134,7 +132,6 @@ func NewAutomationTestDocker(
TransmitterKeyIndex: 0,
UpkeepPrivilegeManager: chainClient.MustGetRootKeyAddress(),
mercuryCredentialName: "",
- useLogBufferV1: false,
Logger: l,
}
}
@@ -147,10 +144,6 @@ func (a *AutomationTest) SetMercuryCredentialName(name string) {
a.mercuryCredentialName = name
}
-func (a *AutomationTest) SetUseLogBufferV1(flag bool) {
- a.useLogBufferV1 = flag
-}
-
func (a *AutomationTest) SetTransmitterKeyIndex(index int) {
a.TransmitterKeyIndex = index
}
@@ -422,9 +415,6 @@ func (a *AutomationTest) AddAutomationJobs() error {
if a.mercuryCredentialName != "" {
pluginCfg["mercuryCredentialName"] = "\"" + a.mercuryCredentialName + "\""
}
- if a.useLogBufferV1 {
- pluginCfg["useBufferV1"] = "true"
- }
}
for i := 1; i < len(a.ChainlinkNodes); i++ {
autoOCR2JobSpec := client.OCR2TaskJobSpec{
diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go
index 79513b2e8f..467f371ad1 100644
--- a/integration-tests/chaos/automation_chaos_test.go
+++ b/integration-tests/chaos/automation_chaos_test.go
@@ -6,6 +6,11 @@ import (
"testing"
"time"
+ ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper"
+
+ ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config"
+ "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2"
+
seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth"
"github.com/onsi/gomega"
@@ -77,22 +82,6 @@ ListenAddresses = ["0.0.0.0:6690"]`
},
},
}
-
- defaultOCRRegistryConfig = contracts.KeeperRegistrySettings{
- PaymentPremiumPPB: uint32(200000000),
- FlatFeeMicroLINK: uint32(0),
- BlockCountPerTurn: big.NewInt(10),
- CheckGasLimit: uint32(2500000),
- StalenessSeconds: big.NewInt(90000),
- GasCeilingMultiplier: uint16(1),
- MinUpkeepSpend: big.NewInt(0),
- MaxPerformGas: uint32(5000000),
- FallbackGasPrice: big.NewInt(2e11),
- FallbackLinkPrice: big.NewInt(2e18),
- MaxCheckDataSize: uint32(5000),
- MaxPerformDataSize: uint32(5000),
- MaxRevertDataSize: uint32(5000),
- }
)
func getDefaultAutomationSettings(config *tc.TestConfig) map[string]interface{} {
@@ -127,6 +116,7 @@ func TestAutomationChaos(t *testing.T) {
"registry_2_0": eth_contracts.RegistryVersion_2_0,
"registry_2_1": eth_contracts.RegistryVersion_2_1,
"registry_2_2": eth_contracts.RegistryVersion_2_2,
+ "registry_2_3": eth_contracts.RegistryVersion_2_3,
}
for name, registryVersion := range registryVersions {
@@ -253,57 +243,76 @@ func TestAutomationChaos(t *testing.T) {
require.NoError(t, err, "Error tearing down environment")
})
- txCost, err := actions.EstimateCostForChainlinkOperations(l, chainClient, network, 1000)
- require.NoError(t, err, "Error estimating cost for Chainlink Operations")
- err = actions.FundChainlinkNodesFromRootAddress(l, chainClient, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(chainlinkNodes), txCost)
- require.NoError(t, err, "Error funding Chainlink nodes")
-
- linkToken, err := contracts.DeployLinkTokenContract(l, chainClient)
- require.NoError(t, err, "Error deploying LINK token")
-
- wethToken, err := contracts.DeployWETHTokenContract(l, chainClient)
- require.NoError(t, err, "Error deploying weth token contract")
-
- // This feed is used for both eth/usd and link/usd
- ethUSDFeed, err := contracts.DeployMockETHUSDFeed(chainClient, defaultOCRRegistryConfig.FallbackLinkPrice)
- require.NoError(t, err, "Error deploying eth usd feed contract")
-
- registry, registrar := actions.DeployAutoOCRRegistryAndRegistrar(
- t,
- chainClient,
- rv,
- defaultOCRRegistryConfig,
- linkToken,
- wethToken,
- ethUSDFeed,
- )
-
- // Fund the registry with LINK
- err = linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(numberOfUpkeeps))))
- require.NoError(t, err, "Funding keeper registry contract shouldn't fail")
-
- actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, rv)
- nodesWithoutBootstrap := chainlinkNodes[1:]
- defaultOCRRegistryConfig.RegistryVersion = rv
- ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 30*time.Second, registry.ChainModuleAddress(), registry.ReorgProtectionEnabled(), linkToken, wethToken, ethUSDFeed)
- require.NoError(t, err, "Error building OCR config vars")
-
- if rv == eth_contracts.RegistryVersion_2_0 {
- err = registry.SetConfig(defaultOCRRegistryConfig, ocrConfig)
- } else {
- err = registry.SetConfigTypeSafe(ocrConfig)
+ a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes)
+ a.SetMercuryCredentialName("cred1")
+ conf := config.Automation.AutomationConfig
+ a.RegistrySettings = contracts.KeeperRegistrySettings{
+ PaymentPremiumPPB: *conf.RegistrySettings.PaymentPremiumPPB,
+ FlatFeeMicroLINK: *conf.RegistrySettings.FlatFeeMicroLINK,
+ CheckGasLimit: *conf.RegistrySettings.CheckGasLimit,
+ StalenessSeconds: conf.RegistrySettings.StalenessSeconds,
+ GasCeilingMultiplier: *conf.RegistrySettings.GasCeilingMultiplier,
+ MaxPerformGas: *conf.RegistrySettings.MaxPerformGas,
+ MinUpkeepSpend: conf.RegistrySettings.MinUpkeepSpend,
+ FallbackGasPrice: conf.RegistrySettings.FallbackGasPrice,
+ FallbackLinkPrice: conf.RegistrySettings.FallbackLinkPrice,
+ MaxCheckDataSize: *conf.RegistrySettings.MaxCheckDataSize,
+ MaxPerformDataSize: *conf.RegistrySettings.MaxPerformDataSize,
+ MaxRevertDataSize: *conf.RegistrySettings.MaxRevertDataSize,
+ RegistryVersion: rv,
+ }
+ a.RegistrarSettings = contracts.KeeperRegistrarSettings{
+ AutoApproveConfigType: uint8(2),
+ AutoApproveMaxAllowed: 1000,
+ MinLinkJuels: big.NewInt(0),
+ }
+ plCfg := config.GetAutomationConfig().AutomationConfig.PluginConfig
+ a.PluginConfig = ocr2keepers30config.OffchainConfig{
+ TargetProbability: *plCfg.TargetProbability,
+ TargetInRounds: *plCfg.TargetInRounds,
+ PerformLockoutWindow: *plCfg.PerformLockoutWindow,
+ GasLimitPerReport: *plCfg.GasLimitPerReport,
+ GasOverheadPerUpkeep: *plCfg.GasOverheadPerUpkeep,
+ MinConfirmations: *plCfg.MinConfirmations,
+ MaxUpkeepBatchSize: *plCfg.MaxUpkeepBatchSize,
+ }
+ pubCfg := config.GetAutomationConfig().AutomationConfig.PublicConfig
+ a.PublicConfig = ocr3.PublicConfig{
+ DeltaProgress: *pubCfg.DeltaProgress,
+ DeltaResend: *pubCfg.DeltaResend,
+ DeltaInitial: *pubCfg.DeltaInitial,
+ DeltaRound: *pubCfg.DeltaRound,
+ DeltaGrace: *pubCfg.DeltaGrace,
+ DeltaCertifiedCommitRequest: *pubCfg.DeltaCertifiedCommitRequest,
+ DeltaStage: *pubCfg.DeltaStage,
+ RMax: *pubCfg.RMax,
+ MaxDurationQuery: *pubCfg.MaxDurationQuery,
+ MaxDurationObservation: *pubCfg.MaxDurationObservation,
+ MaxDurationShouldAcceptAttestedReport: *pubCfg.MaxDurationShouldAcceptAttestedReport,
+ MaxDurationShouldTransmitAcceptedReport: *pubCfg.MaxDurationShouldTransmitAcceptedReport,
+ F: *pubCfg.F,
}
- require.NoError(t, err, "Error setting OCR config")
- consumersConditional, upkeepidsConditional := actions.DeployConsumers(t, chainClient, registry, registrar, linkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false, false, false, nil)
- consumersLogtrigger, upkeepidsLogtrigger := actions.DeployConsumers(t, chainClient, registry, registrar, linkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, true, false, false, nil)
+ a.SetupAutomationDeployment(t)
- consumers := append(consumersConditional, consumersLogtrigger...)
- upkeepIDs := append(upkeepidsConditional, upkeepidsLogtrigger...)
+ err = actions.FundChainlinkNodesFromRootAddress(l, a.ChainClient, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(chainlinkNodes[1:]), big.NewFloat(*config.Common.ChainlinkNodeFunding))
+ require.NoError(t, err, "Error funding Chainlink nodes")
+
+ var consumersLogTrigger, consumersConditional []contracts.KeeperConsumer
+ var upkeepidsConditional, upkeepidsLogTrigger []*big.Int
+ consumersConditional, upkeepidsConditional = actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false, false, false, nil)
+ consumers := consumersConditional
+ upkeepIDs := upkeepidsConditional
+ if rv >= eth_contracts.RegistryVersion_2_1 {
+ consumersLogTrigger, upkeepidsLogTrigger = actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, true, false, false, nil)
- for _, c := range consumersLogtrigger {
- err = c.Start()
- require.NoError(t, err, "Error starting consumer")
+ consumers = append(consumersConditional, consumersLogTrigger...)
+ upkeepIDs = append(upkeepidsConditional, upkeepidsLogTrigger...)
+
+ for _, c := range consumersLogTrigger {
+ err = c.Start()
+ require.NoError(t, err, "Error starting consumer")
+ }
}
l.Info().Msg("Waiting for all upkeeps to be performed")
@@ -324,6 +333,13 @@ func TestAutomationChaos(t *testing.T) {
_, err = testEnvironment.Chaos.Run(testCase.chaosFunc(testEnvironment.Cfg.Namespace, testCase.chaosProps))
require.NoError(t, err)
+ if rv >= eth_contracts.RegistryVersion_2_1 {
+ for _, c := range consumersLogTrigger {
+ err = c.Start()
+ require.NoError(t, err, "Error starting consumer")
+ }
+ }
+
gom.Eventually(func(g gomega.Gomega) {
// Check if the upkeeps are performing multiple times by analyzing their counters and checking they are greater than 10
for i := 0; i < len(upkeepIDs); i++ {
@@ -334,7 +350,7 @@ func TestAutomationChaos(t *testing.T) {
g.Expect(counter.Int64()).Should(gomega.BeNumerically(">=", int64(expect)),
"Expected consumer counter to be greater than %d, but got %d", expect, counter.Int64())
}
- }, "3m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer
+ }, "5m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer
})
}
diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go
index 36704baeda..334334036f 100644
--- a/integration-tests/docker/test_env/test_env_builder.go
+++ b/integration-tests/docker/test_env/test_env_builder.go
@@ -281,6 +281,9 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) {
// new logs can be added to the log stream, so parallel processing would get stuck on waiting for it to be unlocked
LogScanningLoop:
for i := 0; i < b.clNodesCount; i++ {
+ if b == nil || b.te == nil || b.te.ClCluster == nil || b.te.ClCluster.Nodes == nil || b.te.ClCluster.Nodes[i] == nil || len(b.te.ClCluster.Nodes)-1 < i {
+ continue
+ }
// ignore count return, because we are only interested in the error
_, err := logProcessor.ProcessContainerLogs(b.te.ClCluster.Nodes[i].ContainerName, processFn)
if err != nil && !strings.Contains(err.Error(), testreporters.MultipleLogsAtLogLevelErr) && !strings.Contains(err.Error(), testreporters.OneLogAtLogLevelErr) {
diff --git a/integration-tests/go.mod b/integration-tests/go.mod
index 8eed200342..bb07aca3ae 100644
--- a/integration-tests/go.mod
+++ b/integration-tests/go.mod
@@ -34,14 +34,14 @@ require (
github.com/slack-go/slack v0.12.2
github.com/smartcontractkit/chain-selectors v1.0.23
github.com/smartcontractkit/chainlink-automation v1.0.4
- github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834
+ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1
github.com/smartcontractkit/chainlink-testing-framework v1.34.5
github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239
github.com/smartcontractkit/chainlink/integration-tests v0.0.0-00010101000000-000000000000
github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000
github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37
github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7
- github.com/smartcontractkit/seth v1.1.1
+ github.com/smartcontractkit/seth v1.2.1-0.20240827060008-860f949fcb26
github.com/smartcontractkit/wasp v0.4.5
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
@@ -445,7 +445,7 @@ require (
go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect
go.opentelemetry.io/collector/semconv v0.87.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
@@ -457,17 +457,17 @@ require (
go.uber.org/goleak v1.3.0 // indirect
go.uber.org/ratelimit v0.3.0 // indirect
go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect
- golang.org/x/arch v0.7.0 // indirect
+ golang.org/x/arch v0.8.0 // indirect
golang.org/x/mod v0.19.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/term v0.23.0 // indirect
- golang.org/x/time v0.5.0 // indirect
+ golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.23.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
gonum.org/v1/gonum v0.15.0 // indirect
- google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
+ google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect
google.golang.org/grpc v1.65.0 // indirect
diff --git a/integration-tests/go.sum b/integration-tests/go.sum
index d7ec061aeb..7e5179b252 100644
--- a/integration-tests/go.sum
+++ b/integration-tests/go.sum
@@ -14,23 +14,27 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
-cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
+cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14=
+cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
+cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s=
+cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs=
+cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI=
+cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg=
+cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA=
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
-cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
-cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
+cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
+cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
-cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc=
-cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=
+cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw=
+cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@@ -40,8 +44,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
-cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg=
-cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY=
+cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs=
+cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0=
contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo=
@@ -1393,8 +1397,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj
github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8=
github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM=
-github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI=
-github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo=
+github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 h1:pdEpjgbZ5w/Sd5lzg/XiuC5gVyrmSovOo+3nUD46SP8=
+github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs=
github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk=
@@ -1417,8 +1421,8 @@ github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1
github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw=
github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw=
github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM=
-github.com/smartcontractkit/seth v1.1.1 h1:6hvexjJD7ek8ht/CLlEwQcH21K2E/WEYwbSRdKInZmM=
-github.com/smartcontractkit/seth v1.1.1/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk=
+github.com/smartcontractkit/seth v1.2.1-0.20240827060008-860f949fcb26 h1:9c3dbd38M8T/Hkc9LKOSRf3wxfXAFNJcLnEPOBOctNk=
+github.com/smartcontractkit/seth v1.2.1-0.20240827060008-860f949fcb26/go.mod h1:KrhtzffZ+Pp5vyTkYErnnwjfjrGl8F9y3pxrbuZlVr0=
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=
@@ -1626,8 +1630,8 @@ go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
@@ -1640,8 +1644,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
-go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
-go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q=
+go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08=
+go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg=
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
@@ -1679,8 +1683,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s=
go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
-golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
-golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
+golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -1951,8 +1955,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
-golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
+golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -2044,8 +2048,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
-google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU=
-google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o=
+google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw=
+google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -2090,8 +2094,8 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
-google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
+google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc=
+google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY=
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A=
diff --git a/integration-tests/load/automationv2_1/automationv2_1_test.go b/integration-tests/load/automationv2_1/automationv2_1_test.go
index b0555cdd3f..0fe13d4bc7 100644
--- a/integration-tests/load/automationv2_1/automationv2_1_test.go
+++ b/integration-tests/load/automationv2_1/automationv2_1_test.go
@@ -368,10 +368,6 @@ Load Config:
a.SetMercuryCredentialName("cred1")
}
- if *conf.UseLogBufferV1 {
- a.SetUseLogBufferV1(true)
- }
-
startTimeTestSetup := time.Now()
l.Info().Str("START_TIME", startTimeTestSetup.String()).Msg("Test setup started")
diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod
index c8ef675d05..eef855ef03 100644
--- a/integration-tests/load/go.mod
+++ b/integration-tests/load/go.mod
@@ -13,15 +13,15 @@ require (
github.com/go-resty/resty/v2 v2.11.0
github.com/pelletier/go-toml/v2 v2.2.2
github.com/pkg/errors v0.9.1
- github.com/rs/zerolog v1.32.0
+ github.com/rs/zerolog v1.33.0
github.com/slack-go/slack v0.12.2
github.com/smartcontractkit/chainlink-automation v1.0.4
- github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834
+ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1
github.com/smartcontractkit/chainlink-testing-framework v1.34.5
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-20240717100443-f6226e09bee7
- github.com/smartcontractkit/seth v1.1.1
+ github.com/smartcontractkit/seth v1.2.1-0.20240827060008-860f949fcb26
github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1
github.com/smartcontractkit/wasp v0.4.7
github.com/stretchr/testify v1.9.0
@@ -44,7 +44,7 @@ require (
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect
github.com/testcontainers/testcontainers-go v0.28.0 // indirect
- k8s.io/apimachinery v0.30.2 // indirect
+ k8s.io/apimachinery v0.31.0 // indirect
)
// avoids ambigious imports of indirect dependencies
@@ -103,7 +103,7 @@ require (
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
- github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f // indirect
+ github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.0 // indirect
github.com/cockroachdb/errors v1.10.0 // indirect
@@ -164,7 +164,7 @@ require (
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
- github.com/fxamacker/cbor/v2 v2.6.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gagliardetto/binary v0.7.7 // indirect
github.com/gagliardetto/solana-go v1.8.4 // indirect
@@ -217,7 +217,7 @@ require (
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/go-tpm v0.9.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
- github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect
+ github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/context v1.1.1 // indirect
@@ -232,7 +232,7 @@ require (
github.com/grafana/grafana-foundation-sdk/go v0.0.0-20240326122733-6f96a993222b // indirect
github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect
github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect
- github.com/grafana/pyroscope-go v1.1.1 // indirect
+ github.com/grafana/pyroscope-go v1.1.2 // indirect
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
@@ -240,7 +240,7 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
- github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/gtank/merlin v0.1.1 // indirect
github.com/gtank/ristretto255 v0.1.2 // indirect
@@ -379,7 +379,7 @@ require (
github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect
github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect
github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect
- github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 // indirect
+ github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 // indirect
github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 // indirect
github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect
github.com/smartcontractkit/wsrpc v0.8.1 // indirect
@@ -423,16 +423,16 @@ require (
github.com/zondax/ledger-go v0.14.3 // indirect
go.dedis.ch/fixbuf v1.0.3 // indirect
go.dedis.ch/kyber/v3 v3.1.0 // indirect
- go.etcd.io/bbolt v1.3.8 // indirect
- go.etcd.io/etcd/api/v3 v3.5.12 // indirect
- go.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect
- go.etcd.io/etcd/client/v3 v3.5.12 // indirect
+ go.etcd.io/bbolt v1.3.9 // indirect
+ go.etcd.io/etcd/api/v3 v3.5.14 // indirect
+ go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect
+ go.etcd.io/etcd/client/v3 v3.5.14 // indirect
go.mongodb.org/mongo-driver v1.15.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect
go.opentelemetry.io/collector/semconv v0.87.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
@@ -446,23 +446,23 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect
- golang.org/x/arch v0.7.0 // indirect
+ golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
- golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
- golang.org/x/mod v0.19.0 // indirect
- golang.org/x/net v0.27.0 // indirect
- golang.org/x/oauth2 v0.21.0 // indirect
+ golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
+ golang.org/x/mod v0.20.0 // indirect
+ golang.org/x/net v0.28.0 // indirect
+ golang.org/x/oauth2 v0.22.0 // indirect
golang.org/x/sync v0.8.0 // indirect
- golang.org/x/sys v0.23.0 // indirect
+ golang.org/x/sys v0.24.0 // indirect
golang.org/x/term v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
- golang.org/x/time v0.5.0 // indirect
- golang.org/x/tools v0.23.0 // indirect
+ golang.org/x/time v0.6.0 // indirect
+ golang.org/x/tools v0.24.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
gonum.org/v1/gonum v0.15.0 // indirect
- google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect
+ google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/grpc v1.65.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/guregu/null.v4 v4.0.0 // indirect
@@ -471,15 +471,15 @@ require (
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- k8s.io/api v0.30.2 // indirect
- k8s.io/apiextensions-apiserver v0.30.2 // indirect
+ k8s.io/api v0.31.0 // indirect
+ k8s.io/apiextensions-apiserver v0.31.0 // indirect
k8s.io/cli-runtime v0.28.2 // indirect
k8s.io/client-go v1.5.2 // indirect
- k8s.io/component-base v0.30.2 // indirect
+ k8s.io/component-base v0.31.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect
k8s.io/kubectl v0.28.2 // indirect
- k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect
+ k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
nhooyr.io/websocket v1.8.10 // indirect
pgregory.net/rapid v1.1.0 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum
index 714ba7700b..86712da168 100644
--- a/integration-tests/load/go.sum
+++ b/integration-tests/load/go.sum
@@ -14,23 +14,27 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
-cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
+cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14=
+cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
+cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s=
+cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs=
+cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI=
+cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg=
+cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA=
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
-cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
-cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
+cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
+cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
-cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc=
-cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=
+cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw=
+cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@@ -40,8 +44,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
-cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg=
-cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY=
+cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs=
+cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0=
contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo=
@@ -473,8 +477,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
-github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA=
-github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
+github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
+github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY=
@@ -728,8 +732,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg=
-github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
+github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM=
+github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
@@ -778,8 +782,8 @@ github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 h1:gdrsYbmk8822v6qv
github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503/go.mod h1:d8seWXCEXkL42mhuIJYcGi6DxfehzoIpLrMQWJojvOo=
github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeebhJIBkgYOD06Mxk9HV2KhtEG0hp/7R+5RUQ=
github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0=
-github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ=
-github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88=
+github.com/grafana/pyroscope-go v1.1.2 h1:7vCfdORYQMCxIzI3NlYAs3FcBP760+gWuYWOyiVyYx8=
+github.com/grafana/pyroscope-go v1.1.2/go.mod h1:HSSmHo2KRn6FasBA4vK7BMiQqyQq8KSuBKvrhkXxYPU=
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg=
github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU=
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww=
@@ -801,8 +805,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=
@@ -1303,8 +1307,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
-github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
-github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
+github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
+github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
@@ -1359,8 +1363,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj
github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8=
github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM=
-github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI=
-github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo=
+github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 h1:pdEpjgbZ5w/Sd5lzg/XiuC5gVyrmSovOo+3nUD46SP8=
+github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs=
github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk=
@@ -1373,8 +1377,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202407
github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU=
github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM=
github.com/smartcontractkit/chainlink-testing-framework v1.34.5/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ=
-github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8=
-github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU=
+github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQZ4TOFpZ13w94r7amdF096Z96RuEnkOmrz1BGE=
+github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU=
github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo=
github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI=
github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU=
@@ -1383,8 +1387,8 @@ github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1
github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw=
github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw=
github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM=
-github.com/smartcontractkit/seth v1.1.1 h1:6hvexjJD7ek8ht/CLlEwQcH21K2E/WEYwbSRdKInZmM=
-github.com/smartcontractkit/seth v1.1.1/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk=
+github.com/smartcontractkit/seth v1.2.1-0.20240827060008-860f949fcb26 h1:9c3dbd38M8T/Hkc9LKOSRf3wxfXAFNJcLnEPOBOctNk=
+github.com/smartcontractkit/seth v1.2.1-0.20240827060008-860f949fcb26/go.mod h1:KrhtzffZ+Pp5vyTkYErnnwjfjrGl8F9y3pxrbuZlVr0=
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=
@@ -1559,14 +1563,14 @@ go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRL
go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4=
go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
-go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA=
-go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
-go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c=
-go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4=
-go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A=
-go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4=
-go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg=
-go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw=
+go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
+go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
+go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0=
+go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU=
+go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ=
+go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI=
+go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg=
+go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk=
go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
@@ -1590,8 +1594,8 @@ go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
@@ -1604,8 +1608,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
-go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
-go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q=
+go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08=
+go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg=
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
@@ -1643,8 +1647,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s=
go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
-golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
-golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
+golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -1684,8 +1688,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
-golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
+golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
+golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -1710,8 +1714,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
-golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
+golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1767,8 +1771,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
-golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
-golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1776,8 +1780,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
-golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
-golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
+golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1879,8 +1883,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
-golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
+golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1913,8 +1917,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
-golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
+golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -1976,8 +1980,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
-golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
+golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
+golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -2006,8 +2010,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
-google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU=
-google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o=
+google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw=
+google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -2052,12 +2056,12 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
-google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
-google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
-google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
+google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc=
+google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY=
+google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo=
+google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -2159,8 +2163,8 @@ k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6z
k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc=
k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM=
k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64=
-k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak=
-k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
+k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q=
nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
diff --git a/integration-tests/testconfig/automation/automation.toml b/integration-tests/testconfig/automation/automation.toml
index 7e10af62cf..26b9f05597 100644
--- a/integration-tests/testconfig/automation/automation.toml
+++ b/integration-tests/testconfig/automation/automation.toml
@@ -152,6 +152,57 @@ max_check_data_size=5_000
max_perform_data_size=5_000
max_revert_data_size=5_000
+# chaos test specific overrides
+[Chaos.Common]
+chainlink_node_funding = 2.0
+
+[Chaos.Automation]
+
+[Chaos.Automation.AutomationConfig]
+use_log_buffer_v1=false
+
+[Chaos.Automation.AutomationConfig.PublicConfig]
+delta_progress=10_000_000_000
+delta_resend=15_000_000_000
+delta_initial=500_000_000
+delta_round=1_000_000_000
+delta_grace=200_000_000
+delta_certified_commit_request=300_000_000
+delta_stage=30_000_000_000
+r_max=24
+f=1
+max_duration_query=20_000_000
+max_duration_observation=20_000_000
+max_duration_should_accept_attested_report=1_200_000_000
+max_duration_should_transmit_accepted_report=20_000_000
+
+[Chaos.Automation.AutomationConfig.PluginConfig]
+perform_lockout_window=3_600_000
+target_probability="0.999"
+target_in_rounds=1
+min_confirmations=0
+gas_limit_per_report=10_300_000
+gas_overhead_per_upkeep=300_000
+max_upkeep_batch_size=10
+
+[Chaos.Automation.AutomationConfig.PluginConfig.LogProviderConfig]
+block_rate=1
+log_limit=2
+
+[Chaos.Automation.AutomationConfig.RegistrySettings]
+payment_premium_ppb=200_000_000
+flat_fee_micro_link=0
+check_gas_limit=2_500_000
+staleness_seconds=90000
+gas_ceiling_multiplier=1
+max_perform_gas=5_000_000
+min_upkeep_spend=0
+fallback_gas_price=200_000_000_000
+fallback_link_price=2_000_000_000_000_000_000
+max_check_data_size=5_000
+max_perform_data_size=5_000
+max_revert_data_size=5_000
+
# load test specific overrides
[Load.Seth]
ephemeral_addresses_number = 100
diff --git a/integration-tests/testconfig/automation/config.go b/integration-tests/testconfig/automation/config.go
index bde989f544..e6df7714af 100644
--- a/integration-tests/testconfig/automation/config.go
+++ b/integration-tests/testconfig/automation/config.go
@@ -160,7 +160,6 @@ type AutomationConfig struct {
PluginConfig *PluginConfig `toml:"PluginConfig"`
PublicConfig *PublicConfig `toml:"PublicConfig"`
RegistrySettings *RegistrySettings `toml:"RegistrySettings"`
- UseLogBufferV1 *bool `toml:"use_log_buffer_v1"`
}
func (c *AutomationConfig) Validate() error {
@@ -170,13 +169,7 @@ func (c *AutomationConfig) Validate() error {
if err := c.PublicConfig.Validate(); err != nil {
return err
}
- if err := c.RegistrySettings.Validate(); err != nil {
- return err
- }
- if c.UseLogBufferV1 == nil {
- return errors.New("use_log_buffer_v1 must be set")
- }
- return nil
+ return c.RegistrySettings.Validate()
}
type PluginConfig struct {
diff --git a/package.json b/package.json
index 541cfb1aaf..f32ffe9e5a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ccip",
- "version": "2.14.0-ccip1.5.0",
+ "version": "2.15.0-ccip1.5.0",
"description": "node of the decentralized oracle network, bridging on and off-chain computation",
"main": "index.js",
"scripts": {
diff --git a/testdata/scripts/health/default.txtar b/testdata/scripts/health/default.txtar
index 777d3e5e12..1dbf6b8eb9 100644
--- a/testdata/scripts/health/default.txtar
+++ b/testdata/scripts/health/default.txtar
@@ -31,7 +31,6 @@ fj293fbBnlQ!f9vNs
HTTPPort = $PORT
-- out.txt --
-ok HeadReporter
ok JobSpawner
ok Mailbox.Monitor
ok Mercury.WSRPCPool
@@ -39,20 +38,12 @@ ok Mercury.WSRPCPool.CacheSet
ok PipelineORM
ok PipelineRunner
ok PipelineRunner.BridgeCache
+ok PromReporter
ok TelemetryManager
-- out.json --
{
"data": [
- {
- "type": "checks",
- "id": "HeadReporter",
- "attributes": {
- "name": "HeadReporter",
- "status": "passing",
- "output": ""
- }
- },
{
"type": "checks",
"id": "JobSpawner",
@@ -116,6 +107,15 @@ ok TelemetryManager
"output": ""
}
},
+ {
+ "type": "checks",
+ "id": "PromReporter",
+ "attributes": {
+ "name": "PromReporter",
+ "status": "passing",
+ "output": ""
+ }
+ },
{
"type": "checks",
"id": "TelemetryManager",
diff --git a/testdata/scripts/health/multi-chain.txtar b/testdata/scripts/health/multi-chain.txtar
index 3bd15850af..8178f8e821 100644
--- a/testdata/scripts/health/multi-chain.txtar
+++ b/testdata/scripts/health/multi-chain.txtar
@@ -75,7 +75,6 @@ ok EVM.1.Txm.BlockHistoryEstimator
ok EVM.1.Txm.Broadcaster
ok EVM.1.Txm.Confirmer
ok EVM.1.Txm.WrappedEvmEstimator
-ok HeadReporter
ok JobSpawner
ok Mailbox.Monitor
ok Mercury.WSRPCPool
@@ -83,6 +82,7 @@ ok Mercury.WSRPCPool.CacheSet
ok PipelineORM
ok PipelineRunner
ok PipelineRunner.BridgeCache
+ok PromReporter
ok Solana.Bar
ok StarkNet.Baz
ok TelemetryManager
@@ -216,15 +216,6 @@ ok TelemetryManager
"output": ""
}
},
- {
- "type": "checks",
- "id": "HeadReporter",
- "attributes": {
- "name": "HeadReporter",
- "status": "passing",
- "output": ""
- }
- },
{
"type": "checks",
"id": "JobSpawner",
@@ -288,6 +279,15 @@ ok TelemetryManager
"output": ""
}
},
+ {
+ "type": "checks",
+ "id": "PromReporter",
+ "attributes": {
+ "name": "PromReporter",
+ "status": "passing",
+ "output": ""
+ }
+ },
{
"type": "checks",
"id": "Solana.Bar",